<commit_before>'use strict';

var Base    = require('./base'),
    xhtmlIm = require('./utils/xep-0071'),
    state   = require('./utils/xep-0085'),
    delay   = require('./utils/xep-0203'),
    receipt = require('./utils/xep-0184'),
    builder = require('ltx')

var Chat = function() {}

Chat.prototype = new Base()

Chat.prototype.XHTML = 'xhtml'
Chat.prototype.PLAIN = 'plain'

Chat.prototype._events = {
    'xmpp.chat.message': 'sendMessage',
    'xmpp.chat.receipt': 'sendReceipt'
}

Chat.prototype.handles = function(stanza) {
    if (!stanza.is('message')) return false
    if (!stanza.attrs.type || ('chat' === stanza.attrs.type)) return true
    if (stanza.getChild('received', receipt.NS)) return true
    return false
}

Chat.prototype.handle = function(stanza) {
    var chat = { from: this._getJid(stanza.attrs.from) }
    if (stanza.getChild('received', receipt.NS))
        return this._returnDeliveryReceipt(chat, stanza)
    this._getMessageContent(stanza, chat)
    delay.parse(stanza, chat)
    state.parse(stanza, chat)
    var self = this
    stanza.getChildren('archived').forEach(function(archived) {
        if (!chat.archived) chat.archived = []
        chat.archived.push({
            by: self._getJid(archived.attrs.by),
            id: archived.attrs.id
        })
    })
    if (stanza.attrs.id) chat.id = stanza.attrs.id
    this.socket.send('xmpp.chat.message', chat)
    return true
}

Chat.prototype._returnDeliveryReceipt = function(data, stanza) {
    data.id = stanza.getChild('received').attrs.id
    this.socket.send('xmpp.chat.receipt', data)
    return true
}

Chat.prototype._getMessageContent = function(stanza, chat) {
    if (!stanza.getChild('body') &&
        !stanza.getChild('html', xhtmlIm.NS_XHTML_IM)
    ) return

    var format  = this.PLAIN
    var content = stanza.getChild('body').getText()
    var message
    if (!!(message = stanza.getChild('html', xhtmlIm.NS_XHTML_IM))) {
        content = message.getChild('body', xhtmlIm.NS_XHTML)
            .children
            .join('')
            .toString()
            .trim()
        format  = this.XHTML
    }
    chat.content = content
    chat.format = format
}

Chat.prototype.sendReceipt = function(data) {
    if (!data.to)
        return this._clientError('Missing \'to\' key', data)
    if (!data.id)
        return this._clientError('Missing \'id\' key', data)
    var stanza = new builder.Element('message', { id: this._getId(), to: data.to })
    receipt.build(stanza, data, 'received')
    this.client.send(stanza)
}

Chat.prototype._messageReceipt = function(stanza, callback) {
    if ('error' === stanza.attrs.type) {
        return callback(this._parseError(stanza))
    }
    callback(null, true)
}

Chat.prototype._addState = function(stanza, chatState) {
    if (!chatState) return
    stanza.root().c(chatState, { xmlns: state.NS })
}

Chat.prototype._addReceiptRequest = function(stanza, data, hasValidCallback) {
    if (!data.receipt) return true

    if (false === hasValidCallback) {
        this._clientError('Callback required', data)
        return false
    }
    stanza.root().c('request', { xmlns: receipt.NS })
}

Chat.prototype.sendMessage = function(data, callback) {
    if (!data.to) return this._clientError('Missing \'to\' key', data)
    data.type = 'chat'
    if (!data.content && !data.state) {
        return this._clientError(
            'Message content or chat state not provided', data
        )
    }
    var stanza
    if (!(stanza = xhtmlIm.builder(data, { to: data.to, type: 'chat' }, this)))
        return
    var hasValidCallback = false

    if (callback) {
        if (false === this._hasValidCallback(callback, data)) return
        hasValidCallback = true
        stanza.root().attrs.id = this._getId()
    }
    this._addState(stanza, data.state)
    if (false === this._addReceiptRequest(stanza, data, hasValidCallback)) {
        return
    }
    this.client.send(stanza)
    if (false === hasValidCallback) return
    callback(null, { id: stanza.root().attrs.id })
}

module.exports = Chat<commit_msg>Unused code<commit_after>'use strict';

var Base    = require('./base'),
    xhtmlIm = require('./utils/xep-0071'),
    state   = require('./utils/xep-0085'),
    delay   = require('./utils/xep-0203'),
    receipt = require('./utils/xep-0184'),
    builder = require('ltx')

var Chat = function() {}

Chat.prototype = new Base()

Chat.prototype.XHTML = 'xhtml'
Chat.prototype.PLAIN = 'plain'

Chat.prototype._events = {
    'xmpp.chat.message': 'sendMessage',
    'xmpp.chat.receipt': 'sendReceipt'
}

Chat.prototype.handles = function(stanza) {
    if (!stanza.is('message')) return false
    if (!stanza.attrs.type || ('chat' === stanza.attrs.type)) return true
    if (stanza.getChild('received', receipt.NS)) return true
    return false
}

Chat.prototype.handle = function(stanza) {
    var chat = { from: this._getJid(stanza.attrs.from) }
    if (stanza.getChild('received', receipt.NS))
        return this._returnDeliveryReceipt(chat, stanza)
    this._getMessageContent(stanza, chat)
    delay.parse(stanza, chat)
    state.parse(stanza, chat)
    var self = this
    stanza.getChildren('archived').forEach(function(archived) {
        if (!chat.archived) chat.archived = []
        chat.archived.push({
            by: self._getJid(archived.attrs.by),
            id: archived.attrs.id
        })
    })
    if (stanza.attrs.id) chat.id = stanza.attrs.id
    this.socket.send('xmpp.chat.message', chat)
    return true
}

Chat.prototype._returnDeliveryReceipt = function(data, stanza) {
    data.id = stanza.getChild('received').attrs.id
    this.socket.send('xmpp.chat.receipt', data)
    return true
}

Chat.prototype._getMessageContent = function(stanza, chat) {
    if (!stanza.getChild('body') &&
        !stanza.getChild('html', xhtmlIm.NS_XHTML_IM)
    ) return

    var format  = this.PLAIN
    var content = stanza.getChild('body').getText()
    var message
    if (!!(message = stanza.getChild('html', xhtmlIm.NS_XHTML_IM))) {
        content = message.getChild('body', xhtmlIm.NS_XHTML)
            .children
            .join('')
            .toString()
            .trim()
        format  = this.XHTML
    }
    chat.content = content
    chat.format = format
}

Chat.prototype.sendReceipt = function(data) {
    if (!data.to)
        return this._clientError('Missing \'to\' key', data)
    if (!data.id)
        return this._clientError('Missing \'id\' key', data)
    var stanza = new builder.Element('message', { id: this._getId(), to: data.to })
    receipt.build(stanza, data, 'received')
    this.client.send(stanza)
}

Chat.prototype._addState = function(stanza, chatState) {
    if (!chatState) return
    stanza.root().c(chatState, { xmlns: state.NS })
}

Chat.prototype._addReceiptRequest = function(stanza, data, hasValidCallback) {
    if (!data.receipt) return true

    if (false === hasValidCallback) {
        this._clientError('Callback required', data)
        return false
    }
    stanza.root().c('request', { xmlns: receipt.NS })
}

Chat.prototype.sendMessage = function(data, callback) {
    if (!data.to) return this._clientError('Missing \'to\' key', data)
    data.type = 'chat'
    if (!data.content && !data.state) {
        return this._clientError(
            'Message content or chat state not provided', data
        )
    }
    var stanza
    if (!(stanza = xhtmlIm.builder(data, { to: data.to, type: 'chat' }, this)))
        return
    var hasValidCallback = false

    if (callback) {
        if (false === this._hasValidCallback(callback, data)) return
        hasValidCallback = true
        stanza.root().attrs.id = this._getId()
    }
    this._addState(stanza, data.state)
    if (false === this._addReceiptRequest(stanza, data, hasValidCallback)) {
        return
    }
    this.client.send(stanza)
    if (false === hasValidCallback) return
    callback(null, { id: stanza.root().attrs.id })
}

module.exports = Chat<|endoftext|>


<commit_before>/**
 * node-archiver
 *
 * Copyright (c) 2012-2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-archiver/blob/master/LICENSE-MIT
 */
var async = require('async');
var fs = require('fs');
var util = require('./util');

// built-in plugins
var pjson = require('archiver-json');
var ptar = require('archiver-tar');
var pzip = require('archiver-zip');

var inherits = require('util').inherits;
var Transform = require('readable-stream').Transform;

var Archiver = module.exports = function(format, options) {
  if (!(this instanceof Archiver)) {
    return new Archiver(format, options);
  }

  if (typeof format !== 'string') {
    options = format;
    format = 'zip';
  }

  options = this.options = util.defaults(options, {
    highWaterMark: 1024 * 1024,
    statConcurrency: 4
  });

  Transform.call(this, options);

  this._entries = [];
  this._format = false;
  this._module = false;
  this._pending = 0;
  this._pointer = 0;

  this._queue = async.queue(this._onQueueTask.bind(this), 1);
  this._queue.drain = this._onQueueDrain.bind(this);

  this._statQueue = async.queue(this._onStatQueueTask.bind(this), options.statConcurrency);

  this._state = {
    aborted: false,
    finalize: false,
    finalizing: false,
    finalized: false,
    modulePiped: false
  };

  this._streams = [];

  if (format === 'zip') {
    // this.use(pzip());
  } else if (format === 'tar') {
    // this.use(ptar());
  } else if (format === 'json') {
    this.use(pjson());
  } else {
    this.emit(error, new Error('no format plugin'));
  }
};

inherits(Archiver, Transform);

Archiver.prototype._abort = function() {
  this._state.aborted = true;
  this._queue.kill();
  this._statQueue.kill();

  if (this._queue.idle()) {
    this._shutdown();
  }
};

Archiver.prototype._append = function(filepath, data) {
  data = data || {};

  var task = {
    source: null,
    filepath: filepath
  };

  if (!data.name) {
    data.name = filepath;
  }

  data.sourcePath = filepath;
  task.data = data;

  if (data.stats && data.stats instanceof fs.Stats) {
    task = this._updateQueueTaskWithStats(task, data.stats);
    this._queue.push(task);
  } else {
    this._statQueue.push(task);
  }
};

Archiver.prototype._finalize = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return;
  }

  this._state.finalizing = true;

  this._moduleFinalize();

  this._state.finalizing = false;
  this._state.finalized = true;
};

Archiver.prototype._maybeFinalize = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return false;
  }

  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
    return true;
  }

  return false;
};

Archiver.prototype._moduleAppend = function(source, data, callback) {
  if (this._state.aborted) {
    callback();
    return;
  }

  this._module.append(source, data, function(err) {
    this._task = null;

    if (this._state.aborted) {
      this._shutdown();
      return;
    }

    if (err) {
      this.emit('error', err);
      setImmediate(callback);
      return;
    }

    this.emit('entry', data);
    this._entries.push(data);

    setImmediate(callback);
  }.bind(this));
};

Archiver.prototype._moduleFinalize = function() {
  if (typeof this._module.finalize === 'function') {
    this._module.finalize();
  } else if (typeof this._module.end === 'function') {
    this._module.end();
  } else {
    this.emit('error', new Error('module: no suitable finalize/end method found'));
    return;
  }
};

Archiver.prototype._modulePipe = function() {
  this._module.on('error', this._onModuleError.bind(this));
  this._module.pipe(this);
  this._state.modulePiped = true;
};

Archiver.prototype._moduleSupports = function(key) {
  if (!this._module.supports || !this._module.supports[key]) {
    return false;
  }

  return this._module.supports[key];
};

Archiver.prototype._moduleUnpipe = function() {
  this._module.unpipe(this);
  this._state.modulePiped = false;
};

Archiver.prototype._normalizeEntryData = function(data, stats) {
  data = util.defaults(data, {
    type: 'file',
    name: null,
    date: null,
    mode: null,
    sourcePath: null,
    stats: false
  });

  if (stats && data.stats === false) {
    data.stats = stats;
  }

  var isDir = data.type === 'directory';

  if (data.name) {
    data.name = util.sanitizePath(data.name);

    if (data.name.slice(-1) === '/') {
      isDir = true;
      data.type = 'directory';
    } else if (isDir) {
      data.name += '/';
    }
  }

  // 511 === 0777; 493 === 0755; 420 === 0644
  if (typeof data.mode === 'number') {
    data.mode &= 511;
  } else if (data.stats && data.mode === null) {
    data.mode = data.stats.mode & 511;
  } else if (data.mode === null) {
    data.mode = isDir ? 493 : 420;
  }

  if (data.stats && data.date === null) {
    data.date = data.stats.mtime;
  } else {
    data.date = util.dateify(data.date);
  }

  return data;
};

Archiver.prototype._onModuleError = function(err) {
  this.emit('error', err);
};

Archiver.prototype._onQueueDrain = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return;
  }

  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
    return;
  }
};

Archiver.prototype._onQueueTask = function(task, callback) {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    callback();
    return;
  }

  this._task = task;
  this._moduleAppend(task.source, task.data, callback);
};

Archiver.prototype._onStatQueueTask = function(task, callback) {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    callback();
    return;
  }

  fs.stat(task.filepath, function(err, stats) {
    if (this._state.aborted) {
      setImmediate(callback);
      return;
    }

    if (err) {
      this.emit('error', err);
      setImmediate(callback);
      return;
    }

    task = this._updateQueueTaskWithStats(task, stats);

    if (task.source !== null) {
      this._queue.push(task);
      setImmediate(callback);
    } else {
      this.emit('error', new Error('unsupported entry: ' + task.filepath));
      setImmediate(callback);
      return;
    }
  }.bind(this));
};

Archiver.prototype._shutdown = function() {
  this._moduleUnpipe();
  this.end();
};

Archiver.prototype._transform = function(chunk, encoding, callback) {
  if (chunk) {
    this._pointer += chunk.length;
  }

  callback(null, chunk);
};

Archiver.prototype._updateQueueTaskWithStats = function(task, stats) {
  if (stats.isFile()) {
    task.data.type = 'file';
    task.data.sourceType = 'stream';
    task.source = util.lazyReadStream(task.filepath);
  } else if (stats.isDirectory() && this._moduleSupports('directory')) {
    task.data.name = util.trailingSlashIt(task.data.name);
    task.data.type = 'directory';
    task.data.sourcePath = util.trailingSlashIt(task.filepath);
    task.data.sourceType = 'buffer';
    task.source = new Buffer(0);
  } else {
    return task;
  }

  task.data = this._normalizeEntryData(task.data, stats);
  return task;
};

Archiver.prototype.abort = function() {
  if (this._state.aborted || this._state.finalized) {
    return this;
  }

  this._abort();

  return this;
};

Archiver.prototype.append = function(source, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('append: queue closed'));
    return this;
  }

  data = this._normalizeEntryData(data);

  if (typeof data.name !== 'string' || data.name.length === 0) {
    this.emit('error', new Error('append: entry name must be a non-empty string value'));
    return this;
  }

  if (data.type === 'directory' && !this._moduleSupports('directory')) {
    this.emit('error', new Error('append: entries of "directory" type not currently supported by this module'));
    return this;
  }

  source = util.normalizeInputSource(source);

  if (Buffer.isBuffer(source)) {
    data.sourceType = 'buffer';
  } else if (util.isStream(source)) {
    data.sourceType = 'stream';
  } else {
    this.emit('error', new Error('append: input source must be valid Stream or Buffer instance'));
    return this;
  }

  this._queue.push({
    data: data,
    source: source
  });

  return this;
};

Archiver.prototype.bulk = function(mappings) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('bulk: queue closed'));
    return this;
  }

  if (!Array.isArray(mappings)) {
    mappings = [mappings];
  }

  var self = this;
  var files = util.file.normalizeFilesArray(mappings);

  files.forEach(function(file){
    var isExpandedPair = file.orig.expand || false;
    var data = {};
    var dataFunction = false;

    if (typeof file.data === 'function') {
      dataFunction = file.data;
    } else if (typeof file.data === 'object') {
      data = file.data;
    }

    file.src.forEach(function(filepath) {
      var entryData = util._.extend({}, data);
      entryData.name = isExpandedPair ? util.unixifyPath(file.dest) : util.unixifyPath(file.dest || '', filepath);

      if (entryData.name === '.') {
        return;
      }

      try {
        entryData = dataFunction(entryData) || entryData;
      } catch(e) {}

      self._append(filepath, entryData);
    });
  });

  return this;
};

Archiver.prototype.directory = function(dirpath, destpath, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('directory: queue closed'));
    return this;
  }

  if (typeof dirpath !== 'string' || dirpath.length === 0) {
    this.emit('error', new Error('directory: dirpath must be a non-empty string value'));
    return this;
  }

  this._pending++;

  if (destpath === false) {
    destpath = '';
  } else if (typeof destpath !== 'string'){
    destpath = dirpath;
  }

  var dataFunction = false;
  if (typeof data === 'function') {
    dataFunction = data;
    data = {};
  } else if (typeof data !== 'object') {
    data = {};
  }

  var self = this;

  util.walkdir(dirpath, function(err, results) {
    if (err) {
      self.emit('error', err);
    } else {
      results.forEach(function(file) {
        var entryData = util._.extend({}, data);
        entryData.name = util.sanitizePath(destpath, file.relative);
        entryData.stats = file.stats;

        try {
          entryData = dataFunction(entryData) || entryData;
        } catch(e) {}

        self._append(file.path, entryData);
      });
    }

    self._pending--;
    self._maybeFinalize();
  });

  return this;
};

Archiver.prototype.file = function(filepath, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('file: queue closed'));
    return this;
  }

  if (typeof filepath !== 'string' || filepath.length === 0) {
    this.emit('error', new Error('file: filepath must be a non-empty string value'));
    return this;
  }

  this._append(filepath, data);

  return this;
};

Archiver.prototype.finalize = function() {
  if (this._state.aborted) {
    this.emit('error', new Error('finalize: archive was aborted'));
    return this;
  }

  if (this._state.finalize) {
    this.emit('error', new Error('finalize: archive already finalizing'));
    return this;
  }

  this._state.finalize = true;

  if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
  }

  return this;
};

// needs to be deprecated
Archiver.prototype.setFormat = function(format) {
  if (this._format) {
    this.emit('error', new Error('format: archive format already set'));
    return this;
  }

  this._format = format;

  return this;
};

// needs to be deprecated
Archiver.prototype.setModule = function(module) {
  if (this._state.aborted) {
    this.emit('error', new Error('module: archive was aborted'));
    return this;
  }

  if (this._state.module) {
    this.emit('error', new Error('module: module already set'));
    return this;
  }

  this._module = module;
  this._modulePipe();

  return this;
};

Archiver.prototype.pointer = function() {
  return this._pointer;
};

Archiver.prototype.use = function(plugin) {
  this._streams.push(plugin);
  return this;
};<commit_msg>tweak how errors are handled with custom data functions.<commit_after>/**
 * node-archiver
 *
 * Copyright (c) 2012-2014 Chris Talkington, contributors.
 * Licensed under the MIT license.
 * https://github.com/archiverjs/node-archiver/blob/master/LICENSE-MIT
 */
var async = require('async');
var fs = require('fs');
var util = require('./util');

// built-in plugins
var pjson = require('archiver-json');
var ptar = require('archiver-tar');
var pzip = require('archiver-zip');

var inherits = require('util').inherits;
var Transform = require('readable-stream').Transform;

var Archiver = module.exports = function(format, options) {
  if (!(this instanceof Archiver)) {
    return new Archiver(format, options);
  }

  if (typeof format !== 'string') {
    options = format;
    format = 'zip';
  }

  options = this.options = util.defaults(options, {
    highWaterMark: 1024 * 1024,
    statConcurrency: 4
  });

  Transform.call(this, options);

  this._entries = [];
  this._format = false;
  this._module = false;
  this._pending = 0;
  this._pointer = 0;

  this._queue = async.queue(this._onQueueTask.bind(this), 1);
  this._queue.drain = this._onQueueDrain.bind(this);

  this._statQueue = async.queue(this._onStatQueueTask.bind(this), options.statConcurrency);

  this._state = {
    aborted: false,
    finalize: false,
    finalizing: false,
    finalized: false,
    modulePiped: false
  };

  this._streams = [];

  if (format === 'zip') {
    // this.use(pzip());
  } else if (format === 'tar') {
    // this.use(ptar());
  } else if (format === 'json') {
    this.use(pjson());
  } else {
    this.emit(error, new Error('no format plugin'));
  }
};

inherits(Archiver, Transform);

Archiver.prototype._abort = function() {
  this._state.aborted = true;
  this._queue.kill();
  this._statQueue.kill();

  if (this._queue.idle()) {
    this._shutdown();
  }
};

Archiver.prototype._append = function(filepath, data) {
  data = data || {};

  var task = {
    source: null,
    filepath: filepath
  };

  if (!data.name) {
    data.name = filepath;
  }

  data.sourcePath = filepath;
  task.data = data;

  if (data.stats && data.stats instanceof fs.Stats) {
    task = this._updateQueueTaskWithStats(task, data.stats);
    this._queue.push(task);
  } else {
    this._statQueue.push(task);
  }
};

Archiver.prototype._finalize = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return;
  }

  this._state.finalizing = true;

  this._moduleFinalize();

  this._state.finalizing = false;
  this._state.finalized = true;
};

Archiver.prototype._maybeFinalize = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return false;
  }

  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
    return true;
  }

  return false;
};

Archiver.prototype._moduleAppend = function(source, data, callback) {
  if (this._state.aborted) {
    callback();
    return;
  }

  this._module.append(source, data, function(err) {
    this._task = null;

    if (this._state.aborted) {
      this._shutdown();
      return;
    }

    if (err) {
      this.emit('error', err);
      setImmediate(callback);
      return;
    }

    this.emit('entry', data);
    this._entries.push(data);

    setImmediate(callback);
  }.bind(this));
};

Archiver.prototype._moduleFinalize = function() {
  if (typeof this._module.finalize === 'function') {
    this._module.finalize();
  } else if (typeof this._module.end === 'function') {
    this._module.end();
  } else {
    this.emit('error', new Error('module: no suitable finalize/end method found'));
    return;
  }
};

Archiver.prototype._modulePipe = function() {
  this._module.on('error', this._onModuleError.bind(this));
  this._module.pipe(this);
  this._state.modulePiped = true;
};

Archiver.prototype._moduleSupports = function(key) {
  if (!this._module.supports || !this._module.supports[key]) {
    return false;
  }

  return this._module.supports[key];
};

Archiver.prototype._moduleUnpipe = function() {
  this._module.unpipe(this);
  this._state.modulePiped = false;
};

Archiver.prototype._normalizeEntryData = function(data, stats) {
  data = util.defaults(data, {
    type: 'file',
    name: null,
    date: null,
    mode: null,
    sourcePath: null,
    stats: false
  });

  if (stats && data.stats === false) {
    data.stats = stats;
  }

  var isDir = data.type === 'directory';

  if (data.name) {
    data.name = util.sanitizePath(data.name);

    if (data.name.slice(-1) === '/') {
      isDir = true;
      data.type = 'directory';
    } else if (isDir) {
      data.name += '/';
    }
  }

  // 511 === 0777; 493 === 0755; 420 === 0644
  if (typeof data.mode === 'number') {
    data.mode &= 511;
  } else if (data.stats && data.mode === null) {
    data.mode = data.stats.mode & 511;
  } else if (data.mode === null) {
    data.mode = isDir ? 493 : 420;
  }

  if (data.stats && data.date === null) {
    data.date = data.stats.mtime;
  } else {
    data.date = util.dateify(data.date);
  }

  return data;
};

Archiver.prototype._onModuleError = function(err) {
  this.emit('error', err);
};

Archiver.prototype._onQueueDrain = function() {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    return;
  }

  if (this._state.finalize && this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
    return;
  }
};

Archiver.prototype._onQueueTask = function(task, callback) {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    callback();
    return;
  }

  this._task = task;
  this._moduleAppend(task.source, task.data, callback);
};

Archiver.prototype._onStatQueueTask = function(task, callback) {
  if (this._state.finalizing || this._state.finalized || this._state.aborted) {
    callback();
    return;
  }

  fs.stat(task.filepath, function(err, stats) {
    if (this._state.aborted) {
      setImmediate(callback);
      return;
    }

    if (err) {
      this.emit('error', err);
      setImmediate(callback);
      return;
    }

    task = this._updateQueueTaskWithStats(task, stats);

    if (task.source !== null) {
      this._queue.push(task);
      setImmediate(callback);
    } else {
      this.emit('error', new Error('unsupported entry: ' + task.filepath));
      setImmediate(callback);
      return;
    }
  }.bind(this));
};

Archiver.prototype._shutdown = function() {
  this._moduleUnpipe();
  this.end();
};

Archiver.prototype._transform = function(chunk, encoding, callback) {
  if (chunk) {
    this._pointer += chunk.length;
  }

  callback(null, chunk);
};

Archiver.prototype._updateQueueTaskWithStats = function(task, stats) {
  if (stats.isFile()) {
    task.data.type = 'file';
    task.data.sourceType = 'stream';
    task.source = util.lazyReadStream(task.filepath);
  } else if (stats.isDirectory() && this._moduleSupports('directory')) {
    task.data.name = util.trailingSlashIt(task.data.name);
    task.data.type = 'directory';
    task.data.sourcePath = util.trailingSlashIt(task.filepath);
    task.data.sourceType = 'buffer';
    task.source = new Buffer(0);
  } else {
    return task;
  }

  task.data = this._normalizeEntryData(task.data, stats);
  return task;
};

Archiver.prototype.abort = function() {
  if (this._state.aborted || this._state.finalized) {
    return this;
  }

  this._abort();

  return this;
};

Archiver.prototype.append = function(source, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('append: queue closed'));
    return this;
  }

  data = this._normalizeEntryData(data);

  if (typeof data.name !== 'string' || data.name.length === 0) {
    this.emit('error', new Error('append: entry name must be a non-empty string value'));
    return this;
  }

  if (data.type === 'directory' && !this._moduleSupports('directory')) {
    this.emit('error', new Error('append: entries of "directory" type not currently supported by this module'));
    return this;
  }

  source = util.normalizeInputSource(source);

  if (Buffer.isBuffer(source)) {
    data.sourceType = 'buffer';
  } else if (util.isStream(source)) {
    data.sourceType = 'stream';
  } else {
    this.emit('error', new Error('append: input source must be valid Stream or Buffer instance'));
    return this;
  }

  this._queue.push({
    data: data,
    source: source
  });

  return this;
};

Archiver.prototype.bulk = function(mappings) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('bulk: queue closed'));
    return this;
  }

  if (!Array.isArray(mappings)) {
    mappings = [mappings];
  }

  var self = this;
  var files = util.file.normalizeFilesArray(mappings);

  files.forEach(function(file){
    var isExpandedPair = file.orig.expand || false;
    var data = {};
    var dataFunction = false;

    if (typeof file.data === 'function') {
      dataFunction = file.data;
    } else if (typeof file.data === 'object') {
      data = file.data;
    }

    file.src.forEach(function(filepath) {
      var entryData = util._.extend({}, data);
      entryData.name = isExpandedPair ? util.unixifyPath(file.dest) : util.unixifyPath(file.dest || '', filepath);

      if (entryData.name === '.') {
        return;
      }

      try {
        entryData = dataFunction ? dataFunction(entryData) : entryData;

        if (dataFunction && typeof entryData !== 'object') {
          throw new Error('bulk: invalid data returned from custom function');
        }
      } catch(e) {
        self.emit('error', e);
        return;
      }

      self._append(filepath, entryData);
    });
  });

  return this;
};

Archiver.prototype.directory = function(dirpath, destpath, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('directory: queue closed'));
    return this;
  }

  if (typeof dirpath !== 'string' || dirpath.length === 0) {
    this.emit('error', new Error('directory: dirpath must be a non-empty string value'));
    return this;
  }

  this._pending++;

  if (destpath === false) {
    destpath = '';
  } else if (typeof destpath !== 'string'){
    destpath = dirpath;
  }

  var dataFunction = false;
  if (typeof data === 'function') {
    dataFunction = data;
    data = {};
  } else if (typeof data !== 'object') {
    data = {};
  }

  var self = this;

  util.walkdir(dirpath, function(err, results) {
    if (err) {
      self.emit('error', err);
    } else {
      results.forEach(function(file) {
        var entryData = util._.extend({}, data);
        entryData.name = util.sanitizePath(destpath, file.relative);
        entryData.stats = file.stats;

        try {
          entryData = dataFunction ? dataFunction(entryData) : entryData;

          if (dataFunction && typeof entryData !== 'object') {
            throw new Error('directory: invalid data returned from custom function');
          }
        } catch(e) {
          self.emit('error', e);
          return;
        }

        self._append(file.path, entryData);
      });
    }

    self._pending--;
    self._maybeFinalize();
  });

  return this;
};

Archiver.prototype.file = function(filepath, data) {
  if (this._state.finalize || this._state.aborted) {
    this.emit('error', new Error('file: queue closed'));
    return this;
  }

  if (typeof filepath !== 'string' || filepath.length === 0) {
    this.emit('error', new Error('file: filepath must be a non-empty string value'));
    return this;
  }

  this._append(filepath, data);

  return this;
};

Archiver.prototype.finalize = function() {
  if (this._state.aborted) {
    this.emit('error', new Error('finalize: archive was aborted'));
    return this;
  }

  if (this._state.finalize) {
    this.emit('error', new Error('finalize: archive already finalizing'));
    return this;
  }

  this._state.finalize = true;

  if (this._pending === 0 && this._queue.idle() && this._statQueue.idle()) {
    this._finalize();
  }

  return this;
};

// needs to be deprecated
Archiver.prototype.setFormat = function(format) {
  if (this._format) {
    this.emit('error', new Error('format: archive format already set'));
    return this;
  }

  this._format = format;

  return this;
};

// needs to be deprecated
Archiver.prototype.setModule = function(module) {
  if (this._state.aborted) {
    this.emit('error', new Error('module: archive was aborted'));
    return this;
  }

  if (this._state.module) {
    this.emit('error', new Error('module: module already set'));
    return this;
  }

  this._module = module;
  this._modulePipe();

  return this;
};

Archiver.prototype.pointer = function() {
  return this._pointer;
};

Archiver.prototype.use = function(plugin) {
  this._streams.push(plugin);
  return this;
};<|endoftext|>


<commit_before>'use strict';

/*
 * Kalabox core module.
 */

var config = exports.config = require('./core/config.js');

var deps = exports.deps = require('./core/deps.js');

var env = exports.env = require('./core/env.js');

var events = exports.events = require('./core/events.js');

var log = exports.log = require('./core/log.js');

var mode = exports.mode = require('./core/mode.js');

var tasks = exports.tasks = require('./core/tasks.js');
<commit_msg>Small refactor of lib/core.js.<commit_after>'use strict';

/*
 * Kalabox core module.
 */

// Config module.
exports.config = require('./core/config.js');

// Dependencies module.
exports.deps = require('./core/deps.js');

// Environment module.
exports.env = require('./core/env.js');

// Events module.
exports.events = require('./core/events.js');

// Loggin module.
exports.log = require('./core/log.js');

// Mode module.
exports.mode = require('./core/mode.js');

// Tasks module.
exports.tasks = require('./core/tasks.js');
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var extend = require('xtend');
var defaultAlgorithm = require('./algorithms/default.js');

var CONFIG_DEFAULTS = {
  minPeakDistance: 30,
  minPeakHeight: 0,
  transformedValueProperty: 'y'
};

function Slayer(config){
  /**
   * Algorithm object responsible to retrieve spikes in a series of data.
   * @type {Function}
   */
  this.algorithm = null;

  /**
   * Filters to apply when the data to exclude unwanted points.
   *
   * @type {Array.<Function>}
   */
  this.filters = [];

  /**
   * Instance configuration object.
   * @type {Object}
   */
  this.config = extend({}, CONFIG_DEFAULTS, config || {});

  this.use(defaultAlgorithm);

  this.configureFilters(this.config);
}

Slayer.prototype = {
  /**
   * Default item accessor.
   *
   * @param item {Number}
   * @param originalItem {Number}
   * @param i {Number}
   * @returns {Number}
   */
  getItem: function getItem(item, originalItem, i){
    return item;
  },
  /**
   * Default X value accessor.
   *
   * @param item {*}
   * @param i {Number}
   * @returns {Number}
   */
  getValueX: function(item, i){
    return i;
  },
  /**
   * Default Y value accessor.
   *
   * @param item {Number}
   * @returns {Number}
   */
  getValueY: function(item){
    return item;
  },
  /**
   * Configures the internal filters of a slayer instance
   */
  configureFilters: function configureFilters(config){
    if (config.hasOwnProperty('minPeakHeight')) {
      if (typeof config.minPeakHeight !== 'number' || config.minPeakHeight === NaN){
        throw new TypeError('config.minPeakHeight should be a numeric value. Was: ' + config.minPeakHeight);
      }

      this.filters.push(function minHeightFilter(item){
        return item >= config.minPeakHeight;
      });
    }
  },
  /**
   * Filters out any time series value which does not satisfy the filter.
   *
   * @param item {Number}
   * @returns {Boolean}
   */
  filterDataItem: function filterDataItem(item){
    return this.filters.some(function(filter){
      return filter.call(null, item);
    }) ? item : null;
  },
  /**
   * Plugs a new peak detection algorithm.
   *
   *
   * @param module {Function}
   * @returns {Slayer}
   */
  use: function use(fn){
    // external module
    if (typeof fn === 'function'){
      this.algorithm = fn;

      return this;
    }

    throw new TypeError('.use() expects its first and only paramter to be a peak detection function.')
  },
  /**
   * Index accessor applied to each series item.
   *
   * It will return this value as the `x` value of a spike object.
   *
   * @example
   ```js
   slayer()
   .x(function(item, i){
    return item.date;      // considering item looks like `{ date: '2014-04-12T17:31:40.000Z', value: 12 }`
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: '2014-04-12T17:31:40.000Z', y: 12 }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  x: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The x() mapper argument should be a function.');
    }

    this.getValueX = mapper;

    return this;
  },
  /**
   * Data accessor applied to each series item and used to determine spike values.
   *
   * It will return this value as the `y` value of a spike object.
   *
   * @example
   ```js
   slayer()
   .y(function(item){
    return item.value;     // considering item looks like `{ value: 12 }`
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: 4, y: 12 }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  y: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The y() mapper argument should be a function.');
    }

    this.getValueY = mapper;

    return this;
  },
  /**
   * Transforms the spike object before returning it as part of the found spike collections.
   *
   * It is useful if you want to add extra data to the returned spike object.
   *
   * @example
   ```js
   slayer()
   .transform(function(xyItem, originalItem, i){
    xyItem.id = originalItem.id;

    return xyItem;
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: 4, y: 12, id: '21232f297a57a5a743894a0e4a801fc3' }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  transform: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The transform() mapper argument should be a function.');
    }

    this.getItem = mapper;

    return this;
  }
};

module.exports = function SlayerFactory(config){
  return new Slayer(config);
};

module.exports.Slayer = Slayer;
<commit_msg>Remove unncessary check as minPeakDistance is always available<commit_after>'use strict';

var path = require('path');
var extend = require('xtend');
var defaultAlgorithm = require('./algorithms/default.js');

var CONFIG_DEFAULTS = {
  minPeakDistance: 30,
  minPeakHeight: 0,
  transformedValueProperty: 'y'
};

function Slayer(config){
  /**
   * Algorithm object responsible to retrieve spikes in a series of data.
   * @type {Function}
   */
  this.algorithm = null;

  /**
   * Filters to apply when the data to exclude unwanted points.
   *
   * @type {Array.<Function>}
   */
  this.filters = [];

  /**
   * Instance configuration object.
   * @type {Object}
   */
  this.config = extend({}, CONFIG_DEFAULTS, config || {});

  this.use(defaultAlgorithm);

  this.configureFilters(this.config);
}

Slayer.prototype = {
  /**
   * Default item accessor.
   *
   * @param item {Number}
   * @param originalItem {Number}
   * @param i {Number}
   * @returns {Number}
   */
  getItem: function getItem(item, originalItem, i){
    return item;
  },
  /**
   * Default X value accessor.
   *
   * @param item {*}
   * @param i {Number}
   * @returns {Number}
   */
  getValueX: function(item, i){
    return i;
  },
  /**
   * Default Y value accessor.
   *
   * @param item {Number}
   * @returns {Number}
   */
  getValueY: function(item){
    return item;
  },
  /**
   * Configures the internal filters of a slayer instance
   */
  configureFilters: function configureFilters(config){
    if (typeof config.minPeakHeight !== 'number' || config.minPeakHeight === NaN){
      throw new TypeError('config.minPeakHeight should be a numeric value. Was: ' + String(config.minPeakHeight));
    }

    this.filters.push(function minHeightFilter(item){
      return item >= config.minPeakHeight;
    });
  },
  /**
   * Filters out any time series value which does not satisfy the filter.
   *
   * @param item {Number}
   * @returns {Boolean}
   */
  filterDataItem: function filterDataItem(item){
    return this.filters.some(function(filter){
      return filter.call(null, item);
    }) ? item : null;
  },
  /**
   * Plugs a new peak detection algorithm.
   *
   *
   * @param module {Function}
   * @returns {Slayer}
   */
  use: function use(fn){
    // external module
    if (typeof fn === 'function'){
      this.algorithm = fn;

      return this;
    }

    throw new TypeError('.use() expects its first and only paramter to be a peak detection function.')
  },
  /**
   * Index accessor applied to each series item.
   *
   * It will return this value as the `x` value of a spike object.
   *
   * @example
   ```js
   slayer()
   .x(function(item, i){
    return item.date;      // considering item looks like `{ date: '2014-04-12T17:31:40.000Z', value: 12 }`
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: '2014-04-12T17:31:40.000Z', y: 12 }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  x: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The x() mapper argument should be a function.');
    }

    this.getValueX = mapper;

    return this;
  },
  /**
   * Data accessor applied to each series item and used to determine spike values.
   *
   * It will return this value as the `y` value of a spike object.
   *
   * @example
   ```js
   slayer()
   .y(function(item){
    return item.value;     // considering item looks like `{ value: 12 }`
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: 4, y: 12 }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  y: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The y() mapper argument should be a function.');
    }

    this.getValueY = mapper;

    return this;
  },
  /**
   * Transforms the spike object before returning it as part of the found spike collections.
   *
   * It is useful if you want to add extra data to the returned spike object.
   *
   * @example
   ```js
   slayer()
   .transform(function(xyItem, originalItem, i){
    xyItem.id = originalItem.id;

    return xyItem;
  })
   .fromArray(arrayData, function(err, spikes){
    console.log(spikes);   // { x: 4, y: 12, id: '21232f297a57a5a743894a0e4a801fc3' }
  });
   ```
   * @api
   * @param mapper {Function}
   * @returns {Slayer}
   */
  transform: function(mapper){
    if (typeof mapper !== 'function'){
      throw new TypeError('The transform() mapper argument should be a function.');
    }

    this.getItem = mapper;

    return this;
  }
};

module.exports = function SlayerFactory(config){
  return new Slayer(config);
};

module.exports.Slayer = Slayer;
<|endoftext|>


<commit_before>import { LightShadow } from './LightShadow.js';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';

function PointLightShadow() {

	LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) );

	this._frameExtents = new Vector2( 4, 2 );

	this._viewportCount = 6;

	this._viewports = [
		// These viewports map a cube-map onto a 2D texture with the
		// following orientation:
		//
		//  xzXZ
		//   y Y
		//
		// X - Positive x direction
		// x - Negative x direction
		// Y - Positive y direction
		// y - Negative y direction
		// Z - Positive z direction
		// z - Negative z direction

		// positive X
		new Vector4( 2, 1, 1, 1 ),
		// negative X
		new Vector4( 0, 1, 1, 1 ),
		// positive Z
		new Vector4( 3, 1, 1, 1 ),
		// negative Z
		new Vector4( 1, 1, 1, 1 ),
		// positive Y
		new Vector4( 3, 0, 1, 1 ),
		// negative Y
		new Vector4( 1, 0, 1, 1 )
	];

	this._cubeDirections = [
		new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
		new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
	];

	this._cubeUps = [
		new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
		new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),	new Vector3( 0, 0, - 1 )
	];

}

PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {

	constructor: PointLightShadow,

	isPointLightShadow: true,

	updateMatrices: function ( light, viewportIndex = 0 ) {

		const camera = this.camera,
			shadowMatrix = this.matrix,
			lightPositionWorld = this._lightPositionWorld,
			lookTarget = this._lookTarget,
			projScreenMatrix = this._projScreenMatrix;

		lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
		camera.position.copy( lightPositionWorld );

		lookTarget.copy( camera.position );
		lookTarget.add( this._cubeDirections[ viewportIndex ] );
		camera.up.copy( this._cubeUps[ viewportIndex ] );
		camera.lookAt( lookTarget );
		camera.updateMatrixWorld();

		shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );

		projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		this._frustum.setFromProjectionMatrix( projScreenMatrix );

	}

} );

export { PointLightShadow };
<commit_msg>PointLightShadow: Convert to ES6 class<commit_after>import { LightShadow } from './LightShadow.js';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';

class PointLightShadow extends LightShadow {

	constructor() {

		super( new PerspectiveCamera( 90, 1, 0.5, 500 ) );

		Object.defineProperty( this, 'isPointLightShadow', { value: true } );

		this._frameExtents = new Vector2( 4, 2 );

		this._viewportCount = 6;

		this._viewports = [
			// These viewports map a cube-map onto a 2D texture with the
			// following orientation:
			//
			//  xzXZ
			//   y Y
			//
			// X - Positive x direction
			// x - Negative x direction
			// Y - Positive y direction
			// y - Negative y direction
			// Z - Positive z direction
			// z - Negative z direction

			// positive X
			new Vector4( 2, 1, 1, 1 ),
			// negative X
			new Vector4( 0, 1, 1, 1 ),
			// positive Z
			new Vector4( 3, 1, 1, 1 ),
			// negative Z
			new Vector4( 1, 1, 1, 1 ),
			// positive Y
			new Vector4( 3, 0, 1, 1 ),
			// negative Y
			new Vector4( 1, 0, 1, 1 )
		];

		this._cubeDirections = [
			new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
			new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
		];

		this._cubeUps = [
			new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
			new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),	new Vector3( 0, 0, - 1 )
		];

	}

	updateMatrices( light, viewportIndex = 0 ) {

		const camera = this.camera;
		const	shadowMatrix = this.matrix;
		const	lightPositionWorld = this._lightPositionWorld;
		const	lookTarget = this._lookTarget;
		const	projScreenMatrix = this._projScreenMatrix;

		lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
		camera.position.copy( lightPositionWorld );

		lookTarget.copy( camera.position );
		lookTarget.add( this._cubeDirections[ viewportIndex ] );
		camera.up.copy( this._cubeUps[ viewportIndex ] );
		camera.lookAt( lookTarget );
		camera.updateMatrixWorld();

		shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );

		projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		this._frustum.setFromProjectionMatrix( projScreenMatrix );

	}

}

export { PointLightShadow };
<|endoftext|>


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

	//http://promises-aplus.github.io/promises-spec/
	//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

	//if node
	if (global.exports) {
		global.exports = Promise;
	}
	//if browser
	else {
		global.Prom = Promise;
	}

	//2.1 promise states
	var States = {
		pending: 0,
		fulfilled: 1,
		rejected: -1
	};

	//Make States immutable
	if (Object.freeze) {
		Object.freeze(States);
	}

	//Promise constructor
	function Promise(fn) {

		var state = States.pending;
		var valueOrReason;
		var callAsap;
		//Holds the handlers and promises of all the then calls on the current promise instance
		var thenCache = [];

		//setup a callAsap method to call asap on next tick or next iteration of event loop
		try {
			//if node
			if (process && process.nextTick) {
				callAsap = process.nextTick;
			}
			else if (setImmediate) {
				callAsap = setImmediate;
			}
		}
		catch (e) {
			//browser
			callAsap = function(cb) {
				window.setTimeout(cb, 0);
			};
		}

		//mozilla calls fulfill as resolve
		if (fn && typeof fn === "function") {
			fn(fulfill, reject);
		}

		//same as if above
		//try {
		//	(typeof fn === "function" && fn)();
		//}
		//catch(e){
		//}

		//Privileged functions

		this.then = function(onFulfilled, onRejected) {
			var thenPromise = new Promise();

			//store the handlers and the promise returned
			thenCache.push({
				promise: thenPromise,
				//when onFulfilled === "function" && onFulfilled evaluates to true
				//it actually evaluates to onFulfilled
				//which is final truthy value (hence it seems like its evaluated to true).
				//When it evaluates to a falsy value it returns the falsy value which
				//is "false" in this case from the === check
				onFulfilled: typeof onFulfilled === "function" && onFulfilled,
				onRejected: typeof onRejected === "function" && onRejected
			});

			return thenPromise;
		};

		//figure out a way to make sure that the call to resolve is from within the library
		//and not by a naughty user and/or some other piece of non-library code
		this.resolve = function(returnVal) {
			if (this === returnVal) {
				throw new TypeError("Promise cannot resolve to itself. Sorry brah!");
			}
			else if (returnVal.constructor.name === "Promise") {
				//promise should adopt state of returnVal as value is a promise
				adoptCurrentState(returnVal.state, returnVal.value);
				//add someway to adopt future state
			}
			else if (typeof returnVal === "object" || typeof returnVal === "function") {

			}
		};

		this.state = function() {
			return state;
		};

		this.value = function() {
			return valueOrReason;
		};

		//Private functions

		//maybe fulfill and reject can be merged into one function since they
		//do the same stuff on diff methods thats all

		function fulfill(value) {
			changeState("fulfilled");
			//2.1.2		When fulfilled, a promise:
			//2.1.2.2	must have a value, which must not change.
			valueOrReason = value;

			for (var i in thenCache) {
				var cacheElement = thenCache[i];
				try {
					if (cacheElement["onFulfilled"]) {
						callAsap(cacheElement["promise"].resolve(cacheElement["onFulfilled"](valueOrReason)));
					}
					else {
						//if onFulfilled is not a function then resolve (fulfill it while resolving)
						//promise with value from parent promise in chain
						callAsap(cacheElement["promise"].resolve(valueOrReason));
					}
				}
				catch (e) {
					//resolve with error (reject it with e as reason while resolving)
					callAsap(cacheElement["promise"].resolve(e));
				}
			}
		}

		function reject(reason) {
			changeState("rejected");
			//2.1.3		When rejected, a promise:
			//2.1.3.2	must have a reason, which must not change.
			valueOrReason = reason;

			for (var i in thenCache) {
				var cacheElement = thenCache[i];
				try {
					if (cacheElement["onRejected"]) {
						callAsap(cacheElement["promise"].resolve(cacheElement["onRejected"](valueOrReason)));
					}
					else {
						//if onRejected is not a function then resolve (reject it while resolving)
						//promise with reason from parent promise in chain
						callAsap(cacheElement["promise"].resolve(valueOrReason));
					}
				}
				catch (e) {
					//resolve with error (reject it with e as reason while resolving)
					callAsap(cacheElement["promise"].resolve(e));
				}
			}
		}

		function changeState(newState) {
			var newStateVal = States[newState];
			//The new state should be either pending, fulfilled or rejected
			if (!newStateVal) {
				throw new TypeError("State has to be fulfilled, rejected or pending.");
			}
			//2.1.1		When pending, a promise:
			//2.1.1.1	may transition to either the fulfilled or rejected state.
			if (state === States.pending && newStateVal !== States.pending) {
				state = newStateVal;
			}
			else {
				//2.1.2		When fulfilled, a promise:
				//2.1.2.1	must not transition to any other state.
				//2.1.3		When rejected, a promise:
				//2.1.3.1	must not transition to any other state.
				throw new TypeError("State cannot be changed once fulfilled or " +
					"rejected nor can it be made pending when already pending.");
			}

		}

		function adoptCurrentState(newState, value) {
			try {
				changeState(newState);
				valueOrReason = value;
			}
			catch (e) {
				throw e;
			}
		}

	}

	Promise.deferred = function() {

	};

	//mozilla calls this Promise.resolve
	Promise.fulfill = function(value) {

	};

	Promise.reject = function(reason) {

	};

	Promise.cast = function(value) {

	};

	Promise.all = function(promiseList) {

	};

	Promise.race = function(promiseList) {

	};
})(typeof module === "undefined" ? window : module);<commit_msg>fixed a comment<commit_after>(function(global) {
	'use strict';

	//http://promises-aplus.github.io/promises-spec/
	//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

	//if node
	if (global.exports) {
		global.exports = Promise;
	}
	//if browser
	else {
		global.Prom = Promise;
	}

	//2.1 promise states
	var States = {
		pending: 0,
		fulfilled: 1,
		rejected: -1
	};

	//Make States immutable
	if (Object.freeze) {
		Object.freeze(States);
	}

	//Promise constructor
	function Promise(fn) {

		var state = States.pending;
		var valueOrReason;
		var callAsap;
		//Holds the handlers and promises of all the then calls on the current promise instance
		var thenCache = [];

		//setup a callAsap method to call asap on next tick or next iteration of event loop
		try {
			//if node
			if (process && process.nextTick) {
				callAsap = process.nextTick;
			}
			else if (setImmediate) {
				callAsap = setImmediate;
			}
		}
		catch (e) {
			//browser
			callAsap = function(cb) {
				window.setTimeout(cb, 0);
			};
		}

		//mozilla calls fulfill as resolve
		if (fn && typeof fn === "function") {
			fn(fulfill, reject);
		}

		//same as if above
		//try {
		//	(typeof fn === "function" && fn)();
		//}
		//catch(e){
		//}

		//Privileged functions

		this.then = function(onFulfilled, onRejected) {
			var thenPromise = new Promise();

			//store the handlers and the promise returned
			thenCache.push({
				promise: thenPromise,
				//when onFulfilled === "function" && onFulfilled evaluates to true
				//it actually evaluates to onFulfilled
				//which is final truthy value (hence it seems like its evaluated to true).
				//When it evaluates to a falsy value it returns the falsy value which
				//is "false" in this case from the === check
				onFulfilled: typeof onFulfilled === "function" && onFulfilled,
				onRejected: typeof onRejected === "function" && onRejected
			});

			return thenPromise;
		};

		//figure out a way to make sure that the call to resolve is from within the library
		//and not by a naughty user and/or some other piece of non-library code
		this.resolve = function(returnVal) {
			if (this === returnVal) {
				throw new TypeError("Promise cannot resolve to itself. Sorry brah!");
			}
			else if (returnVal.constructor.name === "Promise") {
				//promise should adopt state of returnVal as value is a promise
				adoptCurrentState(returnVal.state, returnVal.value);
				//add someway to adopt future state
			}
			else if (typeof returnVal === "object" || typeof returnVal === "function") {

			}
		};

		this.state = function() {
			return state;
		};

		this.value = function() {
			return valueOrReason;
		};

		//Private functions

		//maybe fulfill and reject can be merged into one function since they
		//do the same stuff on diff methods thats all

		function fulfill(value) {
			changeState("fulfilled");
			//2.1.2		When fulfilled, a promise:
			//2.1.2.2	must have a value, which must not change.
			valueOrReason = value;

			for (var i in thenCache) {
				var cacheElement = thenCache[i];
				try {
					if (cacheElement["onFulfilled"]) {
						callAsap(cacheElement["promise"].resolve(cacheElement["onFulfilled"](valueOrReason)));
					}
					else {
						//if onFulfilled is not a function then resolve (fulfill it while resolving)
						//promise with value from parent promise in chain
						callAsap(cacheElement["promise"].resolve(valueOrReason));
					}
				}
				catch (e) {
					//resolve with error (reject it with 'e' as reason while resolving)
					callAsap(cacheElement["promise"].resolve(e));
				}
			}
		}

		function reject(reason) {
			changeState("rejected");
			//2.1.3		When rejected, a promise:
			//2.1.3.2	must have a reason, which must not change.
			valueOrReason = reason;

			for (var i in thenCache) {
				var cacheElement = thenCache[i];
				try {
					if (cacheElement["onRejected"]) {
						callAsap(cacheElement["promise"].resolve(cacheElement["onRejected"](valueOrReason)));
					}
					else {
						//if onRejected is not a function then resolve (reject it while resolving)
						//promise with reason from parent promise in chain
						callAsap(cacheElement["promise"].resolve(valueOrReason));
					}
				}
				catch (e) {
					//resolve with error (reject it with 'e' as reason while resolving)
					callAsap(cacheElement["promise"].resolve(e));
				}
			}
		}

		function changeState(newState) {
			var newStateVal = States[newState];
			//The new state should be either pending, fulfilled or rejected
			if (!newStateVal) {
				throw new TypeError("State has to be fulfilled, rejected or pending.");
			}
			//2.1.1		When pending, a promise:
			//2.1.1.1	may transition to either the fulfilled or rejected state.
			if (state === States.pending && newStateVal !== States.pending) {
				state = newStateVal;
			}
			else {
				//2.1.2		When fulfilled, a promise:
				//2.1.2.1	must not transition to any other state.
				//2.1.3		When rejected, a promise:
				//2.1.3.1	must not transition to any other state.
				throw new TypeError("State cannot be changed once fulfilled or " +
					"rejected nor can it be made pending when already pending.");
			}

		}

		function adoptCurrentState(newState, value) {
			try {
				changeState(newState);
				valueOrReason = value;
			}
			catch (e) {
				throw e;
			}
		}

	}

	Promise.deferred = function() {

	};

	//mozilla calls this Promise.resolve
	Promise.fulfill = function(value) {

	};

	Promise.reject = function(reason) {

	};

	Promise.cast = function(value) {

	};

	Promise.all = function(promiseList) {

	};

	Promise.race = function(promiseList) {

	};
})(typeof module === "undefined" ? window : module);<|endoftext|>


<commit_before>/* eslint-disable no-case-declarations, no-restricted-modules */

const os = require('os');
const cluster = require('cluster');
const EventEmitter = require('events').EventEmitter;
const oe = require('obj-ease');

let time;
let timeEnd;

class Core extends EventEmitter {
    constructor(config, log) {
        super();
        config = config || {};
        this.log = log;
        this.db = {};
        this.queries = {};
        this.views = {};
        this.viewsEnv = {};
        this.name = config.name || 'meta';
        this.backend = config.backend || 'file';
        this.scriptTimeout = config.scriptTimeout || 10000;

        if (config.verbosity === 'debug') {
            time = console.time;
            timeEnd = console.timeEnd;
        } else {
            time = () => {};
            timeEnd = () => {};
        }

        require('./backend/' + this.backend + '.js')(this);

        this.workers = [];
        this.numWorkers = os.cpus().length;

        cluster.setupMaster({
            exec: 'lib/worker.js',
            args: [],
            silent: false
        });

        cluster.on('online', worker => {
            this.workers.push(worker);
            log.info('worker ' + worker.process.pid + ' is online');
            worker.on('message', msg => {
                switch (msg.type) {
                    case 'view':
                        if (msg.payload === '') {
                            delete this.views[msg.id];
                        } else {
                            this.views[msg.id] = msg.payload;
                        }
                        this.emit('view', msg.id, msg.payload);
                        break;
                    default:
                        console.log(msg);
                }
            });
            if (this.workers.length === this.numWorkers) {
                log.info('all workers ready');
                startInit();
            }
        });

        const env = {};
        if (config.verbosity === 'debug') {
            env.DEBUG = '1';
        }
        for (let i = 0; i < this.numWorkers; i++) {
            cluster.fork(env);
        }

        this.on('update', (id, payload) => {
            this.workers.forEach(worker => {
                time('sending update to worker ' + worker.process.pid);
                worker.send({type: 'update', id, payload, rev: this.rev});
                timeEnd('sending update to worker ' + worker.process.pid);
            });
        });

        this.on('ready', () => {
            startInit();
        });

        let eventCount = 0;
        function startInit() {
            eventCount += 1;
            if (eventCount === 2) {
                init();
            }
        }

        const that = this;

        function init() {
            that.workers.forEach(worker => {
                time('sending db to worker ' + worker.process.pid);
                worker.send({type: 'db', db: that.db, rev: that.rev});
                timeEnd('sending db to worker ' + worker.process.pid);
            });
            Object.keys(that.queries).forEach(id => {
                that.query(id, that.queries[id], true);
            });
            log.info('init complete');
        }
    }

    getRev(id) {
        if (this.db[id] && (typeof this.db[id]._rev !== 'undefined')) {
            const rev = this.db[id]._rev;
            delete this.db[id]._rev;
            return rev;
        }
        return -1;
    }

    setRev(id, rev) {
        if (this.db[id]) {
            this.db[id]._rev = rev;
        }
    }

    incRev(id, rev) {
        if (this.db[id]) {
            this.db[id]._rev = rev + 1;
        }
    }

    set(id, payload) {
        if (payload === '') {
            return this.del(id);
        }
        if (typeof payload !== 'object') {
            return false;
        }
        delete payload._rev;
        delete payload._id;
        const rev = this.getRev(id);
        if (this.db[id]) {
            delete this.db[id]._id;
        }
        if (!oe.equal(this.db[id], payload)) {
            this.db[id] = payload;
            this.db[id]._id = id;
            this.incRev(id, rev);
            this.emit('update', id, this.db[id]);
            return true;
        }
        this.db[id]._id = id;

        this.setRev(id, rev);
        return false;
    }

    prop(id, payload) {
        let rev;
        switch (payload.method) {
            case 'set':
                rev = this.getRev(id);
                if (oe.setProp(this.db[id], payload.prop, payload.val)) {
                    delete this.db[id]._id;
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                this.setRev(id, rev);
                return false;

            case 'create':
                if (typeof oe.getProp(this.db[id], payload.prop) === 'undefined') {
                    rev = this.getRev(id);
                    oe.setProp(this.db[id], payload.prop, payload.val);
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                return false;

            case 'del':
                rev = this.getRev(id);
                if (oe.delProp(this.db[id], payload.prop)) {
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                this.setRev(id, rev);
                return false;

            default:
                console.log('unknown prop method', payload.method);
        }
    }

    extend(id, payload) {
        if (!payload || typeof payload !== 'object') {
            return false;
        }
        const rev = this.getRev(id);
        delete payload._id;
        delete payload._rev;
        if (this.db[id]) {
            delete this.db[id]._id;
        } else {
            this.db[id] = {};
        }
        const change = oe.extend(this.db[id], payload);
        this.db[id]._id = id;
        if (change) {
            this.incRev(id, rev);
            this.emit('update', id, this.db[id]);
            return true;
        }
        this.setRev(id, rev);
        return false;
    }

    del(id) {
        delete this.db[id];
        this.emit('update', id, '');
    }

    getWorker() {
        this.nextWorker = this.nextWorker || 0;
        const id = this.nextWorker;
        this.nextWorker += 1;
        if (this.nextWorker >= this.numWorkers) {
            this.nextWorker = 0;
        }
        return id;
    }

    query(id, payload, init) {
        if (!this.viewsEnv[id]) {
            this.viewsEnv[id] = {};
        }
        let workerId;
        if (!this.viewsEnv[id] || typeof this.viewsEnv[id].worker === 'undefined' || this.viewsEnv[id].worker >= this.numWorkers) {
            workerId = this.getWorker();
            this.viewsEnv[id].worker = workerId;
        } else {
            workerId = this.viewsEnv[id].worker;
        }

        if (payload === '') {
            delete this.queries[id];
            delete this.viewsEnv[id];
            delete this.views[id];
        } else {
            this.queries[id] = payload;
        }

        if (!init) {
            this.emit('query');
        }

        this.log.debug('sending query', id, 'to worker', workerId, payload);
        this.workers[workerId].send({type: 'query', id, payload, init: init ? this.views[id] : undefined});
    }

}

module.exports = Core;
<commit_msg>default name 'db'<commit_after>/* eslint-disable no-case-declarations, no-restricted-modules */

const os = require('os');
const cluster = require('cluster');
const EventEmitter = require('events').EventEmitter;
const oe = require('obj-ease');

let time;
let timeEnd;

class Core extends EventEmitter {
    constructor(config, log) {
        super();
        config = config || {};
        this.log = log;
        this.db = {};
        this.queries = {};
        this.views = {};
        this.viewsEnv = {};
        this.name = config.name || 'db';
        this.backend = config.backend || 'file';
        this.scriptTimeout = config.scriptTimeout || 10000;

        if (config.verbosity === 'debug') {
            time = console.time;
            timeEnd = console.timeEnd;
        } else {
            time = () => {};
            timeEnd = () => {};
        }

        require('./backend/' + this.backend + '.js')(this);

        this.workers = [];
        this.numWorkers = os.cpus().length;

        cluster.setupMaster({
            exec: 'lib/worker.js',
            args: [],
            silent: false
        });

        cluster.on('online', worker => {
            this.workers.push(worker);
            log.info('worker ' + worker.process.pid + ' is online');
            worker.on('message', msg => {
                switch (msg.type) {
                    case 'view':
                        if (msg.payload === '') {
                            delete this.views[msg.id];
                        } else {
                            this.views[msg.id] = msg.payload;
                        }
                        this.emit('view', msg.id, msg.payload);
                        break;
                    default:
                        console.log(msg);
                }
            });
            if (this.workers.length === this.numWorkers) {
                log.info('all workers ready');
                startInit();
            }
        });

        const env = {};
        if (config.verbosity === 'debug') {
            env.DEBUG = '1';
        }
        for (let i = 0; i < this.numWorkers; i++) {
            cluster.fork(env);
        }

        this.on('update', (id, payload) => {
            this.workers.forEach(worker => {
                time('sending update to worker ' + worker.process.pid);
                worker.send({type: 'update', id, payload, rev: this.rev});
                timeEnd('sending update to worker ' + worker.process.pid);
            });
        });

        this.on('ready', () => {
            startInit();
        });

        let eventCount = 0;
        function startInit() {
            eventCount += 1;
            if (eventCount === 2) {
                init();
            }
        }

        const that = this;

        function init() {
            that.workers.forEach(worker => {
                time('sending db to worker ' + worker.process.pid);
                worker.send({type: 'db', db: that.db, rev: that.rev});
                timeEnd('sending db to worker ' + worker.process.pid);
            });
            Object.keys(that.queries).forEach(id => {
                that.query(id, that.queries[id], true);
            });
            log.info('init complete');
        }
    }

    getRev(id) {
        if (this.db[id] && (typeof this.db[id]._rev !== 'undefined')) {
            const rev = this.db[id]._rev;
            delete this.db[id]._rev;
            return rev;
        }
        return -1;
    }

    setRev(id, rev) {
        if (this.db[id]) {
            this.db[id]._rev = rev;
        }
    }

    incRev(id, rev) {
        if (this.db[id]) {
            this.db[id]._rev = rev + 1;
        }
    }

    set(id, payload) {
        if (payload === '') {
            return this.del(id);
        }
        if (typeof payload !== 'object') {
            return false;
        }
        delete payload._rev;
        delete payload._id;
        const rev = this.getRev(id);
        if (this.db[id]) {
            delete this.db[id]._id;
        }
        if (!oe.equal(this.db[id], payload)) {
            this.db[id] = payload;
            this.db[id]._id = id;
            this.incRev(id, rev);
            this.emit('update', id, this.db[id]);
            return true;
        }
        this.db[id]._id = id;

        this.setRev(id, rev);
        return false;
    }

    prop(id, payload) {
        let rev;
        switch (payload.method) {
            case 'set':
                rev = this.getRev(id);
                if (oe.setProp(this.db[id], payload.prop, payload.val)) {
                    delete this.db[id]._id;
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                this.setRev(id, rev);
                return false;

            case 'create':
                if (typeof oe.getProp(this.db[id], payload.prop) === 'undefined') {
                    rev = this.getRev(id);
                    oe.setProp(this.db[id], payload.prop, payload.val);
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                return false;

            case 'del':
                rev = this.getRev(id);
                if (oe.delProp(this.db[id], payload.prop)) {
                    this.db[id]._id = id;
                    this.incRev(id, rev);
                    this.emit('update', id, this.db[id]);
                    return true;
                }
                this.setRev(id, rev);
                return false;

            default:
                console.log('unknown prop method', payload.method);
        }
    }

    extend(id, payload) {
        if (!payload || typeof payload !== 'object') {
            return false;
        }
        const rev = this.getRev(id);
        delete payload._id;
        delete payload._rev;
        if (this.db[id]) {
            delete this.db[id]._id;
        } else {
            this.db[id] = {};
        }
        const change = oe.extend(this.db[id], payload);
        this.db[id]._id = id;
        if (change) {
            this.incRev(id, rev);
            this.emit('update', id, this.db[id]);
            return true;
        }
        this.setRev(id, rev);
        return false;
    }

    del(id) {
        delete this.db[id];
        this.emit('update', id, '');
    }

    getWorker() {
        this.nextWorker = this.nextWorker || 0;
        const id = this.nextWorker;
        this.nextWorker += 1;
        if (this.nextWorker >= this.numWorkers) {
            this.nextWorker = 0;
        }
        return id;
    }

    query(id, payload, init) {
        if (!this.viewsEnv[id]) {
            this.viewsEnv[id] = {};
        }
        let workerId;
        if (!this.viewsEnv[id] || typeof this.viewsEnv[id].worker === 'undefined' || this.viewsEnv[id].worker >= this.numWorkers) {
            workerId = this.getWorker();
            this.viewsEnv[id].worker = workerId;
        } else {
            workerId = this.viewsEnv[id].worker;
        }

        if (payload === '') {
            delete this.queries[id];
            delete this.viewsEnv[id];
            delete this.views[id];
        } else {
            this.queries[id] = payload;
        }

        if (!init) {
            this.emit('query');
        }

        this.log.debug('sending query', id, 'to worker', workerId, payload);
        this.workers[workerId].send({type: 'query', id, payload, init: init ? this.views[id] : undefined});
    }

}

module.exports = Core;
<|endoftext|>


<commit_before>var absURLRegEx = /^[^\/]+:\/\//;

function readMemberExpression(p, value) {
  var pParts = p.split('.');
  while (pParts.length)
    value = value[pParts.shift()];
  return value;
}

var baseURLCache = {};
function getBaseURLObj() {
  if (baseURLCache[this.baseURL])
    return baseURLCache[this.baseURL];

  // normalize baseURL if not already
  if (this.baseURL[this.baseURL.length - 1] != '/')
    this.baseURL += '/';

  var baseURL = new URL(this.baseURL, baseURI);

  this.baseURL = baseURL.href;

  return (baseURLCache[this.baseURL] = baseURL);
}

var baseURIObj = new URL(baseURI);

(function() {

hookConstructor(function(constructor) {
  return function() {
    constructor.call(this);

    // support baseURL
    this.baseURL = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);

    // support the empty module, as a concept
    this.set('@empty', this.newModule({}));
  };
});

/*
  Normalization

  If a name is relative, we apply URL normalization to the page
  If a name is an absolute URL, we leave it as-is

  Plain names (neither of the above) run through the map and package
  normalization phases (applying before and after this one).

  The paths normalization phase applies last (paths extension), which
  defines the `normalizeSync` function and normalizes everything into
  a URL.

  The final normalization
 */
hook('normalize', function() {
  return function(name, parentName) {
    // relative URL-normalization
    if (name[0] == '.' || name[0] == '/')
      return new URL(name, parentName || baseURIObj).href;
    return name;
  };
});

/*
  __useDefault

  When a module object looks like:
  newModule(
    __useDefault: true,
    default: 'some-module'
  })

  Then importing that module provides the 'some-module'
  result directly instead of the full module.

  Useful for eg module.exports = function() {}
*/
hook('import', function(systemImport) {
  return function(name, parentName, parentAddress) {
    return systemImport.call(this, name, parentName, parentAddress).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  };
});

/*
 Extend config merging one deep only

  loader.config({
    some: 'random',
    config: 'here',
    deep: {
      config: { too: 'too' }
    }
  });

  <=>

  loader.some = 'random';
  loader.config = 'here'
  loader.deep = loader.deep || {};
  loader.deep.config = { too: 'too' };

  Normalizes meta and package configs allowing for:

  System.config({
    meta: {
      './index.js': {}
    }
  });

  To become

  System.meta['https://thissite.com/index.js'] = {};

  For easy normalization canonicalization with latest URL support.

*/
var packageProperties = ['main', 'format', 'defaultExtension', 'meta', 'map'];
SystemJSLoader.prototype.config = function(cfg) {

  // always configure baseURL first
  if (cfg.baseURL) {
    var hasConfig = false;
    function checkHasConfig(obj) {
      for (var p in obj)
        return true;
    }
    if (checkHasConfig(this.packages) || checkHasConfig(this.meta) || checkHasConfig(this.depCache) || checkHasConfig(this.bundles))
      throw new TypeError('baseURL should only be configured once and must be configured first.');

    this.baseURL = cfg.baseURL;

    // sanitize baseURL
    getBaseURLObj.call(this);
  }

  if (cfg.defaultJSExtensions)
    this.defaultJSExtensions = cfg.defaultJSExtensions;

  if (cfg.pluginFirst)
    this.pluginFirst = cfg.pluginFirst;

  if (cfg.paths) {
    for (var p in cfg.paths)
      this.paths[p] = cfg.paths[p];
  }

  if (cfg.map) {
    for (var p in cfg.map) {
      var v = cfg.map[p];

      // object map backwards-compat into packages configuration
      if (typeof v !== 'string') {
        var normalized = this.normalizeSync(p);

        // if doing default js extensions, undo to get package name
        if (this.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js')
          normalized = normalized.substr(0, normalized.length - 3);

        // if a package main, revert it
        var pkgMatch = '';
        for (var pkg in this.packages) {
          if (normalized.substr(0, pkg.length) == pkg
              && (!normalized[pkg.length] || normalized[pkg.length] == '/')
              && pkgMatch.split('/').length < pkg.split('/').length)
            pkgMatch = pkg;
        }
        if (pkgMatch && this.packages[pkgMatch].main)
          normalized = normalized.substr(0, normalized.length - this.packages[pkgMatch].main.length - 1);

        var pkg = this.packages[normalized] = this.packages[normalized] || {};
        pkg.map = v;
      }
      else {
        this.map[p] = v;
      }
    }
  }

  if (cfg.packagePaths) {
    for (var i = 0; i < cfg.packagePaths.length; i++) {
      var path = cfg.packagePaths[i];
      var normalized = this.normalizeSync(path);
      if (this.defaultJSExtensions && path.substr(path.length - 3, 3) != '.js')
        normalized = normalized.substr(0, normalized.length - 3);
      cfg.packagePaths[i] = normalized;
    }
  }

  if (cfg.packages) {
    for (var p in cfg.packages) {
      // request with trailing "/" to get package name exactly
      var prop = this.normalizeSync(p + '/');
      prop = prop.substr(0, prop.length - 1);

      // if doing default js extensions, undo to get package name
      if (this.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js')
        prop = prop.substr(0, prop.length - 3);

      this.packages[prop]= this.packages[prop] || {};
      for (var q in cfg.packages[p])
        if (indexOf.call(packageProperties, q) == -1 && typeof console != 'undefined' && console.warn)
          console.warn('"' + q + '" is not a valid package configuration option in package ' + p);

      extendMeta(this.packages[prop], cfg.packages[p]);
    }
  }

  if (cfg.bundles) {
    for (var p in cfg.bundles) {
      var bundle = [];
      for (var i = 0; i < cfg.bundles[p].length; i++)
        bundle.push(this.normalizeSync(cfg.bundles[p][i]));
      this.bundles[p] = bundle;
    }
  }

  for (var c in cfg) {
    var v = cfg[c];
    var normalizeProp = false, normalizeValArray = false;

    if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths')
      continue;

    if (typeof v != 'object' || v instanceof Array) {
      this[c] = v;
    }
    else {
      this[c] = this[c] || {};

      if (c == 'meta' || c == 'depCache')
        normalizeProp = true;

      for (var p in v) {
        if (c == 'meta' && p[0] == '*')
          this[c][p] = v[p];
        else if (normalizeProp)
          this[c][this.normalizeSync(p)] = v[p];
        else
          this[c][p] = v[p];
      }
    }
  }
};

})();<commit_msg>with exact package lookup, no need to provide separate extension removal<commit_after>var absURLRegEx = /^[^\/]+:\/\//;

function readMemberExpression(p, value) {
  var pParts = p.split('.');
  while (pParts.length)
    value = value[pParts.shift()];
  return value;
}

var baseURLCache = {};
function getBaseURLObj() {
  if (baseURLCache[this.baseURL])
    return baseURLCache[this.baseURL];

  // normalize baseURL if not already
  if (this.baseURL[this.baseURL.length - 1] != '/')
    this.baseURL += '/';

  var baseURL = new URL(this.baseURL, baseURI);

  this.baseURL = baseURL.href;

  return (baseURLCache[this.baseURL] = baseURL);
}

var baseURIObj = new URL(baseURI);

(function() {

hookConstructor(function(constructor) {
  return function() {
    constructor.call(this);

    // support baseURL
    this.baseURL = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);

    // support the empty module, as a concept
    this.set('@empty', this.newModule({}));
  };
});

/*
  Normalization

  If a name is relative, we apply URL normalization to the page
  If a name is an absolute URL, we leave it as-is

  Plain names (neither of the above) run through the map and package
  normalization phases (applying before and after this one).

  The paths normalization phase applies last (paths extension), which
  defines the `normalizeSync` function and normalizes everything into
  a URL.

  The final normalization
 */
hook('normalize', function() {
  return function(name, parentName) {
    // relative URL-normalization
    if (name[0] == '.' || name[0] == '/')
      return new URL(name, parentName || baseURIObj).href;
    return name;
  };
});

/*
  __useDefault

  When a module object looks like:
  newModule(
    __useDefault: true,
    default: 'some-module'
  })

  Then importing that module provides the 'some-module'
  result directly instead of the full module.

  Useful for eg module.exports = function() {}
*/
hook('import', function(systemImport) {
  return function(name, parentName, parentAddress) {
    return systemImport.call(this, name, parentName, parentAddress).then(function(module) {
      return module.__useDefault ? module['default'] : module;
    });
  };
});

/*
 Extend config merging one deep only

  loader.config({
    some: 'random',
    config: 'here',
    deep: {
      config: { too: 'too' }
    }
  });

  <=>

  loader.some = 'random';
  loader.config = 'here'
  loader.deep = loader.deep || {};
  loader.deep.config = { too: 'too' };

  Normalizes meta and package configs allowing for:

  System.config({
    meta: {
      './index.js': {}
    }
  });

  To become

  System.meta['https://thissite.com/index.js'] = {};

  For easy normalization canonicalization with latest URL support.

*/
var packageProperties = ['main', 'format', 'defaultExtension', 'meta', 'map'];
SystemJSLoader.prototype.config = function(cfg) {

  // always configure baseURL first
  if (cfg.baseURL) {
    var hasConfig = false;
    function checkHasConfig(obj) {
      for (var p in obj)
        return true;
    }
    if (checkHasConfig(this.packages) || checkHasConfig(this.meta) || checkHasConfig(this.depCache) || checkHasConfig(this.bundles))
      throw new TypeError('baseURL should only be configured once and must be configured first.');

    this.baseURL = cfg.baseURL;

    // sanitize baseURL
    getBaseURLObj.call(this);
  }

  if (cfg.defaultJSExtensions)
    this.defaultJSExtensions = cfg.defaultJSExtensions;

  if (cfg.pluginFirst)
    this.pluginFirst = cfg.pluginFirst;

  if (cfg.paths) {
    for (var p in cfg.paths)
      this.paths[p] = cfg.paths[p];
  }

  if (cfg.map) {
    for (var p in cfg.map) {
      var v = cfg.map[p];

      // object map backwards-compat into packages configuration
      if (typeof v !== 'string') {
        var normalized = this.normalizeSync(p);

        // if doing default js extensions, undo to get package name
        if (this.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js')
          normalized = normalized.substr(0, normalized.length - 3);

        // if a package main, revert it
        var pkgMatch = '';
        for (var pkg in this.packages) {
          if (normalized.substr(0, pkg.length) == pkg
              && (!normalized[pkg.length] || normalized[pkg.length] == '/')
              && pkgMatch.split('/').length < pkg.split('/').length)
            pkgMatch = pkg;
        }
        if (pkgMatch && this.packages[pkgMatch].main)
          normalized = normalized.substr(0, normalized.length - this.packages[pkgMatch].main.length - 1);

        var pkg = this.packages[normalized] = this.packages[normalized] || {};
        pkg.map = v;
      }
      else {
        this.map[p] = v;
      }
    }
  }

  if (cfg.packagePaths) {
    for (var i = 0; i < cfg.packagePaths.length; i++) {
      var path = cfg.packagePaths[i];
      var normalized = this.normalizeSync(path);
      if (this.defaultJSExtensions && path.substr(path.length - 3, 3) != '.js')
        normalized = normalized.substr(0, normalized.length - 3);
      cfg.packagePaths[i] = normalized;
    }
  }

  if (cfg.packages) {
    for (var p in cfg.packages) {
      // request with trailing "/" to get package name exactly
      var prop = this.normalizeSync(p + '/');
      prop = prop.substr(0, prop.length - 1);

      this.packages[prop]= this.packages[prop] || {};
      for (var q in cfg.packages[p])
        if (indexOf.call(packageProperties, q) == -1 && typeof console != 'undefined' && console.warn)
          console.warn('"' + q + '" is not a valid package configuration option in package ' + p);

      extendMeta(this.packages[prop], cfg.packages[p]);
    }
  }

  if (cfg.bundles) {
    for (var p in cfg.bundles) {
      var bundle = [];
      for (var i = 0; i < cfg.bundles[p].length; i++)
        bundle.push(this.normalizeSync(cfg.bundles[p][i]));
      this.bundles[p] = bundle;
    }
  }

  for (var c in cfg) {
    var v = cfg[c];
    var normalizeProp = false, normalizeValArray = false;

    if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths')
      continue;

    if (typeof v != 'object' || v instanceof Array) {
      this[c] = v;
    }
    else {
      this[c] = this[c] || {};

      if (c == 'meta' || c == 'depCache')
        normalizeProp = true;

      for (var p in v) {
        if (c == 'meta' && p[0] == '*')
          this[c][p] = v[p];
        else if (normalizeProp)
          this[c][this.normalizeSync(p)] = v[p];
        else
          this[c][p] = v[p];
      }
    }
  }
};

})();<|endoftext|>


<commit_before>var later = require('later');
var moment = require('moment');
require('moment-precise-range-plugin');

function serviceUptimeStart() {
    var uptimeLogLevel = 'verbose',
        uptimeInterval = 'every 600 seconds';

    // Formatter for numbers
    const formatter = new Intl.NumberFormat('en-US');

    // Log uptime to console
    Number.prototype.toTime = function(isSec) {
        var ms = isSec ? this * 1e3 : this,
            lm = ~(4 * !!isSec),
            /* limit fraction */
            fmt = new Date(ms).toISOString().slice(11, lm);

        if (ms >= 8.64e7) {
            /* >= 24 hours */
            var parts = fmt.split(/:(?=\d{2}:)/);
            parts[0] -= -24 * ((ms / 8.64e7) | 0);
            return parts.join(':');
        }

        return fmt;
    };

    var startTime = Date.now();
    var startIterations = 0;

    var uptimeCheck = later.setInterval(function() {
        startIterations++;
        let uptimeMilliSec = Date.now() - startTime;
        moment.duration(uptimeMilliSec);

        logger.log(uptimeLogLevel, '--------------------------------');
        logger.log(
            uptimeLogLevel,
            'Iteration # ' +
                formatter.format(startIterations) +
                ', Uptime: ' +
                moment.preciseDiff(0, uptimeMilliSec) +

                // formatter.format(uptimeMilliSec / 1000) +
                // ' seconds' +
                ', Heap used: ' +
                formatter.format(process.memoryUsage().heapUsed),
        );
    }, later.parse.text(uptimeInterval));
}

module.exports = {
    serviceUptimeStart,
};
<commit_msg>More metrics in uptime message<commit_after>
var later = require('later');
var moment = require('moment');
require('moment-precise-range-plugin');
const globals = require('../globals');

function serviceUptimeStart() {
    var uptimeLogLevel = 'verbose',
        uptimeInterval = 'every 15 seconds';
    // uptimeInterval = 'every 60 seconds';

    // Formatter for numbers
    const formatter = new Intl.NumberFormat('en-US');

    // Log uptime to console
    Number.prototype.toTime = function(isSec) {
        var ms = isSec ? this * 1e3 : this,
            lm = ~(4 * !!isSec),
            /* limit fraction */
            fmt = new Date(ms).toISOString().slice(11, lm);

        if (ms >= 8.64e7) {
            /* >= 24 hours */
            var parts = fmt.split(/:(?=\d{2}:)/);
            parts[0] -= -24 * ((ms / 8.64e7) | 0);
            return parts.join(':');
        }

        return fmt;
    };

    var startTime = Date.now();
    var startIterations = 0;

    later.setInterval(function() {
        startIterations++;
        let uptimeMilliSec = Date.now() - startTime;
        moment.duration(uptimeMilliSec);

        let heapTotal = Math.round(process.memoryUsage().heapTotal / 1024 / 1024 * 100) / 100,
            heapUsed = Math.round(process.memoryUsage().heapUsed / 1024 / 1024 * 100) / 100,
            processMemory = Math.round(process.memoryUsage().rss / 1024 / 1024 * 100) / 100;

        globals.logger.log(uptimeLogLevel, '--------------------------------');
        globals.logger.log(
            uptimeLogLevel,
            'Iteration # ' +
                formatter.format(startIterations) +
                ', Uptime: ' +
                moment.preciseDiff(0, uptimeMilliSec) +

                // formatter.format(uptimeMilliSec / 1000) +
                // ' seconds' +
                `, Heap used ${heapUsed} MB of total heap ${heapTotal} MB. Memory allocated to process: ${processMemory} MB.`
        );
    }, later.parse.text(uptimeInterval));
}

module.exports = {
    serviceUptimeStart,
};
<|endoftext|>


<commit_before>feedhoosControllers.controller(
    "ReaderCtrl",
    ["$scope", "$routeParams", "$http", "$timeout", "readingManager", "timelineManager", "bookmarkManager", "readingEntryManager", "timelineEntryManager", "folderManager", "folderEntryManager",
    function($scope, $routeParams, $http, $timeout, readingManager, timelineManager, bookmarkManager, readingEntryManager, timelineEntryManager, folderManager, folderEntryManager) {
        $scope.type = "";
        //現在選択されているfeedのid
        $scope._feed_id = null;
        $scope.feed = null;
        $scope.folders = null;
        $scope.entries = null;
        $scope.feeds = [];
        $scope.bookmark = null;
        $scope.active_reading_id = -1;
        $scope.active_timeline_id = -1;
        $scope.feed_tab = true;
        $scope.timeline_tab = true;
        var predict_func = function() {
            return $scope.bookmark === null || $scope.folders === null;
        }
        bookmarkManager.set($scope, function(scope, that) {
            scope.bookmark = that.data;
        });
        folderManager.set($scope, function(scope, that) {
            scope.folders = that.data;
        });
        timelineManager.set($scope, function(scope, that) {
            that.wait($timeout, 25, predict_func, function() {
                var feeds = [];
                var timelines = that.attachRating(that.data);
                Array.prototype.push.apply(feeds, timelines);
                Array.prototype.push.apply(feeds, scope.folders);
                scope.feeds = feeds;
            });
        });
        readingManager.set($scope, function(scope, that) {
            that.wait($timeout, 25, predict_func,  function() {
                scope.readings = that.sortByRating(that.data);
            });
        });
        $scope.read_timeline = function(feed_id, type) {
            $scope.active_timeline_id = feed_id;
            if (type == "feed") {
                timelineEntryManager.read_feed($scope, feed_id, type);
            }
            else if (type == "folder") {
                folderEntryManager.read_feed($scope, feed_id, type);
            }
        }
        $scope.read_reading = function(feed_id, type) {
            $scope.active_reading_id = feed_id;
            readingEntryManager.read_feed($scope, feed_id, type);
        }
    }]
);
<commit_msg>不要な引数を削除<commit_after>feedhoosControllers.controller(
    "ReaderCtrl",
    ["$scope", "$routeParams", "$http", "$timeout", "readingManager", "timelineManager", "bookmarkManager", "readingEntryManager", "timelineEntryManager", "folderManager", "folderEntryManager",
    function($scope, $routeParams, $http, $timeout, readingManager, timelineManager, bookmarkManager, readingEntryManager, timelineEntryManager, folderManager, folderEntryManager) {
        $scope.type = "";
        //現在選択されているfeedのid
        $scope._feed_id = null;
        $scope.feed = null;
        $scope.folders = null;
        $scope.entries = null;
        $scope.feeds = [];
        $scope.bookmark = null;
        $scope.active_reading_id = -1;
        $scope.active_timeline_id = -1;
        $scope.feed_tab = true;
        $scope.timeline_tab = true;
        var predict_func = function() {
            return $scope.bookmark === null || $scope.folders === null;
        }
        bookmarkManager.set($scope, function(scope, that) {
            scope.bookmark = that.data;
        });
        folderManager.set($scope, function(scope, that) {
            scope.folders = that.data;
        });
        timelineManager.set($scope, function(scope, that) {
            that.wait($timeout, 25, predict_func, function() {
                var feeds = [];
                var timelines = that.attachRating();
                Array.prototype.push.apply(feeds, timelines);
                Array.prototype.push.apply(feeds, scope.folders);
                scope.feeds = feeds;
            });
        });
        readingManager.set($scope, function(scope, that) {
            that.wait($timeout, 25, predict_func,  function() {
                scope.readings = that.sortByRating(that.data);
            });
        });
        $scope.read_timeline = function(feed_id, type) {
            $scope.active_timeline_id = feed_id;
            if (type == "feed") {
                timelineEntryManager.read_feed($scope, feed_id, type);
            }
            else if (type == "folder") {
                folderEntryManager.read_feed($scope, feed_id, type);
            }
        }
        $scope.read_reading = function(feed_id, type) {
            $scope.active_reading_id = feed_id;
            readingEntryManager.read_feed($scope, feed_id, type);
        }
    }]
);
<|endoftext|>