<commit_before>'use strict';

var EventEmitter = require('events').EventEmitter,
  Gpio = require('onoff').Gpio,
  Q = require('q'),
  util = require('util'),
  tick = global.setImmediate || process.nextTick;

var ROW_OFFSETS = [0x00, 0x40, 0x14, 0x54];

// TODO - Don't use magic numbers, define constants instead.

function Lcd(config) {
  var i;

  if (!(this instanceof Lcd)) {
    return new Lcd(config);
  }

  EventEmitter.call(this);

  this.cols = config.cols || 16; // TODO - Never used, remove?
  this.rows = config.rows || 1;
  this.largeFont = !!config.largeFont;

  this.rs = new Gpio(config.rs, 'low'); // reg. select, output, initially low
  this.e = new Gpio(config.e, 'low'); // enable, output, initially low

  this.data = []; // data bus, db4 thru db7, outputs, initially low
  for (i = 0; i < config.data.length; i += 1) {
    this.data.push(new Gpio(config.data[i], 'low'));
  }

  this.displayControl = 0x0c; // display on, cursor off, cursor blink off
  this.displayMode = 0x06; // left to right, no shift

  this.init();
}

util.inherits(Lcd, EventEmitter);
module.exports = Lcd;

// private
Lcd.prototype.init = function () {
  Q.delay(16)                                               // wait > 15ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 1st wake up
  .delay(6)                                                 // wait > 4.1ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 2nd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 3rd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () {
    var displayFunction = 0x20;

    this._write4Bits(0x02); // 4 bit interface

    if (this.rows > 1) {
      displayFunction |= 0x08;
    }
    if (this.rows === 1 && this.largeFont) {
      displayFunction |= 0x04;
    }
    this._command(displayFunction);

    this._command(0x10);
    this._command(this.displayControl);
    this._command(this.displayMode);

    this._command(0x01); // clear display (don't call clear to avoid event)
  }.bind(this))
  .delay(3)             // wait > 1.52ms for display to clear
  .then(function () { this.emit('ready'); }.bind(this));
};

Lcd.prototype.print = function (val, cb) {
  var index,
    displayFills;

  val += '';

  // If n*80+m characters should be printed, where n>1, m<80, don't display the
  // first (n-1)*80 characters as they will be overwritten. For example, if
  // asked to print 802 characters, don't display the first 720.
  displayFills = Math.floor(val.length / 80);
  index = displayFills > 1 ? (displayFills - 1) * 80 : 0;

  this._printChar(val, index, cb);
};

// private
Lcd.prototype._printChar = function (str, index, cb) {
  tick(function () {
    if (index >= str.length) {
      if (cb) {
        return cb(null, str);
      }

      return this.emit('printed', str);
    }

    try {
      this._write(str.charCodeAt(index));
      this._printChar(str, index + 1, cb);
    } catch (e) {
      if (cb) {
        return cb(e);
      }

      return this.emit('error', e);
    }
  }.bind(this));
};

Lcd.prototype.clear = function (cb) {
  // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
  this._commandAndDelay(0x01, 3, 'clear', cb);
};

Lcd.prototype.home = function (cb) {
  // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
  this._commandAndDelay(0x02, 3, 'home', cb);
};

Lcd.prototype.setCursor = function (col, row) {
  var r = row > this.rows ? this.rows - 1 : row;
  this._command(0x80 | (col + ROW_OFFSETS[r]));
};

Lcd.prototype.display = function () {
  this.displayControl |= 0x04;
  this._command(this.displayControl);
};

Lcd.prototype.noDisplay = function () {
  this.displayControl &= ~0x04;
  this._command(this.displayControl);
};

Lcd.prototype.cursor = function () {
  this.displayControl |= 0x02;
  this._command(this.displayControl);
};

Lcd.prototype.noCursor = function () {
  this.displayControl &= ~0x02;
  this._command(this.displayControl);
};

Lcd.prototype.blink = function () {
  this.displayControl |= 0x01;
  this._command(this.displayControl);
};

Lcd.prototype.noBlink = function () {
  this.displayControl &= ~0x01;
  this._command(this.displayControl);
};

Lcd.prototype.scrollDisplayLeft = function () {
  this._command(0x18);
};

Lcd.prototype.scrollDisplayRight = function () {
  this._command(0x1c);
};

Lcd.prototype.leftToRight = function () {
  this.displayMode |= 0x02;
  this._command(this.displayMode);
};

Lcd.prototype.rightToLeft = function () {
  this.displayMode &= ~0x02;
  this._command(this.displayMode);
};

Lcd.prototype.autoscroll = function () {
  this.displayMode |= 0x01;
  this._command(this.displayMode);
};

Lcd.prototype.noAutoscroll = function () {
  this.displayMode &= ~0x01;
  this._command(this.displayMode);
};

Lcd.prototype.close = function () {
  var i;

  this.rs.unexport();
  this.e.unexport();

  for (i = 0; i < this.data.length; i += 1) {
    this.data[i].unexport();
  }
};

// private
Lcd.prototype._commandAndDelay = function (command, timeout, event, cb) {
  tick(function () {
    try {
      this._command(command);

      setTimeout(function () {
        if (cb) {
          return cb(null);
        }

        return this.emit(event);
      }.bind(this), timeout);
    } catch (e) {
      if (cb) {
        return cb(e);
      }

      return this.emit('error', e);
    }
  }.bind(this));
};

// private
Lcd.prototype._command = function (cmd) {
  this._send(cmd, 0);
};

// private
Lcd.prototype._write = function (val) {
  this._send(val, 1);
};

// private
Lcd.prototype._send = function (val, mode) {
  this.rs.writeSync(mode);
  this._write4Bits(val >> 4);
  this._write4Bits(val);
};

// private
Lcd.prototype._write4Bits = function (val) {
  var i;

  for (i = 0; i < this.data.length; i += 1, val = val >> 1) {
    this.data[i].writeSync(val & 1);
  }

  // enable pulse >= 300ns
  // writeSync takes ~10 microseconds to execute on the BBB, so there's
  // nothing special needed to wait 300 nanoseconds.
  this.e.writeSync(1);
  this.e.writeSync(0);
};

<commit_msg>Got rid of the magic numbers and replaced them with a command map<commit_after>'use strict';

var EventEmitter = require('events').EventEmitter,
  Gpio = require('onoff').Gpio,
  Q = require('q'),
  util = require('util'),
  tick = global.setImmediate || process.nextTick;

var __ROW_OFFSETS = [0x00, 0x40, 0x14, 0x54];

var __COMMANDS = {
  CLEAR_DISPLAY: 0x01,
  HOME: 0x02,
  SET_CURSOR: 0x80,
  DISPLAY_ON: 0x04,
  DISPLAY_OFF: ~0x04,
  CURSOR_ON: 0x02,
  CURSOR_OFF: ~0x02,
  BLINK_ON: 0x01,
  BLINK_OFF: ~0x01,
  SCROLL_LEFT: 0x18,
  SCROLL_RIGHT: 0x1c,
  LEFT_TO_RIGHT: 0x02,
  RIGHT_TO_LEFT: ~0x02,
  AUTOSCROLL_ON: 0x01,
  AUTOSCROLL_OFF: ~0x01
}

function Lcd(config) {
  var i;

  if (!(this instanceof Lcd)) {
    return new Lcd(config);
  }

  EventEmitter.call(this);

  this.cols = config.cols || 16; // TODO - Never used, remove?
  this.rows = config.rows || 1;
  this.largeFont = !!config.largeFont;

  this.rs = new Gpio(config.rs, 'low'); // reg. select, output, initially low
  this.e = new Gpio(config.e, 'low'); // enable, output, initially low

  this.data = []; // data bus, db4 thru db7, outputs, initially low
  for (i = 0; i < config.data.length; i += 1) {
    this.data.push(new Gpio(config.data[i], 'low'));
  }

  this.displayControl = 0x0c; // display on, cursor off, cursor blink off
  this.displayMode = 0x06; // left to right, no shift

  this.init();
}

util.inherits(Lcd, EventEmitter);
module.exports = Lcd;

// private
Lcd.prototype.init = function () {
  Q.delay(16)                                               // wait > 15ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 1st wake up
  .delay(6)                                                 // wait > 4.1ms
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 2nd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () { this._write4Bits(0x03); }.bind(this)) // 3rd wake up
  .delay(2)                                                 // wait > 160us
  .then(function () {
    var displayFunction = 0x20;

    this._write4Bits(0x02); // 4 bit interface

    if (this.rows > 1) {
      displayFunction |= 0x08;
    }
    if (this.rows === 1 && this.largeFont) {
      displayFunction |= 0x04;
    }
    this._command(displayFunction);

    this._command(0x10);
    this._command(this.displayControl);
    this._command(this.displayMode);

    this._command(0x01); // clear display (don't call clear to avoid event)
  }.bind(this))
  .delay(3)             // wait > 1.52ms for display to clear
  .then(function () { this.emit('ready'); }.bind(this));
};

Lcd.prototype.print = function (val, cb) {
  var index,
    displayFills;

  val += '';

  // If n*80+m characters should be printed, where n>1, m<80, don't display the
  // first (n-1)*80 characters as they will be overwritten. For example, if
  // asked to print 802 characters, don't display the first 720.
  displayFills = Math.floor(val.length / 80);
  index = displayFills > 1 ? (displayFills - 1) * 80 : 0;

  this._printChar(val, index, cb);
};

// private
Lcd.prototype._printChar = function (str, index, cb) {
  tick(function () {
    if (index >= str.length) {
      if (cb) {
        return cb(null, str);
      }

      return this.emit('printed', str);
    }

    try {
      this._write(str.charCodeAt(index));
      this._printChar(str, index + 1, cb);
    } catch (e) {
      if (cb) {
        return cb(e);
      }

      return this.emit('error', e);
    }
  }.bind(this));
};

Lcd.prototype.clear = function (cb) {
  // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
  this._commandAndDelay(__COMMMANDS.CLEAR_DISPLAY, 3, 'clear', cb);
};

Lcd.prototype.home = function (cb) {
  // Wait > 1.52ms. There were issues waiting for 2ms so wait 3ms.
  this._commandAndDelay(__COMMANDS.HOME, 3, 'home', cb);
};

Lcd.prototype.setCursor = function (col, row) {
  var r = row > this.rows ? this.rows - 1 : row; //TODO: throw error instead? Seems like this could cause a silent bug.
  //we don't check for column because scrolling is a possibility. Should we check if it's in range if scrolling is off?
  this._command(__COMMANDS.SET_CURSOR | (col + __ROW_OFFSETS[r]));
};

Lcd.prototype.display = function () {
  this.displayControl |= __COMMANDS.DISPLAY_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noDisplay = function () {
  this.displayControl &= __COMMANDS.DISPLAY_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.cursor = function () {
  this.displayControl |= __COMMANDS.CURSOR_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noCursor = function () {
  this.displayControl &= __COMMANDS.CURSOR_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.blink = function () {
  this.displayControl |= __COMMANDS.BLINK_ON;
  this._command(this.displayControl);
};

Lcd.prototype.noBlink = function () {
  this.displayControl &= __COMMANDS.BLINK_OFF;
  this._command(this.displayControl);
};

Lcd.prototype.scrollDisplayLeft = function () {
  this._command(__COMMANDS.SCROLL_LEFT);
};

Lcd.prototype.scrollDisplayRight = function () {
  this._command(__COMMANDS.SCROLL_RIGHT);
};

Lcd.prototype.leftToRight = function () {
  this.displayMode |= __COMMANDS.LEFT_TO_RIGHT;
  this._command(this.displayMode);
};

Lcd.prototype.rightToLeft = function () {
  this.displayMode &= __COMMANDS.RIGHT_TO_LEFT;
  this._command(this.displayMode);
};

Lcd.prototype.autoscroll = function () {
  this.displayMode |= __COMMANDS.AUTOSCROLL_ON;
  this._command(this.displayMode);
};

Lcd.prototype.noAutoscroll = function () {
  this.displayMode &= __COMMANDS.AUTOSCROLL_OFF;
  this._command(this.displayMode);
};

Lcd.prototype.close = function () {
  var i;

  this.rs.unexport();
  this.e.unexport();

  for (i = 0; i < this.data.length; i += 1) {
    this.data[i].unexport();
  }
};

// private
Lcd.prototype._commandAndDelay = function (command, timeout, event, cb) {
  tick(function () {
    try {
      this._command(command);

      setTimeout(function () {
        if (cb) {
          return cb(null);
        }

        return this.emit(event);
      }.bind(this), timeout);
    } catch (e) {
      if (cb) {
        return cb(e);
      }

      return this.emit('error', e);
    }
  }.bind(this));
};

// private
Lcd.prototype._command = function (cmd) {
  this._send(cmd, 0);
};

// private
Lcd.prototype._write = function (val) {
  this._send(val, 1);
};

// private
Lcd.prototype._send = function (val, mode) {
  this.rs.writeSync(mode);
  this._write4Bits(val >> 4);
  this._write4Bits(val);
};

// private
Lcd.prototype._write4Bits = function (val) {
  var i;

  for (i = 0; i < this.data.length; i += 1, val = val >> 1) {
    this.data[i].writeSync(val & 1);
  }

  // enable pulse >= 300ns
  // writeSync takes ~10 microseconds to execute on the BBB, so there's
  // nothing special needed to wait 300 nanoseconds.
  this.e.writeSync(1);
  this.e.writeSync(0);
};

<|endoftext|>


<commit_before>(function() {
    var audCon = new (window.AudioContext || window.webkitAudioContext || alert("Could not find audio context"))();

    var toneCache = {};
    var createTone = function(freq, dur, callback) {
        var oss = audCon.createOscillator();
        toneCache[freq] = oss;
        oss.frequency.value = freq;
        oss.connect(audCon.destination);
        oss.start();
        setTimeout(function() {
            oss.stop();
            if (callback) callback();
        }, dur);
    }

    var baseFreq = 18000;
    var incFreq = 200;
    var binsFreq = 8;
    var transmitByte = function(byte, dur, callback) {
        if ((byte < 0) || (byte > 255)) {
            return false;
        }
        local bits = {};
        for (int i = 8; i > 0; i--) {
            var v = 2 ** i;
            if (v <= byte) {
                createTone((i - 1) * incFreq + baseFreq, dur);
                byte -= v;
            }
        }
    }
    var window.transmitByte = transmitByte;
})();
<commit_msg>This is not lua<commit_after>(function() {
    var audCon = new (window.AudioContext || window.webkitAudioContext || alert("Could not find audio context"))();

    var toneCache = {};
    var createTone = function(freq, dur, callback) {
        var oss = audCon.createOscillator();
        toneCache[freq] = oss;
        oss.frequency.value = freq;
        oss.connect(audCon.destination);
        oss.start();
        setTimeout(function() {
            oss.stop();
            if (callback) callback();
        }, dur);
    }

    var baseFreq = 18000;
    var incFreq = 200;
    var binsFreq = 8;
    var transmitByte = function(byte, dur, callback) {
        if ((byte < 0) || (byte > 255)) {
            return false;
        }
        var bits = {};
        for (int i = 8; i > 0; i--) {
            var v = 2 ** i;
            if (v <= byte) {
                createTone((i - 1) * incFreq + baseFreq, dur);
                byte -= v;
            }
        }
    }
    var window.transmitByte = transmitByte;
})();
<|endoftext|>


<commit_before>(function() {

	var express = require('express'),
		router = express.Router(),
		responseTime = require('reponse-time'),
		zmq = require('zmq'),
		socket = zmq.socket('pub');

	socket.bindSync('tcp://127.0.0.1:3000');

	router.use(responseTime());

	function publishResponse(response) {
		socket.send(response);
	}

	router.use(function(request, response, next) {

		response.on('finish', function() { publishResponse(response) });

		socket.send(request);

		next();
	});

	module.exports = router;

})();<commit_msg>After some testing, this makes more sense<commit_after>(function() {

	var express = require('express'),
		router = express.Router(),
		responseTime = require('response-time'),
		zmq = require('zmq'),
		socket = zmq.socket('pub');

	socket.bindSync('tcp://127.0.0.1:3000');

	router.use(responseTime());

	function publishResponse(response) {
		console.log('publishing response...');
		socket.send(['responses', JSON.stringify(response._headers)]);
		console.dir(response._headers);
	}

	router.use(function(request, response, next) {

		response.on('finish', function() { publishResponse(response) });

		console.log('publishing request...');
		socket.send(['requests', JSON.stringify(request.headers)]);
		console.dir(request.headers);

		next();
	});

	module.exports = router;

})();<|endoftext|>


<commit_before>const util = require("util"),

    queue = [];

/**
 * @type {typeof import("./discord")}
 */
let Discord;

//  #
//  #
//  #       ###    ## #
//  #      #   #  #  #
//  #      #   #   ##
//  #      #   #  #
//  #####   ###    ###
//                #   #
//                 ###
/**
 * A class that handles logging.
 */
class Log {
    // ##
    //  #
    //  #     ##    ###
    //  #    #  #  #  #
    //  #    #  #   ##
    // ###    ##   #
    //              ###
    /**
     * Logs a message.
     * @param {object} obj The object to log.
     * @returns {void}
     */
    static log(obj) {
        queue.push({
            type: "log",
            date: new Date(),
            obj
        });
        Log.output();
    }

    //                          #
    //
    // #  #   ###  ###   ###   ##    ###    ###
    // #  #  #  #  #  #  #  #   #    #  #  #  #
    // ####  # ##  #     #  #   #    #  #   ##
    // ####   # #  #     #  #  ###   #  #  #
    //                                      ###
    /**
     * Logs a warning.
     * @param {string} message The string to log.
     * @returns {void}
     */
    static warning(message) {
        queue.push({
            type: "warning",
            date: new Date(),
            message
        });
        Log.output();
    }

    //                                #     #
    //                                #
    //  ##   #  #   ##    ##   ###   ###   ##     ##   ###
    // # ##   ##   #     # ##  #  #   #     #    #  #  #  #
    // ##     ##   #     ##    #  #   #     #    #  #  #  #
    //  ##   #  #   ##    ##   ###     ##  ###    ##   #  #
    //                         #
    /**
     * Logs an exception.
     * @param {string} message The message describing the error.
     * @param {object} obj The object to log.
     * @returns {void}
     */
    static exception(message, obj) {
        queue.push({
            type: "exception",
            date: new Date(),
            message,
            obj
        });
        Log.output();
    }

    //              #                 #
    //              #                 #
    //  ##   #  #  ###   ###   #  #  ###
    // #  #  #  #   #    #  #  #  #   #
    // #  #  #  #   #    #  #  #  #   #
    //  ##    ###    ##  ###    ###    ##
    //                   #
    /**
     * Outputs the log queue.
     * @returns {void}
     */
    static output() {
        if (!Discord) {
            Discord = require("./discord");
        }

        if (Discord.isConnected()) {
            const logChannel = Discord.findChannelByName("fusionbot-log"),
                errorChannel = Discord.findChannelByName("fusionbot-errors");

            queue.forEach((log) => {
                const message = {
                    embed: {
                        color: log.type === "log" ? 0x80FF80 : log.type === "warning" ? 0xFFFF00 : log.type === "exception" ? 0xFF0000 : 0x16F6F8,
                        footer: {"icon_url": Discord.icon, text: "DescentBot"},
                        fields: [],
                        timestamp: log.date
                    }
                };

                if (log.message) {
                    ({message: message.embed.description} = log);
                }

                if (log.obj) {
                    const msg = util.inspect(log.obj);

                    if (msg.length > 1024) {
                        Discord.queue(msg, log.type === "exception" ? errorChannel : logChannel);
                        return;
                    }

                    message.embed.fields.push({
                        name: "Message",
                        value: msg
                    });
                }

                Discord.richQueue(message, log.type === "exception" ? errorChannel : logChannel);
            });

            queue.splice(0, queue.length);
        } else {
            console.log(queue[queue.length - 1]);
        }
    }
}

module.exports = Log;
<commit_msg>Logs with undefined types should be red.<commit_after>const util = require("util"),

    queue = [];

/**
 * @type {typeof import("./discord")}
 */
let Discord;

//  #
//  #
//  #       ###    ## #
//  #      #   #  #  #
//  #      #   #   ##
//  #      #   #  #
//  #####   ###    ###
//                #   #
//                 ###
/**
 * A class that handles logging.
 */
class Log {
    // ##
    //  #
    //  #     ##    ###
    //  #    #  #  #  #
    //  #    #  #   ##
    // ###    ##   #
    //              ###
    /**
     * Logs a message.
     * @param {object} obj The object to log.
     * @returns {void}
     */
    static log(obj) {
        queue.push({
            type: "log",
            date: new Date(),
            obj
        });
        Log.output();
    }

    //                          #
    //
    // #  #   ###  ###   ###   ##    ###    ###
    // #  #  #  #  #  #  #  #   #    #  #  #  #
    // ####  # ##  #     #  #   #    #  #   ##
    // ####   # #  #     #  #  ###   #  #  #
    //                                      ###
    /**
     * Logs a warning.
     * @param {string} message The string to log.
     * @returns {void}
     */
    static warning(message) {
        queue.push({
            type: "warning",
            date: new Date(),
            message
        });
        Log.output();
    }

    //                                #     #
    //                                #
    //  ##   #  #   ##    ##   ###   ###   ##     ##   ###
    // # ##   ##   #     # ##  #  #   #     #    #  #  #  #
    // ##     ##   #     ##    #  #   #     #    #  #  #  #
    //  ##   #  #   ##    ##   ###     ##  ###    ##   #  #
    //                         #
    /**
     * Logs an exception.
     * @param {string} message The message describing the error.
     * @param {object} obj The object to log.
     * @returns {void}
     */
    static exception(message, obj) {
        queue.push({
            type: "exception",
            date: new Date(),
            message,
            obj
        });
        Log.output();
    }

    //              #                 #
    //              #                 #
    //  ##   #  #  ###   ###   #  #  ###
    // #  #  #  #   #    #  #  #  #   #
    // #  #  #  #   #    #  #  #  #   #
    //  ##    ###    ##  ###    ###    ##
    //                   #
    /**
     * Outputs the log queue.
     * @returns {void}
     */
    static output() {
        if (!Discord) {
            Discord = require("./discord");
        }

        if (Discord.isConnected()) {
            const logChannel = Discord.findChannelByName("fusionbot-log"),
                errorChannel = Discord.findChannelByName("fusionbot-errors");

            queue.forEach((log) => {
                const message = {
                    embed: {
                        color: log.type === "log" ? 0x80FF80 : log.type === "warning" ? 0xFFFF00 : 0xFF0000,
                        footer: {"icon_url": Discord.icon, text: "DescentBot"},
                        fields: [],
                        timestamp: log.date
                    }
                };

                if (log.message) {
                    ({message: message.embed.description} = log);
                }

                if (log.obj) {
                    const msg = util.inspect(log.obj);

                    if (msg.length > 1024) {
                        Discord.queue(msg, log.type === "exception" ? errorChannel : logChannel);
                        return;
                    }

                    message.embed.fields.push({
                        name: "Message",
                        value: msg
                    });
                }

                Discord.richQueue(message, log.type === "exception" ? errorChannel : logChannel);
            });

            queue.splice(0, queue.length);
        } else {
            console.log(queue[queue.length - 1]);
        }
    }
}

module.exports = Log;
<|endoftext|>


<commit_before>(function(){
  var crypt = require('crypt'),
      utf8 = require('charenc').utf8,
      bin = require('charenc').bin,

  // The core
  md5 = function (message, options) {
    // Convert to byte array
    if (message.constructor == String)
      if (options && options.encoding === 'binary')
        message = bin.stringToBytes(message);
      else
        message = utf8.stringToBytes(message);
    else if (typeof Buffer != 'undefined' &&
        typeof Buffer.isBuffer == 'function' && Buffer.isBuffer(message))
      message = Array.prototype.slice.call(message, 0);
    else if (!Array.isArray(message))
      message = message.toString();
    // else, assume byte array already

    var m = crypt.bytesToWords(message),
        l = message.length * 8,
        a =  1732584193,
        b = -271733879,
        c = -1732584194,
        d =  271733878;

    // Swap endian
    for (var i = 0; i < m.length; i++) {
      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
    }

    // Padding
    m[l >>> 5] |= 0x80 << (l % 32);
    m[(((l + 64) >>> 9) << 4) + 14] = l;

    // Method shortcuts
    var FF = md5._ff,
        GG = md5._gg,
        HH = md5._hh,
        II = md5._ii;

    for (var i = 0; i < m.length; i += 16) {

      var aa = a,
          bb = b,
          cc = c,
          dd = d;

      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
      c = FF(c, d, a, b, m[i+10], 17, -42063);
      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
      d = FF(d, a, b, c, m[i+13], 12, -40341101);
      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
      b = FF(b, c, d, a, m[i+15], 22,  1236535329);

      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
      c = GG(c, d, a, b, m[i+11], 14,  643717713);
      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
      d = GG(d, a, b, c, m[i+10],  9,  38016083);
      c = GG(c, d, a, b, m[i+15], 14, -660478335);
      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
      b = GG(b, c, d, a, m[i+12], 20, -1926607734);

      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
      b = HH(b, c, d, a, m[i+14], 23, -35309556);
      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
      a = HH(a, b, c, d, m[i+13],  4,  681279174);
      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
      d = HH(d, a, b, c, m[i+12], 11, -421815835);
      c = HH(c, d, a, b, m[i+15], 16,  530742520);
      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);

      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
      c = II(c, d, a, b, m[i+14], 15, -1416354905);
      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
      a = II(a, b, c, d, m[i+12],  6,  1700485571);
      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
      c = II(c, d, a, b, m[i+10], 15, -1051523);
      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
      d = II(d, a, b, c, m[i+15], 10, -30611744);
      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
      b = II(b, c, d, a, m[i+13], 21,  1309151649);
      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
      d = II(d, a, b, c, m[i+11], 10, -1120210379);
      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
      b = II(b, c, d, a, m[i+ 9], 21, -343485551);

      a = (a + aa) >>> 0;
      b = (b + bb) >>> 0;
      c = (c + cc) >>> 0;
      d = (d + dd) >>> 0;
    }

    return crypt.endian([a, b, c, d]);
  };

  // Auxiliary functions
  md5._ff  = function (a, b, c, d, x, s, t) {
    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._gg  = function (a, b, c, d, x, s, t) {
    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._hh  = function (a, b, c, d, x, s, t) {
    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._ii  = function (a, b, c, d, x, s, t) {
    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  // Package private blocksize
  md5._blocksize = 16;
  md5._digestsize = 16;

  module.exports = function (message, options) {
    var digestbytes = crypt.wordsToBytes(md5(message, options));
    return options && options.asBytes ? digestbytes :
        options && options.asString ? bin.bytesToString(digestbytes) :
        crypt.bytesToHex(digestbytes);
  };

})();
<commit_msg>Removed some trailing whitespace<commit_after>(function(){
  var crypt = require('crypt'),
      utf8 = require('charenc').utf8,
      bin = require('charenc').bin,

  // The core
  md5 = function (message, options) {
    // Convert to byte array
    if (message.constructor == String)
      if (options && options.encoding === 'binary')
        message = bin.stringToBytes(message);
      else
        message = utf8.stringToBytes(message);
    else if (typeof Buffer != 'undefined' &&
        typeof Buffer.isBuffer == 'function' && Buffer.isBuffer(message))
      message = Array.prototype.slice.call(message, 0);
    else if (!Array.isArray(message))
      message = message.toString();
    // else, assume byte array already

    var m = crypt.bytesToWords(message),
        l = message.length * 8,
        a =  1732584193,
        b = -271733879,
        c = -1732584194,
        d =  271733878;

    // Swap endian
    for (var i = 0; i < m.length; i++) {
      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
    }

    // Padding
    m[l >>> 5] |= 0x80 << (l % 32);
    m[(((l + 64) >>> 9) << 4) + 14] = l;

    // Method shortcuts
    var FF = md5._ff,
        GG = md5._gg,
        HH = md5._hh,
        II = md5._ii;

    for (var i = 0; i < m.length; i += 16) {

      var aa = a,
          bb = b,
          cc = c,
          dd = d;

      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
      c = FF(c, d, a, b, m[i+10], 17, -42063);
      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
      d = FF(d, a, b, c, m[i+13], 12, -40341101);
      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
      b = FF(b, c, d, a, m[i+15], 22,  1236535329);

      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
      c = GG(c, d, a, b, m[i+11], 14,  643717713);
      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
      d = GG(d, a, b, c, m[i+10],  9,  38016083);
      c = GG(c, d, a, b, m[i+15], 14, -660478335);
      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
      b = GG(b, c, d, a, m[i+12], 20, -1926607734);

      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
      b = HH(b, c, d, a, m[i+14], 23, -35309556);
      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
      a = HH(a, b, c, d, m[i+13],  4,  681279174);
      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
      d = HH(d, a, b, c, m[i+12], 11, -421815835);
      c = HH(c, d, a, b, m[i+15], 16,  530742520);
      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);

      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
      c = II(c, d, a, b, m[i+14], 15, -1416354905);
      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
      a = II(a, b, c, d, m[i+12],  6,  1700485571);
      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
      c = II(c, d, a, b, m[i+10], 15, -1051523);
      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
      d = II(d, a, b, c, m[i+15], 10, -30611744);
      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
      b = II(b, c, d, a, m[i+13], 21,  1309151649);
      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
      d = II(d, a, b, c, m[i+11], 10, -1120210379);
      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
      b = II(b, c, d, a, m[i+ 9], 21, -343485551);

      a = (a + aa) >>> 0;
      b = (b + bb) >>> 0;
      c = (c + cc) >>> 0;
      d = (d + dd) >>> 0;
    }

    return crypt.endian([a, b, c, d]);
  };

  // Auxiliary functions
  md5._ff  = function (a, b, c, d, x, s, t) {
    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._gg  = function (a, b, c, d, x, s, t) {
    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._hh  = function (a, b, c, d, x, s, t) {
    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };
  md5._ii  = function (a, b, c, d, x, s, t) {
    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  // Package private blocksize
  md5._blocksize = 16;
  md5._digestsize = 16;

  module.exports = function (message, options) {
    var digestbytes = crypt.wordsToBytes(md5(message, options));
    return options && options.asBytes ? digestbytes :
        options && options.asString ? bin.bytesToString(digestbytes) :
        crypt.bytesToHex(digestbytes);
  };

})();
<|endoftext|>


<commit_before>class MobileDevEnvironment
{
    constructor({reload=true, hardReload=true, logbox=true, logErrors=true, group='global'}={}) {
        if (reload === true) {
            this.reload = new MDEReload({hardReload});
        }
        if (logbox === true) {
            this.logbox = new MDELogbox({reload, logErrors, group});
        }
    }
}

class MDEHelpers
{
    getDB(key, group) {
        const DBkey = `mde-${group}-${key}`;
        return localStorage[DBkey] ? JSON.parse(localStorage[DBkey]) : null;
    }

    setDB(key, val, group) {
        const DBkey = `mde-${group}-${key}`;
        return localStorage[DBkey] = JSON.stringify(val);
    }

    setupDB(keyVals, group) {
        for (let key in keyVals) {
            const DBkey = `mde-${group}-${key}`;
            localStorage[DBkey] = JSON.stringify(keyVals[key]);
        }
    }

    fetch(query) {
        return document.querySelector('#mde-'+query);
    }

    query(elem, query) {
        return elem.querySelector(query);
    }

    insert(html, elem, position = 'beforeend') {
        return elem.insertAdjacentHTML(position, html);
    }

    containsClass(elem, cls) {
        return elem.classList.contains(cls);
    }

    toggleClass(elem, cls, assert) {
        return elem.classList.toggle(cls, assert);
    }

    getType(obj) {
        const type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
        return Number.isNaN(obj) ? 'NaN': type;
    }

    toString(obj, type)  {
        switch (type) {
            case 'string':    return obj;
            case 'undefined': return 'undefined';
            case 'NaN':       return 'NaN';
            default:          return JSON.stringify(obj);
        }
    }

    touches(e) {
        return e.changedTouches;
    }

    getDragDistance(dragStart, dragEnd) {
        return {
            x: dragStart.pageX-dragEnd.pageX,
            y: dragStart.pageY-dragEnd.pageY
        }
    }

    returnInRange(num, min, max) {
        num  = num > max ? max : num;
        return num < min ? min : num;
    }

    scrollInfo(elem) {
        const {scrollTop, scrollHeight, clientHeight} = elem;
        return {
            top:        scrollTop,
            bottom:     scrollTop + clientHeight,
            height:     clientHeight,
            atTop:      scrollTop === 0,
            atBottom:   scrollHeight - scrollTop <= clientHeight + 1,
            fullHeight: scrollHeight
        }
    }

    returnTraceFromError(error) {
        // get relevant trace parts
        const bits = error.stack.split(":").slice(4,9)
        // clear redundant chars at start and end
        let first = bits[0];
        bits[0] = first.substring(first.indexOf('(')+1,first.length);
        let last = bits[bits.length-1];
        bits[bits.length-1] = last.substring(0, last.indexOf(')'));
        // compile
        const fileName = bits[2].replace(/^.*[\\\/]/, '');
        return {
            fileName: fileName.length > 0 ? fileName : 'N/A',
            filePath: bits[0]+':'+bits[1]+':'+bits[2],
            lineNumber: bits[3]
        };
    }
}

class MDEReload extends MDEHelpers
{
    constructor(options) {
        super();

        const { insert, fetch } = this;
        const { hardReload } = options;

        insert('<button id="mde-reload" class="mde"></button>', document.body);
        fetch('reload').addEventListener('click', (e) => {
            location.reload(hardReload)
        }, false);
    }
}

class MDELogbox extends MDEHelpers
{
    constructor(options) {
        super();

        this.options = options;

        const { setupDB, getDB } = this;

        setupDB({
            logboxOpen: getDB('logboxOpen', options.group ) || false,
            logboxHeight: getDB('logboxHeight', options.group) || 40
        }, options.group);

        this.buildLogboxButton();
        this.buildLogbox();

        window.console.log = (message) => {
            const trace = this.returnTraceFromError(new Error);
            this.log(message, trace);
        };

        if (options.logErrors === true) {
            window.onerror = (message, filePath, lineNumber) => {
                const fileName = filePath.replace(/^.*[\\\/]/, '');
                this.log(message, {fileName, filePath, lineNumber, isError: true});
            }
        }
    }

    buildLogboxButton() {
        const { state, insert, fetch } = this;
        insert(`<button id="mde-open-logbox" class="mde ${state}"></button>`, document.body);
        fetch('open-logbox').addEventListener('click', (e) => {
            this.open();
        }, false);
    }

    buildLogbox() {
        const { state, height, insert, fetch, drag } = this;

        insert(`

                    <button id="mde-resize-logbox" class="mde">···</button>
                    <button id="mde-close-logbox" class="mde">—</button>

`, document.body)

        this.setHeight(height);

        const closeButton  = fetch('close-logbox');
        const resizeButton = fetch('resize-logbox');

        window.addEventListener('resize', (e) => {
            this.setHeight(this.height);
        }, false);
        closeButton.addEventListener('click', (e) => {
            this.close();
        }, false);
        resizeButton.addEventListener('touchstart', (e) => {
            resizeButton.classList.add('pressed');
            this.resize(e);
            e.preventDefault();
        }, false);
        resizeButton.addEventListener('touchend', (e) => {
            resizeButton.classList.remove('pressed');
        }, false);
    }

    // constants

    get state() {
        const { options } = this;
        return this.getDB('logboxOpen', options.group);
    }

    get height() {
        const { options } = this;
        return this.getDB('logboxHeight', options.group);
    }

    get minHeight() {
        return this.fetch('resize-logbox').offsetHeight;
    }

    get maxHeight() {
        const { fetch, options } = this;
        return window.innerHeight - (options.reload ? fetch('reload').offsetHeight + 20 : 10);
    }

    // modify global

    setHeight(height) {
        const { setDB, fetch, minHeight, maxHeight, returnInRange, options } = this;
        height = returnInRange(height, minHeight, maxHeight);
        setDB('logboxHeight', height, options.group);
        fetch('logbox').style.height = height+'px';
    }

    // actions

    open() {
        const { fetch, setDB, options } = this;
        setDB('logboxOpen', true, options.group);
        fetch('open-logbox').classList = true;
        fetch('logbox').classList = true;
    }

    close() {
        const { fetch, setDB, options } = this;
        setDB('logboxOpen', false, options.group);
        fetch('open-logbox').classList = false;
        fetch('logbox').classList = false;
    }

    resize(e) {
        const { height, fetch, touches, scrollInfo, getDragDistance } = this;

        const startHeight = height;
        const startTouch  = touches(e)[0];
        const startScroll = scrollInfo(fetch('logs'));

        const onMove = (e) => {
            const distance = getDragDistance(startTouch, touches(e)[0]);
            const newHeight = startHeight+distance.y;
            this.setHeight(newHeight);

            if (startScroll.atBottom && distance.y < startScroll.top) {
                fetch('logs').scrollTop = fetch('logs').scrollHeight;
            }
        }

        const onEnd = (e) => {
            resizeButton.removeEventListener('touchmove', onMove, false);
            resizeButton.removeEventListener('touchend', onEnd, false);
        }

        const resizeButton = fetch('resize-logbox');
        resizeButton.addEventListener('touchmove', onMove, false);
        resizeButton.addEventListener('touchend', onEnd, false);
    }

    log(message, trace) {
        const { filePath, fileName, lineNumber, isError } = trace;
        const { scrollInfo, fetch, insert, getType, toString, query, containsClass, toggleClass } = this;

        const initialScroll = scrollInfo(fetch('logs'));

        const logs = fetch('logs');
        const lastLog = logs.lastChild || false;
        const lastMessage = (lastLog) ? query(lastLog, '.message').innerText : false;

        const id = 'log-'+logs.children.length;
        const type = isError ? 'error' : getType(message);
        message = toString(message, type);

        if (message !== lastMessage) {
            insert('
'
                  +    '
'
                  +        '

'
                  +        ''+fileName+':'+lineNumber+''
                  +        '

'
                  +    '
'
                  +    '

'
                  +'
', logs);

            const submitted = this.fetch(id);

            query(submitted, '.preview .message').innerText = message;
            query(submitted, '.full').innerText = message;

            query(submitted, '.preview').addEventListener('click', (e) => {
                if (!containsClass(e.target, 'trace')) {
                    const clickedLog = e.target.closest('.log');
                    toggleClass(clickedLog, 'expand');
                }
            });
        } else {
            const stackSize = parseInt(query(lastLog, '.stack').innerText) || 1;
            query(lastLog, '.stack').innerText = stackSize+1;
        }

        if (initialScroll.atBottom) {
            logs.scrollTop = logs.scrollHeight;
        }
    }
}<commit_msg>Handle trace link of unknown sourcefile<commit_after>class MobileDevEnvironment
{
    constructor({reload=true, hardReload=true, logbox=true, logErrors=true, group='global'}={}) {
        if (reload === true) {
            this.reload = new MDEReload({hardReload});
        }
        if (logbox === true) {
            this.logbox = new MDELogbox({reload, logErrors, group});
        }
    }
}

class MDEHelpers
{
    getDB(key, group) {
        const DBkey = `mde-${group}-${key}`;
        return localStorage[DBkey] ? JSON.parse(localStorage[DBkey]) : null;
    }

    setDB(key, val, group) {
        const DBkey = `mde-${group}-${key}`;
        return localStorage[DBkey] = JSON.stringify(val);
    }

    setupDB(keyVals, group) {
        for (let key in keyVals) {
            const DBkey = `mde-${group}-${key}`;
            localStorage[DBkey] = JSON.stringify(keyVals[key]);
        }
    }

    fetch(query) {
        return document.querySelector('#mde-'+query);
    }

    query(elem, query) {
        return elem.querySelector(query);
    }

    insert(html, elem, position = 'beforeend') {
        return elem.insertAdjacentHTML(position, html);
    }

    containsClass(elem, cls) {
        return elem.classList.contains(cls);
    }

    toggleClass(elem, cls, assert) {
        return elem.classList.toggle(cls, assert);
    }

    getType(obj) {
        const type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
        return Number.isNaN(obj) ? 'NaN': type;
    }

    toString(obj, type)  {
        switch (type) {
            case 'string':    return obj;
            case 'undefined': return 'undefined';
            case 'NaN':       return 'NaN';
            default:          return JSON.stringify(obj);
        }
    }

    touches(e) {
        return e.changedTouches;
    }

    getDragDistance(dragStart, dragEnd) {
        return {
            x: dragStart.pageX-dragEnd.pageX,
            y: dragStart.pageY-dragEnd.pageY
        }
    }

    returnInRange(num, min, max) {
        num  = num > max ? max : num;
        return num < min ? min : num;
    }

    scrollInfo(elem) {
        const {scrollTop, scrollHeight, clientHeight} = elem;
        return {
            top:        scrollTop,
            bottom:     scrollTop + clientHeight,
            height:     clientHeight,
            atTop:      scrollTop === 0,
            atBottom:   scrollHeight - scrollTop <= clientHeight + 1,
            fullHeight: scrollHeight
        }
    }

    returnTraceFromError(error) {
        // get relevant trace parts
        const bits = error.stack.split(":").slice(4,9)
        // clear redundant chars at start and end
        let first = bits[0];
        bits[0] = first.substring(first.indexOf('(')+1,first.length);
        let last = bits[bits.length-1];
        bits[bits.length-1] = last.substring(0, last.indexOf(')'));
        // compile
        const fileName = bits[2].replace(/^.*[\\\/]/, '');
        return {
            fileName: fileName.length > 0 ? fileName : 'N/A',
            filePath: fileName.length > 0 ? bits[0]+':'+bits[1]+':'+bits[2] : '',
            lineNumber: bits[3]
        };
    }
}

class MDEReload extends MDEHelpers
{
    constructor(options) {
        super();

        const { insert, fetch } = this;
        const { hardReload } = options;

        insert('<button id="mde-reload" class="mde"></button>', document.body);
        fetch('reload').addEventListener('click', (e) => {
            location.reload(hardReload)
        }, false);
    }
}

class MDELogbox extends MDEHelpers
{
    constructor(options) {
        super();

        this.options = options;

        const { setupDB, getDB } = this;

        setupDB({
            logboxOpen: getDB('logboxOpen', options.group ) || false,
            logboxHeight: getDB('logboxHeight', options.group) || 40
        }, options.group);

        this.buildLogboxButton();
        this.buildLogbox();

        window.console.log = (message) => {
            const trace = this.returnTraceFromError(new Error);
            this.log(message, trace);
        };

        if (options.logErrors === true) {
            window.onerror = (message, filePath, lineNumber) => {
                const fileName = filePath.replace(/^.*[\\\/]/, '');
                this.log(message, {fileName, filePath, lineNumber, isError: true});
            }
        }
    }

    buildLogboxButton() {
        const { state, insert, fetch } = this;
        insert(`<button id="mde-open-logbox" class="mde ${state}"></button>`, document.body);
        fetch('open-logbox').addEventListener('click', (e) => {
            this.open();
        }, false);
    }

    buildLogbox() {
        const { state, height, insert, fetch, drag } = this;

        insert(`

                    <button id="mde-resize-logbox" class="mde">···</button>
                    <button id="mde-close-logbox" class="mde">—</button>

`, document.body)

        this.setHeight(height);

        const closeButton  = fetch('close-logbox');
        const resizeButton = fetch('resize-logbox');

        window.addEventListener('resize', (e) => {
            this.setHeight(this.height);
        }, false);
        closeButton.addEventListener('click', (e) => {
            this.close();
        }, false);
        resizeButton.addEventListener('touchstart', (e) => {
            resizeButton.classList.add('pressed');
            this.resize(e);
            e.preventDefault();
        }, false);
        resizeButton.addEventListener('touchend', (e) => {
            resizeButton.classList.remove('pressed');
        }, false);
    }

    // constants

    get state() {
        const { options } = this;
        return this.getDB('logboxOpen', options.group);
    }

    get height() {
        const { options } = this;
        return this.getDB('logboxHeight', options.group);
    }

    get minHeight() {
        return this.fetch('resize-logbox').offsetHeight;
    }

    get maxHeight() {
        const { fetch, options } = this;
        return window.innerHeight - (options.reload ? fetch('reload').offsetHeight + 20 : 10);
    }

    // modify global

    setHeight(height) {
        const { setDB, fetch, minHeight, maxHeight, returnInRange, options } = this;
        height = returnInRange(height, minHeight, maxHeight);
        setDB('logboxHeight', height, options.group);
        fetch('logbox').style.height = height+'px';
    }

    // actions

    open() {
        const { fetch, setDB, options } = this;
        setDB('logboxOpen', true, options.group);
        fetch('open-logbox').classList = true;
        fetch('logbox').classList = true;
    }

    close() {
        const { fetch, setDB, options } = this;
        setDB('logboxOpen', false, options.group);
        fetch('open-logbox').classList = false;
        fetch('logbox').classList = false;
    }

    resize(e) {
        const { height, fetch, touches, scrollInfo, getDragDistance } = this;

        const startHeight = height;
        const startTouch  = touches(e)[0];
        const startScroll = scrollInfo(fetch('logs'));

        const onMove = (e) => {
            const distance = getDragDistance(startTouch, touches(e)[0]);
            const newHeight = startHeight+distance.y;
            this.setHeight(newHeight);

            if (startScroll.atBottom && distance.y < startScroll.top) {
                fetch('logs').scrollTop = fetch('logs').scrollHeight;
            }
        }

        const onEnd = (e) => {
            resizeButton.removeEventListener('touchmove', onMove, false);
            resizeButton.removeEventListener('touchend', onEnd, false);
        }

        const resizeButton = fetch('resize-logbox');
        resizeButton.addEventListener('touchmove', onMove, false);
        resizeButton.addEventListener('touchend', onEnd, false);
    }

    log(message, trace) {
        const { filePath, fileName, lineNumber, isError } = trace;
        const { scrollInfo, fetch, insert, getType, toString, query, containsClass, toggleClass } = this;

        const initialScroll = scrollInfo(fetch('logs'));

        const logs = fetch('logs');
        const lastLog = logs.lastChild || false;
        const lastMessage = (lastLog) ? query(lastLog, '.message').innerText : false;

        const id = 'log-'+logs.children.length;
        const type = isError ? 'error' : getType(message);
        message = toString(message, type);

        if (message !== lastMessage) {
            insert('
'
                  +    '
'
                  +        '

'
                  +        ''+fileName+':'+lineNumber+''
                  +        '

'
                  +    '
'
                  +    '

'
                  +'
', logs);

            const submitted = this.fetch(id);

            query(submitted, '.preview .message').innerText = message;
            query(submitted, '.full').innerText = message;

            query(submitted, '.preview').addEventListener('click', (e) => {
                if (!containsClass(e.target, 'trace')) {
                    const clickedLog = e.target.closest('.log');
                    toggleClass(clickedLog, 'expand');
                }
            });
        } else {
            const stackSize = parseInt(query(lastLog, '.stack').innerText) || 1;
            query(lastLog, '.stack').innerText = stackSize+1;
        }

        if (initialScroll.atBottom) {
            logs.scrollTop = logs.scrollHeight;
        }
    }
}<|endoftext|>


<commit_before>const TaskHealthStates = {
  HEALTHY: "正常",
  UNHEALTHY: "异常",
  UNKNOWN: "未知"
};

module.exports = TaskHealthStates;
<commit_msg>恢复TaskHealthStates<commit_after>const TaskHealthStates = {
  HEALTHY: "Healthy",
  UNHEALTHY: "Unhealthy",
  UNKNOWN: "Unkown"
};

module.exports = TaskHealthStates;
<|endoftext|>


<commit_before>/*
 * grunt-forceAtlas2
 *
 * This task crush and minify Force Atlas 2 code.
 */
var uglify = require('uglify-js');

// Shorteners
function minify(string) {
  return uglify.minify(string, {fromString: true}).code;
}

// Crushing function
function crush(fnString) {
  var pattern,
      i,
      l;

  var np = [
    'x',
    'y',
    'dx',
    'dy',
    'old_dx',
    'old_dy',
    'mass',
    'convergence',
    'size',
    'fixed'
  ];

  var ep = [
    'source',
    'target',
    'weight'
  ];

  // Replacing matrix accessors by incremented indexes
  for (i = 0, l = np.length; i < l; i++) {
    pattern = new RegExp('np\\(([^,]*), \'' + np[i] + '\'\\)', 'g');
    fnString = fnString.replace(
      pattern,
      (i === 0) ? '$1' : '$1 + ' + i
    );
  }

  for (i = 0, l = ep.length; i < l; i++) {
    pattern = new RegExp('ep\\(([^,]*), \'' + ep[i] + '\'\\)', 'g');
    fnString = fnString.replace(
      pattern,
      (i === 0) ? '$1' : '$1 + ' + i
    );
  }

  return fnString;
}

// Cleaning function
function clean(string) {
  return string.replace(
    /function crush\(fnString\) \{[\s\S]*sigma\.prototype\.getForceAtlas2Worker/,
    'var crush = null; sigma.prototype.getForceAtlas2Worker'
  );
}

module.exports = function(grunt) {

  // Force atlas grunt multitask
  function multitask() {

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({});

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      }).join('\n');

      // Crushing, cleaning and minifying
      src = minify(clean(crush(src)));

      // Write the destination file.
      grunt.file.write(f.dest, src);

      // Print a success message.
      grunt.log.writeln('File "' + f.dest + '" created.');
    });
  }

  // Registering the task
  grunt.registerMultiTask(
    'forceAtlas2',
    'A grunt task to crush and minify ForceAtlas2.',
    multitask
  );
};
<commit_msg>fixes build for the forceAtlas2 plugin.<commit_after>/*
 * grunt-forceAtlas2
 *
 * This task crush and minify Force Atlas 2 code.
 */
var uglify = require('uglify-js');

// Shorteners
function minify(string) {
  return uglify.minify(string, {fromString: true}).code;
}

// Crushing function
function crush(fnString) {
  var pattern,
      i,
      l;

  var np = [
    'x',
    'y',
    'dx',
    'dy',
    'old_dx',
    'old_dy',
    'mass',
    'convergence',
    'size',
    'fixed'
  ];

  var ep = [
    'source',
    'target',
    'weight'
  ];

  // Replacing matrix accessors by incremented indexes
  for (i = 0, l = np.length; i < l; i++) {
    pattern = new RegExp('np\\(([^,]*), \'' + np[i] + '\'\\)', 'g');
    fnString = fnString.replace(
      pattern,
      (i === 0) ? '$1' : '$1 + ' + i
    );
  }

  for (i = 0, l = ep.length; i < l; i++) {
    pattern = new RegExp('ep\\(([^,]*), \'' + ep[i] + '\'\\)', 'g');
    fnString = fnString.replace(
      pattern,
      (i === 0) ? '$1' : '$1 + ' + i
    );
  }

  return fnString;
}

// Cleaning function
function clean(string) {
  return string.replace(
    /function crush\(fnString\)/,
    'var crush = null; function no_crush(fnString)'
  );
}

module.exports = function(grunt) {

  // Force atlas grunt multitask
  function multitask() {

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({});

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      // Concat specified files.
      var src = f.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        // Read file source.
        return grunt.file.read(filepath);
      }).join('\n');

      // Crushing, cleaning and minifying
      src = minify(clean(crush(src)));

      // Write the destination file.
      grunt.file.write(f.dest, src);

      // Print a success message.
      grunt.log.writeln('File "' + f.dest + '" created.');
    });
  }

  // Registering the task
  grunt.registerMultiTask(
    'forceAtlas2',
    'A grunt task to crush and minify ForceAtlas2.',
    multitask
  );
};
<|endoftext|>


<commit_before>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

// This file extends and proxies the default behavior defined in vitro/webapp/web/js/menupage/browseByClassGroupsPie.js

// Saving the original graphClasses function from browseClassGroups
var graphPersonClasses = graphClasses.piechart;

// Assigning the proxy function
graphClasses.piechart = function(values, labels, uris) {
    // Clear the existing pie chart
    $('#menupage-graph').empty();

    // Create the canvas
    var r = Raphael("menupage-graph", 300, 300);

    // Setup the colors for the slices
    // colors = ['#192933', '#26404E', '#294656', '#194c68', '#487A96', '#63A8CE', '#67AED6','#758A96', '#9DB9C9' ];
    colors = ['#143D52', '#1F5C7A', '#297AA3', '#3399CC', '#5CADD6', '#85C2E0', '#ADD6EB', '#ADCBDD', '#D6EBF5', '#E9F1F5' ];
    // Reverse colors to see how it looks with larger slices in lighter hues:
    // colors = colors.reverse();

    // Now draw the pie chart
    var pie = r.g.piechart(100, 80, 70, values, {legend: labels, legendmark: "square", legendpos: "south", colors: colors});
    pie.hover(function () {
        this.sector.stop();
        this.sector.scale(1.1, 1.1, this.cx, this.cy);
        if (this.label) {
            this.label[0].stop();
            this.label[0].scale(1.5);
            this.label[1].attr({"font-weight": 800});
        }
    }, function () {
        this.sector.animate({scale: [1, 1, this.cx, this.cy]}, 500, "bounce");
        if (this.label) {
            this.label[0].animate({scale: 1}, 500, "bounce");
            this.label[1].attr({"font-weight": 400});
        }
    });
};<commit_msg>NIHVIVO-1972: Increased size of pie chart in menupage people<commit_after>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

// This file extends and proxies the default behavior defined in vitro/webapp/web/js/menupage/browseByClassGroupsPie.js

// Saving the original graphClasses function from browseClassGroups
var graphPersonClasses = graphClasses.piechart;

// Assigning the proxy function
graphClasses.piechart = function(values, labels, uris) {
    // Clear the existing pie chart
    $('#menupage-graph').empty();

    // Create the canvas
    var r = Raphael("menupage-graph", 360, 360);

    // Setup the colors for the slices
    // colors = ['#192933', '#26404E', '#294656', '#194c68', '#487A96', '#63A8CE', '#67AED6','#758A96', '#9DB9C9' ];
    colors = ['#143D52', '#1F5C7A', '#297AA3', '#3399CC', '#5CADD6', '#85C2E0', '#ADD6EB', '#ADCBDD', '#D6EBF5', '#E9F1F5' ];
    // Reverse colors to see how it looks with larger slices in lighter hues:
    // colors = colors.reverse();

    // Now draw the pie chart
    var pie = r.g.piechart(110, 120, 100, values, {legend: labels, legendmark: "square", legendpos: "south", colors: colors});
    pie.hover(function () {
        this.sector.stop();
        this.sector.scale(1.1, 1.1, this.cx, this.cy);
        if (this.label) {
            this.label[0].stop();
            this.label[0].scale(1.5);
            this.label[1].attr({"font-weight": 800});
        }
    }, function () {
        this.sector.animate({scale: [1, 1, this.cx, this.cy]}, 500, "bounce");
        if (this.label) {
            this.label[0].animate({scale: 1}, 500, "bounce");
            this.label[1].attr({"font-weight": 400});
        }
    });
};<|endoftext|>


<commit_before>
tabSignal.connect("openapi.factory.history", function(data)
{
    apihistory.one.loadLines = function(item_id, opt)
    {
        var thisObj = this;
        if(!opt.limit)
        {
            opt.limit = 30;
        }

        if(!opt.offset)
        {
            opt.offset = 0;
        }

        opt.format = 'json';

        var def = new $.Deferred();
        spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/lines/",
            type: "GET",
            contentType:'application/json',
            data: opt,
            success: function(data)
            {
                if(!thisObj.model.data.stdout)
                {
                    thisObj.model.data.stdout = {}
                    thisObj.model.data.stdout_count = 0
                    thisObj.model.data.stdout_maxline = 0
                    thisObj.model.data.stdout_minline = 999999999
                }

                thisObj.model.data.stdout_count = data.count;
                for(var i in data.results)
                {
                    var line_number = data.results[i].line_gnumber

                    if(thisObj.model.data.stdout_maxline < line_number)
                    {
                        thisObj.model.data.stdout_maxline = line_number;
                    }

                    if(thisObj.model.data.stdout_minline > line_number)
                    {
                        thisObj.model.data.stdout_minline = line_number;
                    }

                    if(!thisObj.model.data.stdout[line_number])
                    {
                        thisObj.model.data.stdout[line_number] = {id:line_number, text:data.results[i].line}
                    }
                    else {
                        thisObj.model.data.stdout[line_number].text = data.results[i].line + thisObj.model.data.stdout[line_number].text
                    }
                }

                def.resolve()

            },
            error:function(e)
            {
                console.warn(e)
                polemarch.showErrors(e)
                def.reject(e)
            }
        });

        return def.promise();
    }

    apihistory.one.scrollBottom = function()
    {
        jQuery('#history-stdout').scrollTop(9999999);
    }

    apihistory.one.loadNewLines = function(item_id, last_stdout_maxline)
    {
        var thisObj = this;

        if(last_stdout_maxline === undefined)
        {
            last_stdout_maxline = thisObj.model.data.stdout_maxline;
        }

        if(!last_stdout_maxline)
        {
            last_stdout_maxline = 0;
        }

        return $.when(this.load(item_id), this.loadLines(item_id, {after:last_stdout_maxline, limit:30})).always(function()
        {
            var addData = false;
            var history_stdout = $("#history-stdout");
            if(!history_stdout || !history_stdout.length)
            {
                return;
            }

            var needScrollDowun = $('#history-stdout').prop('scrollHeight') - $('#history-stdout').scrollTop() -  history_stdout.css('height').replace("px", "")/1 < 100

            if(last_stdout_maxline == 0)
            {
                for(var i in thisObj.model.data.stdout)
                {
                    if(thisObj.model.data.stdout[i] != undefined)
                    {
                        history_stdout.append(thisObj.getLine(item_id, i))
                        addData = true;
                    }
                }
            }
            else
            {
                for(var i = last_stdout_maxline+1; i <= thisObj.model.data.stdout_maxline; i++)
                {
                    if(thisObj.model.data.stdout[i] != undefined)
                    {
                        history_stdout.append(thisObj.getLine(item_id, i))
                        addData = true;
                    }
                }
            }

            if( addData && needScrollDowun)
            {
                // Прокручиваем в низ только если и так скрол был не сильно приподнят
                thisObj.scrollBottom()
            }

            if(thisObj.model.data.status == 'RUN' || thisObj.model.data.status == 'DELAY')
            {
                thisObj.loadNewLines_timeoutId = setTimeout(function(){
                    thisObj.loadNewLines(item_id)
                }, 5001)
            }
        }).promise()
    }

    apihistory.one.stopUpdates = function()
    {
        clearTimeout(this.model.loadNewLines_timeoutId)
        this.model.loadNewLines_timeoutId = undefined;
    }

    /**
     * Подсветка синтаксиса
     * @link https://habrahabr.ru/post/43030/
     *
     * @param {String} code
     * @returns {String}
     */
    apihistory.one.Syntax = function(code)
    {
        var comments	= [];	// Тут собираем все каменты
        var strings		= [];	// Тут собираем все строки
        var res			= [];	// Тут собираем все RegExp
        var all			= { 'C': comments, 'S': strings, 'R': res };
        var safe		= { '<': '<', '>': '>', '&': '&' };

        var ansi_up = new AnsiUp;
        ansi_up.use_classes = true;
        var html = ansi_up.ansi_to_html(code);
        return html
        // Табуляцию заменяем неразрывными пробелами
            .replace(/\t/g, '    ');
    }

    apihistory.one.getLine = function(item_id, line_id)
    {
        var line = thisObj.model.data.stdout[line_id]
        if(/^fatal:/.test(line.text))
        {
            line.fatal = 'fatal';
        }
        else
        {
            line.fatal = '';
        }

        return spajs.just.render(this.model.name+'_stdout_line', {line:line})
    }

    apihistory.one.bindStdoutUpdates = function(item_id)
    {
        var thisObj = this;
        tabSignal.once("spajs.open", function(){
            thisObj.stopUpdates()
        })

        $.when(this.loadNewLines(item_id, 0)).always(function()
        {
            var content = $('#history-stdout')
            content.scroll(function()
            {
                // End of the document reached?
                if (content.scrollTop() < 150)
                {
                    if(thisObj.stdout_minline <= 1)
                    {
                        return;
                    }

                    if(thisObj.inLoadTopData)
                    {
                        return;
                    }

                    //thisObj.lastContentScrollHeight = $('#history-stdout').prop('scrollHeight') - content.scrollTop() + 100;

                    var stdout_minline = thisObj.model.data.stdout_minline;
                    if(stdout_minline <= 1)
                    {
                        return;
                    }

                    thisObj.inLoadTopData = true;
                    $.when(thisObj.loadLines(item_id, {before:stdout_minline, limit:thisObj.model.linePerPage})).always(function()
                    {
                        var history_stdout = $("#history-stdout");
                        if(!history_stdout || !history_stdout.length)
                        {
                            return;
                        }

                        for(var i = stdout_minline-1; i > stdout_minline - thisObj.model.linePerPage; i = i -1)
                        {
                            if(thisObj.model.data.stdout[i] != undefined)
                            {
                                history_stdout.prepend(thisObj.getLine(item_id, i))
                            }
                        }

                        thisObj.inLoadTopData = false;
                        if(content.scrollTop() < 10)
                        {
                            content.scrollTop(20)
                        }
                    })
                }
            });
        });
    }

    apihistory.one.cancelTask = function(item_id)
    {
        var thisObj = this;
        return spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/cancel/",
            type: "POST",
            contentType:'application/json',
            success: function(data)
            {
                $.notify("Task canceled!", "warning");
            },
            error:function(e)
            {
                polemarch.showErrors(e.responseJSON)
            }
        })
    }

    apihistory.one.clearOutput = function(item_id)
    {
        var thisObj = this;
        return spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/clear/",
            type: "DELETE",
            contentType:'application/json',
            success: function(data)
            {
                $.notify("Output trancated", "success");
                thisObj.model.data.stdout={};
                spajs.openURL(window.location.href);
            },
            error:function(e)
            {
                polemarch.showErrors(e.responseJSON)
            }
        });
    }

    apihistory.one.renderAsPage = function ()
    {
        var def = new $.Deferred();

        var thisObj = this;
        var tpl = this.view.bulk_name + '_one'
        if (!spajs.just.isTplExists(tpl))
        {
            tpl = 'entity_one'
        }

        if (this.model.data.inventory != null)
        {
            let inventory = new apiinventory.one()
            $.when(inventory.load(this.model.data.inventory)).done(function ()
            {
                thisObj.bindStdoutUpdates(thisObj.model.data.id)
                def.resolve(spajs.just.render(tpl, {guiObj: thisObj, opt: {inventory:inventory}}))
            }).fail(function (e)
            {
                def.reject(e)
            });

            let promise = def.promise();
            promise._test = "ABC"
            return promise
        }

        return spajs.just.render(tpl, {query: "", guiObj: this, opt: {}});
    }
})
<commit_msg>reload fileds [ci skip]<commit_after>
tabSignal.connect("openapi.factory.history", function(data)
{
    apihistory.one.loadLines = function(item_id, opt)
    {
        var thisObj = this;
        if(!opt.limit)
        {
            opt.limit = 30;
        }

        if(!opt.offset)
        {
            opt.offset = 0;
        }

        opt.format = 'json';

        var def = new $.Deferred();
        spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/lines/",
            type: "GET",
            contentType:'application/json',
            data: opt,
            success: function(data)
            {
                if(!thisObj.model.data.stdout)
                {
                    thisObj.model.data.stdout = {}
                    thisObj.model.data.stdout_count = 0
                    thisObj.model.data.stdout_maxline = 0
                    thisObj.model.data.stdout_minline = 999999999
                }

                thisObj.model.data.stdout_count = data.count;
                for(var i in data.results)
                {
                    var line_number = data.results[i].line_gnumber

                    if(thisObj.model.data.stdout_maxline < line_number)
                    {
                        thisObj.model.data.stdout_maxline = line_number;
                    }

                    if(thisObj.model.data.stdout_minline > line_number)
                    {
                        thisObj.model.data.stdout_minline = line_number;
                    }

                    if(!thisObj.model.data.stdout[line_number])
                    {
                        thisObj.model.data.stdout[line_number] = {id:line_number, text:data.results[i].line}
                    }
                    else {
                        thisObj.model.data.stdout[line_number].text = data.results[i].line + thisObj.model.data.stdout[line_number].text
                    }
                }

                def.resolve()

            },
            error:function(e)
            {
                console.warn(e)
                polemarch.showErrors(e)
                def.reject(e)
            }
        });

        return def.promise();
    }

    apihistory.one.scrollBottom = function()
    {
        jQuery('#history-stdout').scrollTop(9999999);
    }

    apihistory.one.loadNewLines = function(item_id, last_stdout_maxline)
    {
        var thisObj = this;

        if(last_stdout_maxline === undefined)
        {
            last_stdout_maxline = thisObj.model.data.stdout_maxline;
        }

        if(!last_stdout_maxline)
        {
            last_stdout_maxline = 0;
        }

        return $.when(this.load(item_id), this.loadLines(item_id, {after:last_stdout_maxline, limit:30})).always(function()
        {
            var addData = false;
            var history_stdout = $("#history-stdout");
            if(!history_stdout || !history_stdout.length)
            {
                return;
            }

            var needScrollDowun = $('#history-stdout').prop('scrollHeight') - $('#history-stdout').scrollTop() -  history_stdout.css('height').replace("px", "")/1 < 100

            if(last_stdout_maxline == 0)
            {
                for(var i in thisObj.model.data.stdout)
                {
                    if(thisObj.model.data.stdout[i] != undefined)
                    {
                        history_stdout.append(thisObj.getLine(item_id, i))
                        addData = true;
                    }
                }
            }
            else
            {
                for(var i = last_stdout_maxline+1; i <= thisObj.model.data.stdout_maxline; i++)
                {
                    if(thisObj.model.data.stdout[i] != undefined)
                    {
                        history_stdout.append(thisObj.getLine(item_id, i))
                        addData = true;
                    }
                }
            }

            if( addData && needScrollDowun)
            {
                // Прокручиваем в низ только если и так скрол был не сильно приподнят
                thisObj.scrollBottom()
            }

            if(thisObj.model.data.status == 'RUN' || thisObj.model.data.status == 'DELAY')
            {
                thisObj.loadNewLines_timeoutId = setTimeout(function(){
                    thisObj.loadNewLines(item_id)
                }, 5001)
            }
        }).promise()
    }

    apihistory.one.stopUpdates = function()
    {
        clearTimeout(this.model.loadNewLines_timeoutId)
        this.model.loadNewLines_timeoutId = undefined;
    }

    /**
     * Подсветка синтаксиса
     * @link https://habrahabr.ru/post/43030/
     *
     * @param {String} code
     * @returns {String}
     */
    apihistory.one.Syntax = function(code)
    {
        var comments	= [];	// Тут собираем все каменты
        var strings		= [];	// Тут собираем все строки
        var res			= [];	// Тут собираем все RegExp
        var all			= { 'C': comments, 'S': strings, 'R': res };
        var safe		= { '<': '<', '>': '>', '&': '&' };

        var ansi_up = new AnsiUp;
        ansi_up.use_classes = true;
        var html = ansi_up.ansi_to_html(code);
        return html
        // Табуляцию заменяем неразрывными пробелами
            .replace(/\t/g, '    ');
    }

    apihistory.one.getLine = function(item_id, line_id)
    {
        var line = thisObj.model.data.stdout[line_id]
        if(/^fatal:/.test(line.text))
        {
            line.fatal = 'fatal';
        }
        else
        {
            line.fatal = '';
        }

        return spajs.just.render(this.model.name+'_stdout_line', {line:line})
    }

    apihistory.one.bindStdoutUpdates = function(item_id)
    {
        var thisObj = this;
        tabSignal.once("spajs.open", function(){
            thisObj.stopUpdates()
        })

        $.when(this.loadNewLines(item_id, 0)).always(function()
        {
            var content = $('#history-stdout')
            content.scroll(function()
            {
                // End of the document reached?
                if (content.scrollTop() < 150)
                {
                    if(thisObj.stdout_minline <= 1)
                    {
                        return;
                    }

                    if(thisObj.inLoadTopData)
                    {
                        return;
                    }

                    //thisObj.lastContentScrollHeight = $('#history-stdout').prop('scrollHeight') - content.scrollTop() + 100;

                    var stdout_minline = thisObj.model.data.stdout_minline;
                    if(stdout_minline <= 1)
                    {
                        return;
                    }

                    thisObj.inLoadTopData = true;
                    $.when(thisObj.loadLines(item_id, {before:stdout_minline, limit:thisObj.model.linePerPage})).always(function()
                    {
                        var history_stdout = $("#history-stdout");
                        if(!history_stdout || !history_stdout.length)
                        {
                            return;
                        }

                        for(var i = stdout_minline-1; i > stdout_minline - thisObj.model.linePerPage; i = i -1)
                        {
                            if(thisObj.model.data.stdout[i] != undefined)
                            {
                                history_stdout.prepend(thisObj.getLine(item_id, i))
                            }
                        }

                        thisObj.inLoadTopData = false;
                        if(content.scrollTop() < 10)
                        {
                            content.scrollTop(20)
                        }
                    })
                }
            });
        });
    }

    apihistory.one.cancelTask = function(item_id)
    {
        var thisObj = this;
        return spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/cancel/",
            type: "POST",
            contentType:'application/json',
            success: function(data)
            {
                $.notify("Task canceled!", "warning");
            },
            error:function(e)
            {
                polemarch.showErrors(e.responseJSON)
            }
        })
    }

    apihistory.one.clearOutput = function(item_id)
    {
        var thisObj = this;
        return spajs.ajax.Call({
            url: hostname + "/api/v2/history/"+item_id+"/clear/",
            type: "DELETE",
            contentType:'application/json',
            success: function(data)
            {
                $.notify("Output trancated", "success");
                thisObj.model.data.stdout={};
                spajs.openURL(window.location.href);
            },
            error:function(e)
            {
                polemarch.showErrors(e.responseJSON)
            }
        });
    }

    apihistory.one.renderAsPage = function ()
    {
        var def = new $.Deferred();

        var thisObj = this;
        var tpl = this.view.bulk_name + '_one'
        if (!spajs.just.isTplExists(tpl))
        {
            tpl = 'entity_one'
        }

        if (this.model.data.inventory != null)
        {
            let inventory = new apiinventory.one()
            $.when(inventory.load(this.model.data.inventory)).done(function ()
            {
                thisObj.bindStdoutUpdates(thisObj.model.data.id)
                def.resolve(spajs.just.render(tpl, {guiObj: thisObj, opt: {inventory:inventory}}))
            }).fail(function (e)
            {
                def.reject(e)
            });

            let promise = def.promise();
            promise._test = "ABC"
            return promise
        }

        return spajs.just.render(tpl, {query: "", guiObj: this, opt: {}});
    }

    // Переопределяет список полей которые будут показаны в списке истории
    apihistory.list.getFiledsFor_renderAsPage = function()
    {
        let fileds = []
        for(let i in this.model.fileds)
        {
            let val = this.model.fileds[i]

            if($.inArray(val.name, ['id', 'mode', 'kind', 'status']) != -1)
            {
                fileds.push(val)
            }
        }

        return fileds;
    }
})
<|endoftext|>


<commit_before>/*
 * Get Polices from AWS
 *
 * @param {object} iam
 * @param {object} params
 * @param {function} cb
 *
 */

function getPolicies(iam, params, cb){

    iam.listPolicies(params, function(err, data){

        if(err){
            cb(err, null);
            return;
        }

        var policies = [];

        for (var i = 0; i < data.Policies.length; i++){

            var policy = {
                'policyName':data.Policies[i].PolicyName,
                'policyArn': data.Policies[i].Arn,
                'createDate':data.Policies[i].CreateDate
            };

            policies.push(policy);
        }

        cb(null, policies);

    });
}

/*
 * Delete Polices from AWS
 *
 * @param {object} iam
 * @param {object} params
 * @param {function} cb
 *
 */

function deletePolicy(iam, params, cb){

    iam.deletePolicy(params, function(err, data){

        if(err){
            cb(err, null);
            return;
        }

        cb(null);

    });
}

module.exports = {
    getPolicies:getPolicies
    deletePolicy:deletePolicy
}
<commit_msg>DeletePolicy function will return data<commit_after>/*
 * Get Polices from AWS
 *
 * @param {object} iam
 * @param {object} params
 * @param {function} cb
 *
 */

function getPolicies(iam, params, cb){

    iam.listPolicies(params, function(err, data){

        if(err){
            cb(err, null);
            return;
        }

        var policies = [];

        for (var i = 0; i < data.Policies.length; i++){

            var policy = {
                'policyName':data.Policies[i].PolicyName,
                'policyArn': data.Policies[i].Arn,
                'createDate':data.Policies[i].CreateDate
            };

            policies.push(policy);
        }

        cb(null, policies);

    });
}

/*
 * Delete Polices from AWS
 *
 * @param {object} iam
 * @param {object} params
 * @param {function} cb
 *
 */

function deletePolicy(iam, params, cb){

    iam.deletePolicy(params, function(err, data){

        if(err){
            cb(err, null);
            return;
        }

        cb(null, data);

    });
}

module.exports = {
    getPolicies:getPolicies,
    deletePolicy:deletePolicy
}
<|endoftext|>


<commit_before>// ~~Dashboard:Feature~~
doaj.dashboard = {
    statusOrder : [
        "pending",
        "in progress",
        "completed",
        "update_request",
        "revisions_required",
        "on hold",
        "ready",
        "rejected",
        "accepted"
    ]
};

doaj.dashboard.init = function() {
    $(".js-group-tab").on("click", doaj.dashboard.groupTabClick);

    // trigger a click on the first one, so there is something for the user to look at
    let first = $(".js-managed-groups-tabs").find("li:first-child a");
    first.trigger("click");
}

doaj.dashboard.groupTabClick = function(event) {
    let groupId = $(event.target).attr("data-group-id");
    doaj.dashboard.loadGroupTab(groupId);
}

// ~~->GroupStats:Endpoint~~
doaj.dashboard.loadGroupTab = function(groupId) {
    $.ajax({
        type: "GET",
        contentType: "application/json",
        dataType: "jsonp",
        url: "/service/groupstatus/" + groupId,
        success: doaj.dashboard.groupLoaded,
        error: doaj.dashboard.groupLoadError
    });
}

doaj.dashboard.groupLoaded = function(data) {
    let container = $("#group-tab");
    container.html(doaj.dashboard.renderGroupInfo(data));
}

doaj.dashboard.groupLoadError = function(data) {
    alert("Unable to determine group status at this time");
}

doaj.dashboard.renderGroupInfo = function(data) {
    // ~~-> EditorGroup:Model~~
    let allEditors = [data.editor_group.editor].concat(data.editor_group.associates);

    let editorListFrag = "";
    for (let i = 0; i < allEditors.length; i++) {
        let ed = allEditors[i];
        // ~~-> ApplicationSearch:Page~~
        let appQuerySource = doaj.searchQuerySource({"term" : [
            {"admin.editor.exact" : ed},
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
        ]})
        // ~~-> UpdateRequestsSearch:Page ~~
        let urQuerySource = doaj.searchQuerySource({"term" : [
            {"admin.editor.exact" : ed},
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.application_type.exact" : "update request"}    // this is required so we only see open update requests, not finished ones
        ]})
        let appCount = 0;
        let urCount = 0;
        if (data.by_editor[ed]) {
            appCount = data.by_editor[ed].applications || 0;
            urCount = data.by_editor[ed].update_requests || 0;
        }
        editorListFrag += `

            ${ed}
            ${appCount} applications

`;
    }

    // ~~-> ApplicationSearch:Page~~
    let appUnassignedSource = doaj.searchQuerySource({"term" : [
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.has_editor.exact": "No"},
            {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
    ]})
    // ~~-> UpdateRequestsSearch:Page ~~
    let urUnassignedSource = doaj.searchQuerySource({"term" : [
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.has_editor.exact": "No"},
            {"index.application_type.exact" : "update request"}    // this is required so we only see open update requests, not finished ones
    ]})
    editorListFrag += `

        Unassigned
        ${data.unassigned.applications} applications

`;

    let appStatusProgressBar = "";

    for (let j = 0; j < doaj.dashboard.statusOrder.length; j++) {
        let status = doaj.dashboard.statusOrder[j];
        if (data.by_status.hasOwnProperty(status)) {
            if (data.by_status[status].applications > 0) {
                // ~~-> ApplicationSearch:Page~~
                let appStatusSource = doaj.searchQuerySource({
                    "term": [
                        {"admin.editor_group.exact": data.editor_group.name},
                        {"admin.application_status.exact": status},
                        {"index.application_type.exact": "new application"}    // this is required so we only see open applications, not finished ones
                    ]
                })
                appStatusProgressBar += `

                        ${status} (${data.by_status[status].applications})

`;
            }
        }
    }

    // ~~-> ApplicationSearch:Page~~
    let appGroupSource = doaj.searchQuerySource({ "term" : [
        {"admin.editor_group.exact" : data.editor_group.name},
        {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
    ]})
    // ~~-> UpdateRequestsSearch:Page ~~
    let urGroupSource = doaj.searchQuerySource({ "term" : [
        {"admin.editor_group.exact" : data.editor_group.name},
        {"index.application_type.exact" : "update request"}    // this is required so we only see open applications, not finished ones
    ]})
    let frag = `

          ${data.editor_group.name}’s ongoing applications
          ${data.total.applications} applications

By editor

              ${editorListFrag}

Applications by status

Status progress bar colour legend

Pending

In progress

Completed

Ready

            ${appStatusProgressBar}

`;
    return frag;
}
<commit_msg>avoid displaying an editor twice, and identify which user is the editor<commit_after>// ~~Dashboard:Feature~~
doaj.dashboard = {
    statusOrder : [
        "pending",
        "in progress",
        "completed",
        "update_request",
        "revisions_required",
        "on hold",
        "ready",
        "rejected",
        "accepted"
    ]
};

doaj.dashboard.init = function() {
    $(".js-group-tab").on("click", doaj.dashboard.groupTabClick);

    // trigger a click on the first one, so there is something for the user to look at
    let first = $(".js-managed-groups-tabs").find("li:first-child a");
    first.trigger("click");
}

doaj.dashboard.groupTabClick = function(event) {
    let groupId = $(event.target).attr("data-group-id");
    doaj.dashboard.loadGroupTab(groupId);
}

// ~~->GroupStats:Endpoint~~
doaj.dashboard.loadGroupTab = function(groupId) {
    $.ajax({
        type: "GET",
        contentType: "application/json",
        dataType: "jsonp",
        url: "/service/groupstatus/" + groupId,
        success: doaj.dashboard.groupLoaded,
        error: doaj.dashboard.groupLoadError
    });
}

doaj.dashboard.groupLoaded = function(data) {
    let container = $("#group-tab");
    container.html(doaj.dashboard.renderGroupInfo(data));
}

doaj.dashboard.groupLoadError = function(data) {
    alert("Unable to determine group status at this time");
}

doaj.dashboard.renderGroupInfo = function(data) {
    // ~~-> EditorGroup:Model~~

    // first remove the editor from the associates list if they are there
    let edInAssEd = data.editor_group.associates.indexOf(data.editor_group.editor)
    if (edInAssEd > -1) {
        data.editor_group.associates.splice(edInAssEd, 1);
    }

    let allEditors = [data.editor_group.editor].concat(data.editor_group.associates);

    let editorListFrag = "";
    for (let i = 0; i < allEditors.length; i++) {
        let ed = allEditors[i];
        // ~~-> ApplicationSearch:Page~~
        let appQuerySource = doaj.searchQuerySource({"term" : [
            {"admin.editor.exact" : ed},
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
        ]})
        // ~~-> UpdateRequestsSearch:Page ~~
        let urQuerySource = doaj.searchQuerySource({"term" : [
            {"admin.editor.exact" : ed},
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.application_type.exact" : "update request"}    // this is required so we only see open update requests, not finished ones
        ]})
        let appCount = 0;
        let urCount = 0;
        if (data.by_editor[ed]) {
            appCount = data.by_editor[ed].applications || 0;
            urCount = data.by_editor[ed].update_requests || 0;
        }

        let isEd = "";
        if (i === 0) {  // first one in the list is always the editor
            isEd = " (Ed.)"
        }
        editorListFrag += `

            ${ed}${isEd}
            ${appCount} applications

`;
    }

    // ~~-> ApplicationSearch:Page~~
    let appUnassignedSource = doaj.searchQuerySource({"term" : [
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.has_editor.exact": "No"},
            {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
    ]})
    // ~~-> UpdateRequestsSearch:Page ~~
    let urUnassignedSource = doaj.searchQuerySource({"term" : [
            {"admin.editor_group.exact" : data.editor_group.name},
            {"index.has_editor.exact": "No"},
            {"index.application_type.exact" : "update request"}    // this is required so we only see open update requests, not finished ones
    ]})
    editorListFrag += `

        Unassigned
        ${data.unassigned.applications} applications

`;

    let appStatusProgressBar = "";

    for (let j = 0; j < doaj.dashboard.statusOrder.length; j++) {
        let status = doaj.dashboard.statusOrder[j];
        if (data.by_status.hasOwnProperty(status)) {
            if (data.by_status[status].applications > 0) {
                // ~~-> ApplicationSearch:Page~~
                let appStatusSource = doaj.searchQuerySource({
                    "term": [
                        {"admin.editor_group.exact": data.editor_group.name},
                        {"admin.application_status.exact": status},
                        {"index.application_type.exact": "new application"}    // this is required so we only see open applications, not finished ones
                    ]
                })
                appStatusProgressBar += `

                        ${status} (${data.by_status[status].applications})

`;
            }
        }
    }

    // ~~-> ApplicationSearch:Page~~
    let appGroupSource = doaj.searchQuerySource({ "term" : [
        {"admin.editor_group.exact" : data.editor_group.name},
        {"index.application_type.exact" : "new application"}    // this is required so we only see open applications, not finished ones
    ]})
    // ~~-> UpdateRequestsSearch:Page ~~
    let urGroupSource = doaj.searchQuerySource({ "term" : [
        {"admin.editor_group.exact" : data.editor_group.name},
        {"index.application_type.exact" : "update request"}    // this is required so we only see open applications, not finished ones
    ]})
    let frag = `

          ${data.editor_group.name}’s ongoing applications
          ${data.total.applications} applications

By editor

              ${editorListFrag}

Applications by status

Status progress bar colour legend

Pending

In progress

Completed

Ready

            ${appStatusProgressBar}

`;
    return frag;
}
<|endoftext|>