<commit_before>"use strict";

var helpers = require('./helpers');

function applyStatsFns (Client) {
  /**
   * Represents the timing stat
   * @param stat {String|Array} The stat(s) to send
   * @param time {Number} The time in milliseconds to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.timing = function (stat, time, sampleRate, tags, callback) {
    this.sendAll(stat, time, 'ms', sampleRate, tags, callback);
  };

  /**
   * Represents the timing stat by recording the duration a function takes to run (in milliseconds)
   * @param func {Function} The function to run
   * @param stat {String|Array} The stat(s) to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.timer = function (func, stat, sampleRate, tags, callback) {
    var _this = this;

    return function () {
      var start = process.hrtime();
      try {
        return func.apply(null, arguments);
      } finally {
        // get duration in milliseconds
        var duration = process.hrtime(start)[1] / 1000000;

        _this.timing(
          stat,
          duration,
          sampleRate,
          tags,
          callback
        );
      }
    };
  };

  /**
   * Increments a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.increment = function (stat, value, sampleRate, tags, callback) {
    // allow use of tags without explicit value or sampleRate
    if (arguments.length < 3) {
      if (typeof value !== 'number') {
        tags = value;
        value = undefined;
      }
    }
    // we explicitly check for undefined and null (and don't do a "! value" check)
    // so that 0 values are allowed and sent through as-is
    if (value === undefined || value === null) {
      value = 1;
    }
    this.sendAll(stat, value, 'c', sampleRate, tags, callback);
  };

  /**
   * Decrements a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.decrement = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, -value || -1, 'c', sampleRate, tags, callback);
  };

  /**
   * Represents the histogram stat
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.histogram = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'h', sampleRate, tags, callback);
  };

  /**
   * Represents the distribution stat
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.distribution = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'd', sampleRate, tags, callback);
  };

  /**
   * Gauges a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.gauge = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'g', sampleRate, tags, callback);
  };

  /**
   * Counts unique values by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.unique = Client.prototype.set = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 's', sampleRate, tags, callback);
  };

  /**
   * Send a service check
   * @param name {String} The name of the service check
   * @param status {Number=} The status of the service check (0 to 3).
   * @param options
   *   @option date_happened {Date} Assign a timestamp to the event. Default is now.
   *   @option hostname {String} Assign a hostname to the check.
   *   @option message {String} Assign a message to the check.
   * @param tags {Array=} The Array of tags to add to the check. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.check = function (name, status, options, tags, callback) {
    if (this.telegraf) {
      var err = new Error('Not supported by Telegraf / InfluxDB');
      if (callback) {
        return callback(err);
      }
      else if (this.errorHandler) {
        return this.errorHandler(err);
      }

      throw err;
    }

    var check = ['_sc', this.prefix + name + this.suffix, status],
      metadata = options || {};

    if (metadata.date_happened) {
      var timestamp = helpers.formatDate(metadata.date_happened);
      if (timestamp) {
        check.push('d:' + timestamp);
      }
    }
    if (metadata.hostname) {
      check.push('h:' + metadata.hostname);
    }

    var mergedTags = this.globalTags;
    if (tags && typeof(tags) === "object") {
      mergedTags = helpers.overrideTags(mergedTags, tags, this.telegraf);
    }
    if (mergedTags.length > 0) {
      check.push('#' + mergedTags.join(','));
    }

    // message has to be the last part of a service check
    if (metadata.message) {
      check.push('m:' + metadata.message);
    }

    // allow for tags to be omitted and callback to be used in its place
    if(typeof tags === 'function' && callback === undefined) {
      callback = tags;
    }

    var message = check.join('|');
    // Service checks are unique in that message has to be the last element in
    // the stat if provided, so we can't append tags like other checks. This
    // directly calls the `_send` method to avoid appending tags, since we've
    // already added them.
    this._send(message, callback);
  };

  /**
   * Send on an event
   * @param title {String} The title of the event
   * @param text {String} The description of the event.  Optional- title is used if not given.
   * @param options
   *   @option date_happened {Date} Assign a timestamp to the event. Default is now.
   *   @option hostname {String} Assign a hostname to the event.
   *   @option aggregation_key {String} Assign an aggregation key to the event, to group it with some others.
   *   @option priority {String} Can be ‘normal’ or ‘low’. Default is 'normal'.
   *   @option source_type_name {String} Assign a source type to the event.
   *   @option alert_type {String} Can be ‘error’, ‘warning’, ‘info’ or ‘success’. Default is 'info'.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.event = function (title, text, options, tags, callback) {
    if (this.telegraf) {
      var err = new Error('Not supported by Telegraf / InfluxDB');
      if (callback) {
        return callback(err);
      }
      else if (this.errorHandler) {
        return this.errorHandler(err);
      }

      throw err;
    }

    // Convert to strings
    var message,
        msgTitle = String(title ? title : ''),
        msgText = String(text ? text : msgTitle);
    // Escape new lines (unescaping is supported by DataDog)
    msgText = msgText.replace(/\n/g, '\\n');

    // start out the message with the event-specific title and text info
    message = '_e{' + msgTitle.length + ',' + msgText.length + '}:' + msgTitle + '|' + msgText;

    // add in the event-specific options
    if (options) {
      if (options.date_happened) {
        var timestamp = helpers.formatDate(options.date_happened);
        if (timestamp) {
          message += '|d:' + timestamp;
        }
      }
      if (options.hostname) {
        message += '|h:' + options.hostname;
      }
      if (options.aggregation_key) {
        message += '|k:' + options.aggregation_key;
      }
      if (options.priority) {
        message += '|p:' + options.priority;
      }
      if (options.source_type_name) {
        message += '|s:' + options.source_type_name;
      }
      if (options.alert_type) {
        message += '|t:' + options.alert_type;
      }
    }

    // allow for tags to be omitted and callback to be used in its place
    if(typeof tags === 'function' && callback === undefined) {
      callback = tags;
    }

    this.send(message, tags, callback);
  };
}

module.exports = applyStatsFns;<commit_msg>Fix `timer` function in `lib/statsFunctions.js` to properly interpret `process.hrtime`<commit_after>"use strict";

var helpers = require('./helpers');

function applyStatsFns (Client) {
  /**
   * Represents the timing stat
   * @param stat {String|Array} The stat(s) to send
   * @param time {Number} The time in milliseconds to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.timing = function (stat, time, sampleRate, tags, callback) {
    this.sendAll(stat, time, 'ms', sampleRate, tags, callback);
  };

  /**
   * Represents the timing stat by recording the duration a function takes to run (in milliseconds)
   * @param func {Function} The function to run
   * @param stat {String|Array} The stat(s) to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.timer = function (func, stat, sampleRate, tags, callback) {
    var _this = this;

    return function () {
      var start = process.hrtime();
      try {
        return func.apply(null, arguments);
      } finally {
        // get duration in milliseconds
        var durationComponents = process.hrtime(start);
        var seconds = durationComponents[0];
        var nanoseconds = durationComponents[1];
        var duration = seconds * 1000 + nanoseconds / 10E6;

        _this.timing(
          stat,
          duration,
          sampleRate,
          tags,
          callback
        );
      }
    };
  };

  /**
   * Increments a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.increment = function (stat, value, sampleRate, tags, callback) {
    // allow use of tags without explicit value or sampleRate
    if (arguments.length < 3) {
      if (typeof value !== 'number') {
        tags = value;
        value = undefined;
      }
    }
    // we explicitly check for undefined and null (and don't do a "! value" check)
    // so that 0 values are allowed and sent through as-is
    if (value === undefined || value === null) {
      value = 1;
    }
    this.sendAll(stat, value, 'c', sampleRate, tags, callback);
  };

  /**
   * Decrements a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.decrement = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, -value || -1, 'c', sampleRate, tags, callback);
  };

  /**
   * Represents the histogram stat
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.histogram = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'h', sampleRate, tags, callback);
  };

  /**
   * Represents the distribution stat
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.distribution = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'd', sampleRate, tags, callback);
  };

  /**
   * Gauges a stat by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.gauge = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 'g', sampleRate, tags, callback);
  };

  /**
   * Counts unique values by a specified amount
   * @param stat {String|Array} The stat(s) to send
   * @param value The value to send
   * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.unique = Client.prototype.set = function (stat, value, sampleRate, tags, callback) {
    this.sendAll(stat, value, 's', sampleRate, tags, callback);
  };

  /**
   * Send a service check
   * @param name {String} The name of the service check
   * @param status {Number=} The status of the service check (0 to 3).
   * @param options
   *   @option date_happened {Date} Assign a timestamp to the event. Default is now.
   *   @option hostname {String} Assign a hostname to the check.
   *   @option message {String} Assign a message to the check.
   * @param tags {Array=} The Array of tags to add to the check. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.check = function (name, status, options, tags, callback) {
    if (this.telegraf) {
      var err = new Error('Not supported by Telegraf / InfluxDB');
      if (callback) {
        return callback(err);
      }
      else if (this.errorHandler) {
        return this.errorHandler(err);
      }

      throw err;
    }

    var check = ['_sc', this.prefix + name + this.suffix, status],
      metadata = options || {};

    if (metadata.date_happened) {
      var timestamp = helpers.formatDate(metadata.date_happened);
      if (timestamp) {
        check.push('d:' + timestamp);
      }
    }
    if (metadata.hostname) {
      check.push('h:' + metadata.hostname);
    }

    var mergedTags = this.globalTags;
    if (tags && typeof(tags) === "object") {
      mergedTags = helpers.overrideTags(mergedTags, tags, this.telegraf);
    }
    if (mergedTags.length > 0) {
      check.push('#' + mergedTags.join(','));
    }

    // message has to be the last part of a service check
    if (metadata.message) {
      check.push('m:' + metadata.message);
    }

    // allow for tags to be omitted and callback to be used in its place
    if(typeof tags === 'function' && callback === undefined) {
      callback = tags;
    }

    var message = check.join('|');
    // Service checks are unique in that message has to be the last element in
    // the stat if provided, so we can't append tags like other checks. This
    // directly calls the `_send` method to avoid appending tags, since we've
    // already added them.
    this._send(message, callback);
  };

  /**
   * Send on an event
   * @param title {String} The title of the event
   * @param text {String} The description of the event.  Optional- title is used if not given.
   * @param options
   *   @option date_happened {Date} Assign a timestamp to the event. Default is now.
   *   @option hostname {String} Assign a hostname to the event.
   *   @option aggregation_key {String} Assign an aggregation key to the event, to group it with some others.
   *   @option priority {String} Can be ‘normal’ or ‘low’. Default is 'normal'.
   *   @option source_type_name {String} Assign a source type to the event.
   *   @option alert_type {String} Can be ‘error’, ‘warning’, ‘info’ or ‘success’. Default is 'info'.
   * @param tags {Array=} The Array of tags to add to metrics. Optional.
   * @param callback {Function=} Callback when message is done being delivered. Optional.
   */
  Client.prototype.event = function (title, text, options, tags, callback) {
    if (this.telegraf) {
      var err = new Error('Not supported by Telegraf / InfluxDB');
      if (callback) {
        return callback(err);
      }
      else if (this.errorHandler) {
        return this.errorHandler(err);
      }

      throw err;
    }

    // Convert to strings
    var message,
        msgTitle = String(title ? title : ''),
        msgText = String(text ? text : msgTitle);
    // Escape new lines (unescaping is supported by DataDog)
    msgText = msgText.replace(/\n/g, '\\n');

    // start out the message with the event-specific title and text info
    message = '_e{' + msgTitle.length + ',' + msgText.length + '}:' + msgTitle + '|' + msgText;

    // add in the event-specific options
    if (options) {
      if (options.date_happened) {
        var timestamp = helpers.formatDate(options.date_happened);
        if (timestamp) {
          message += '|d:' + timestamp;
        }
      }
      if (options.hostname) {
        message += '|h:' + options.hostname;
      }
      if (options.aggregation_key) {
        message += '|k:' + options.aggregation_key;
      }
      if (options.priority) {
        message += '|p:' + options.priority;
      }
      if (options.source_type_name) {
        message += '|s:' + options.source_type_name;
      }
      if (options.alert_type) {
        message += '|t:' + options.alert_type;
      }
    }

    // allow for tags to be omitted and callback to be used in its place
    if(typeof tags === 'function' && callback === undefined) {
      callback = tags;
    }

    this.send(message, tags, callback);
  };
}

module.exports = applyStatsFns;<|endoftext|>


<commit_before>const electron = require('electron');
const {app} = electron;
const {BrowserWindow} = electron;

let win;

function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({width: 600, height: 400, autoHideMenuBar: true});

  // and load the index.html of the app.
  win.loadURL(`file://${__dirname}/index.html`);

  // Emitted when the window is closed.
  win.on('closed', () => {
    win = null;
  });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});
<commit_msg>update index<commit_after>const electron = require('electron');
const {app} = electron;
const {BrowserWindow} = electron;

let win;

function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({width: 600, height: 400, autoHideMenuBar: true});

  // and load the index.html of the app.
  win.loadURL(`file://${__dirname}/index.html`);
  // Emitted when the window is closed.
  win.on('closed', () => {
    win = null;
  });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});
<|endoftext|>


<commit_before>function ddg_spice_dns(api_result) {
    if (!api_result.response.records > 0) return;

    Spice.render({
        data              : api_result,
        //header1         : api_result.query.domain + ' (ViewDNS)',
        source_url        : 'http://www.viewdns.info/dnsrecord/?domain=' + api_result.query.domain,
        source_name       : 'ViewDNS',
        template_normal   : 'dns',
        force_big_header  : true,
        force_favicon_url : 'http://viewdns.info/favicon.ico'
    });
}
<commit_msg>remove force_big_header as it is obsolete<commit_after>function ddg_spice_dns(api_result) {
    if (!api_result.response.records > 0) return;

    Spice.render({
        data              : api_result,
        //header1         : api_result.query.domain + ' (ViewDNS)',
        source_url        : 'http://www.viewdns.info/dnsrecord/?domain=' + api_result.query.domain,
        source_name       : 'ViewDNS',
        template_normal   : 'dns',
        force_favicon_url : 'http://viewdns.info/favicon.ico'
    });
}
<|endoftext|>


<commit_before>'use strict';

var method = require('./../method');
var assign = require('lodash.assign');
var path = require('path');
var os = require('os');
var fs = require('fs');
var AdmZip = require('adm-zip');

/**
 * @memberof jobs
 * @method create
 * @description Create a new Paperspace job.
 * @param {object} params - Job creation parameters
 * @param {string} params.name - A memorable name for this job
 * @param {string} params.machineType - Job type: either 'GPU+', 'P4000', 'P5000', 'P6000', 'V100', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', or 'C10'

 * @param {string} params.container - A required reference to a container name or container link to be used for the job.
 * @param {string} params.project - The name of the project for this job.  If not provided, this is taken from the .ps_project/config.json file, or the current directory name.
 * @param {string} params.command - An optional command to run within the workspace or container.
 * @param {string} params.workspace - An optional path to a workspace to merge with the container.  If a zip file is provided that is used instead.  If no workspace is provieded the current directory is zipped up and transferred.  If the workspace is 'none', no workspace is merged and the container is run as-is.
 * @param {string} params.dataset - An optional reference to a dataset to be merged with the container.
 * @param {function} cb - Node-style error-first callback function
 * @returns {object} job - The created job JSON object
 * @example
 * paperspace.jobs.create({
 *   name: 'My Job 1',
 *   machineType: 'P6000',
 *   container: 'http://dockerhub.com/mycontainer',
 *   project: 'My Project' // Optional; if not specified the project name is taken from the current directory or the .ps_project/config.json file.
 * }, function(err, resp) {
 *   // handle error or http response
 * });
 * @example
 * $ paperspace jobs create \
 *     --name "My Job 1" \
 *     --machineType "P6000" \
 *     --container "http://dockerhub.com/mycontainer" \
 *     --project "My Project"
 * @example
 * # HTTP request:
 * https://api.paperspace.io
 * POST /jobs/createJob { "name": "My Job 1", "machineType": "P6000", "container": "http://dockerhub.com/mycontainer", "project": "My Project"}
 * x-api-key: 1ba4f98e7c0...
 * # Returns 201 on success
 * @example
 * // Example return value:
 * {
 *   "id": "j123abc",
 *   "name": "My Job 1",
 *   "machineType": "P6000",
 *   "project": "My Project",
 *   "state": "Pending",
 * }
 */

function create(params, cb) {
	var cwd = process.cwd();
	// XXX TODO test code  DO NOT CHECK IN:
	// cwd = '/home/sanfilip/sdk/streamtest';
	if (!params.project && !params.projectId) {
		// default to name of project in .ps_project/config or name of current directory
		params.project = path.basename(cwd);
		if (params.project == '/') {
			var err = { error: 'Error: cannot create project from root dir. Please create a project dir and run from there.' };
			console.log(err.error);
			return err;
		}
	}
	if (params.workspace) {
		if (params.workspace != 'none') {
			if (!fs.existsSync(params.workspace)) {
				var err = { error: 'Error: cannot find workspace file.' };
				console.log(err.error);
				return err;
			}
			// TODO check that workspace file is a zip file

			// save workspace file name as a extra parameter since we are not using multer to parse the files on the server
			params.workspaceFileName = path.basename(workspace);
		}
	}
	if (!params.workspace) {
		// no workspace provided; zip the current directory

		// don't allow zipping of the root directory
		if (cwd == '/') {
			var err = { error: 'Error: cannot zip workspace from root dir.' };
			console.log(err.error);
			return err;
		}

		// construct zip file name in tmpdir
		var zip_file = path.resolve(os.tmpdir(), path.basename(cwd) + '.zip');

		// delete prior zip file if it exists
		if (fs.existsSync(zip_file)) {
			fs.unlinkSync(zip_file);
		}

		// zip up current working directory
		var zip = new AdmZip();
    zip.addLocalFolder(cwd);
    zip.writeZip(zip_file);

		//check it does not exceed the current limit for upload using loopback storage component with s3
		if (getFilesizeInBytes(zip_file) > 10485760) {
			var err = { error: 'Error: zipped workspace ' + zip_file + ' cannot exceed 10485760 bytes.' };
			console.log(err.error);
			return err;
		}

		// save name of the workspace file for superagent to attach it
		params.workspace = zip_file;

		// save workspace file name as a extra parameter since we are not using multer to parse the files on the server
		params.workspaceFileName = path.basename(zip_file);
	} else {
		// no workspace desired
		if (params.workspace == 'none') delete params.workspace;
	}

	return method(create, params, cb);
}

function getFilesizeInBytes(filename) {
    var stats = fs.statSync(filename)
    var fileSizeInBytes = stats["size"]
    return fileSizeInBytes
}

assign(create, {
	auth: true,
	group: 'jobs',
	name: 'create',
	method: 'post',
	route: '/jobs/createJob',
	requires: {
		name: 'string',
		machineType: 'string',
		container: 'string',
	},
	file: 'workspace',
	returns: {},
});

module.exports = create;
<commit_msg>fix job create optional parameters docs<commit_after>'use strict';

var method = require('./../method');
var assign = require('lodash.assign');
var path = require('path');
var os = require('os');
var fs = require('fs');
var AdmZip = require('adm-zip');

/**
 * @memberof jobs
 * @method create
 * @description Create a new Paperspace job.
 * @param {object} params - Job creation parameters
 * @param {string} params.name - A memorable name for this job
 * @param {string} params.machineType - Job type: either 'GPU+', 'P4000', 'P5000', 'P6000', 'V100', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', or 'C10'

 * @param {string} params.container - A required reference to a container name or container link to be used for the job.
 * @param {string} [params.project] - The name of the project for this job.  If not provided, this is taken from the .ps_project/config.json file, or the current directory name.
 * @param {string} [params.command] - An optional command to run within the workspace or container.
 * @param {string} [params.workspace] - An optional path to a workspace to merge with the container.  If a zip file is provided that is used instead.  If no workspace is provieded the current directory is zipped up and transferred.  If the workspace is 'none', no workspace is merged and the container is run as-is.
 * @param {string} [params.dataset] - An optional reference to a dataset to be merged with the container.
 * @param {function} cb - Node-style error-first callback function
 * @returns {object} job - The created job JSON object
 * @example
 * paperspace.jobs.create({
 *   name: 'My Job 1',
 *   machineType: 'P6000',
 *   container: 'http://dockerhub.com/mycontainer',
 *   project: 'My Project' // Optional; if not specified the project name is taken from the current directory or the .ps_project/config.json file.
 * }, function(err, resp) {
 *   // handle error or http response
 * });
 * @example
 * $ paperspace jobs create \
 *     --name "My Job 1" \
 *     --machineType "P6000" \
 *     --container "http://dockerhub.com/mycontainer" \
 *     --project "My Project"
 * @example
 * # HTTP request:
 * https://api.paperspace.io
 * POST /jobs/createJob { "name": "My Job 1", "machineType": "P6000", "container": "http://dockerhub.com/mycontainer", "project": "My Project"}
 * x-api-key: 1ba4f98e7c0...
 * # Returns 201 on success
 * @example
 * // Example return value:
 * {
 *   "id": "j123abc",
 *   "name": "My Job 1",
 *   "machineType": "P6000",
 *   "project": "My Project",
 *   "state": "Pending",
 * }
 */

function create(params, cb) {
	var cwd = process.cwd();
	// XXX TODO test code  DO NOT CHECK IN:
	// cwd = '/home/sanfilip/sdk/streamtest';
	if (!params.project && !params.projectId) {
		// default to name of project in .ps_project/config or name of current directory
		params.project = path.basename(cwd);
		if (params.project == '/') {
			var err = { error: 'Error: cannot create project from root dir. Please create a project dir and run from there.' };
			console.log(err.error);
			return err;
		}
	}
	if (params.workspace) {
		if (params.workspace != 'none') {
			if (!fs.existsSync(params.workspace)) {
				var err = { error: 'Error: cannot find workspace file.' };
				console.log(err.error);
				return err;
			}
			// TODO check that workspace file is a zip file

			// save workspace file name as a extra parameter since we are not using multer to parse the files on the server
			params.workspaceFileName = path.basename(workspace);
		}
	}
	if (!params.workspace) {
		// no workspace provided; zip the current directory

		// don't allow zipping of the root directory
		if (cwd == '/') {
			var err = { error: 'Error: cannot zip workspace from root dir.' };
			console.log(err.error);
			return err;
		}

		// construct zip file name in tmpdir
		var zip_file = path.resolve(os.tmpdir(), path.basename(cwd) + '.zip');

		// delete prior zip file if it exists
		if (fs.existsSync(zip_file)) {
			fs.unlinkSync(zip_file);
		}

		// zip up current working directory
		var zip = new AdmZip();
    zip.addLocalFolder(cwd);
    zip.writeZip(zip_file);

		//check it does not exceed the current limit for upload using loopback storage component with s3
		if (getFilesizeInBytes(zip_file) > 10485760) {
			var err = { error: 'Error: zipped workspace ' + zip_file + ' cannot exceed 10485760 bytes.' };
			console.log(err.error);
			return err;
		}

		// save name of the workspace file for superagent to attach it
		params.workspace = zip_file;

		// save workspace file name as a extra parameter since we are not using multer to parse the files on the server
		params.workspaceFileName = path.basename(zip_file);
	} else {
		// no workspace desired
		if (params.workspace == 'none') delete params.workspace;
	}

	return method(create, params, cb);
}

function getFilesizeInBytes(filename) {
    var stats = fs.statSync(filename)
    var fileSizeInBytes = stats["size"]
    return fileSizeInBytes
}

assign(create, {
	auth: true,
	group: 'jobs',
	name: 'create',
	method: 'post',
	route: '/jobs/createJob',
	requires: {
		name: 'string',
		machineType: 'string',
		container: 'string',
	},
	file: 'workspace',
	returns: {},
});

module.exports = create;
<|endoftext|>


<commit_before>/* This file contains JavaScript inbuilt functions, their accepted types and return types */
const jsFunctions = {
  'Number': {
    'type': 'function',
    'paramTypes': ['string'],
    'returnType': 'number'
  },
  'require': {
    'type': 'function',
    'paramTypes': ['string'],
    'returnType': 'needsInference'
  },
  'parseInt': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'number'
  },
  'parseFloat': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'number'
  },
  'String': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'string'
  }
}

/* Module exports jsFunctions */
module.exports = jsFunctions
<commit_msg>add even more js functions for type inference<commit_after>/* This file contains JavaScript inbuilt functions, their accepted types and return types */
const jsFunctions = {
  'Number': {
    'type': 'function',
    'paramTypes': ['string'],
    'returnType': 'number'
  },
  'require': {
    'type': 'function',
    'paramTypes': ['string'],
    'returnType': 'needsInference'
  },
  'parseInt': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'number'
  },
  'parseFloat': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'number'
  },
  'String': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'string'
  },
  'Object': {
    'type': 'function',
    'paramTypes': ['needsInference'],
    'returnType': 'object'
  },
  'RegExp': {
    'type': 'function',
    'paramTypes': ['string'],
    'returnType': 'object'
  },
  'Date': {
    'type': 'function',
    'paramTypes': [],
    'returnType': 'string'
  },
  'isFinite': {
    'type': 'function',
    'paramTypes': ['number'],
    'returnType': 'boolean'
  },
  'isNaN': {
    'type': 'function',
    'paramTypes': ['number'],
    'returnType': 'boolean'
  }
}

/* Module exports jsFunctions */
module.exports = jsFunctions
<|endoftext|>


<commit_before>var execFile = require("child_process").execFile;
var path = require("path");

// run jsg on srcunit (a CommonJSPackage), calling cb(err, graphData).
module.exports.run = function(dir, srcunit, cb) {
  var args = [path.join(__dirname, "../node_modules/jsg/bin/jsg")];

  // add plugins from the source unit config
  if (srcunit.Config && srcunit.Config.jsg && srcunit.Config.jsg.plugins) {
    Object.keys(srcunit.Config.jsg.plugins).forEach(function(pluginName) {
      var opts = srcunit.Config.jsg.plugins[pluginName];

      // perform variable substitutions
      // TODO(sqs): document these
      var substs = {"JSG_DIR": path.join(__dirname, "../node_modules/jsg")};
      Object.keys(substs).forEach(function(varName) {
        pluginName = pluginName.replace("$(" + varName + ")", substs[varName]);
        if (pluginName == "node" && opts.coreModulesDir) {
          opts.coreModulesDir = opts.coreModulesDir.replace("$(" + varName + ")", substs[varName]);
        }
      });

      args.push("--plugin", pluginName+"="+JSON.stringify(opts));
    });
  }

  srcunit.Files.forEach(function(f) {
    args.push(path.join(dir, f));
  });

  console.error("Exec: ", args);
  execFile(process.execPath /* node */, args, {maxBuffer: 50*1024*1024}, function(err, stdout, stderr) {
    if (stderr) console.error(stderr);
    if (err) {
      cb(err, null);
      return;
    }

    console.error("Converting to srclib format...");
    var jsgData = JSON.parse(stdout);

    var graphData = convertJSGData(jsgData);

    cb(null, graphData);
  });
};

// convertJSGData converts from jsg output format to srclib output format.
function convertJSGData(data) {
  var out = {
    Defs: [],
    Refs: [],
    Docs: [],
    Propg: [], // TODO(sqs): add propg support, and check that this is the right field name
  };

  data.symbols.forEach(function(jdef) {
    var defData = convertDef(jdef);
    if (defData) {
      out.Defs.push.apply(out.Defs, defData.Defs);
      out.Refs.push.apply(out.Refs, defData.Refs);
      out.Propg.push.apply(out.Propg, defData.Propgs);
      out.Docs.push.apply(out.Docs, defData.Docs);
    }
  });

  data.refs.forEach(function(jref) {
    var ref = convertRef(jref);
    if (ref) {
      out.Refs.push(ref);
    }
  });

  return out;
}

// keyToDefPath converts from a jsg key to a srclib def path.
function keyToDefPath(key) {
  key.path = JSON.stringify(key.path).slice(1,-1); // escape string
  if (!key.module) return [key.namespace, "-", key.path].join("/");
  if (!key.path) return [key.namespace, key.module].join("/");
  return [key.namespace, key.module, "-", key.path.replace(/\./g, "/")].join("/");
}

// TODO implement
function keyToDefTreePath(key) {
  key.path = key.path.replace(/\/\//g, "/"); // hack so we don't break on paths containing "//"
  key.path = JSON.stringify(key.path).slice(1,-1); // escape string

  var namespaceComponents = key.namespace.split("/").map(function(c) { return "-" + c; });
  var ghostedNamespace = namespaceComponents.join("/");

  if (!key.module) return [ghostedNamespace, "-", key.path].join("/");
  if (!key.path) return [ghostedNamespace, key.module].join("/");
  return [ghostedNamespace, key.module, "-", key.path.replace(/\./g, "/").replace(/\/\//g, "/")].join("/");
}

// convertDef returns an object {Defs: [...], Refs: [...], Docs: [...],
// Propg: [...]} whose map value arrays should be appended to the whole output
// (convertJSGData "out").
function convertDef(jdef) {
  var out = {
    Defs: [],
    Refs: [],
    Docs: [],
    Propg: [], // TODO(sqs): add propg support, and check that this is the right field name
  };

  // unexported if it has (or is underneath) a name prefixed with "_" or that
  // contains "<i>" (the array element marker)
  var exported = jdef.exported && !strHasPrefix(jdef.key.path, "_") && !strContains(jdef.key.path, "._") && !strContains(jdef.key.path, "<i>");

  var isFunc = strHasPrefix(jdef.type, "fn(");
  var path = keyToDefPath(jdef.key);
  var treePath = keyToDefTreePath(jdef.key);

  // JavaScript def
  var def = {
    Path:      path,
    TreePath:  treePath,
    Kind:      kindOfJSGDef(jdef),
    Exported:  exported,
    Callable:  isFunc,
  };

  var defData = {
    Kind:          jsKind(jdef),
    Key:           jdef.key,
    jsgDefData: jdef.data,
    Type:          jdef.type,
    IsFunc:        isFunc,
  };
  def.Data = defData;

  if (defData.Kind == "amd-module" || defData.Kind == "commonjs-module") {
    // File
    var moduleFile = jdef.key.module;
    var moduleName = jdef.key.module.replace(/\.js$/, "");
    def.Name = moduleName;
    def.File = moduleFile;
    def.DefStart = 0;
    def.DefEnd = 0; // TODO(sqs): get filesize
    def.Exported = true
  } else {
    def.Name = lastScopePathComponent(jdef.key.path)
    def.File = jdef.file

    if (jdef.defn) {
      var defnSpan = parseSpan(jdef.defn);
      def.DefStart = defnSpan[0];
      def.DefEnd = defnSpan[1];
    }
  }

  // HACK TODO(sqs): some avals have an origin in this project but a file
  // outside of it, and they refer to defs outside of this project. but
  // because the origin is in this project, they get emitted as defs in
  // this project. fix this in jsg dump.js (most likely).
  if (strContains(def.Path, "/node_core_modules/")) {
    console.error("skipping def key path in node_core_modules:", def.Path);
    return;
  }

  if (jdef.doc) {
    out.Docs.push({
      Path:      def.Path,
      Format:    "",
      Data:      jdef.doc.trim().replace(/^\* /, ''),
    })
  }

  // TODO(sqs): implement propgs
  // for _, recv = range jdef.Recv {
  //   srcRepo, srcUnit, srcPath, err = recv.Resolve()
  //   if err == ErrSkipResolve {
  //     continue
  //   }
  //   if err != nil {
  //     return nil, nil, nil, nil, err
  //   }
  //   propgs = append(propgs, &graph.Propagate{
  //     DstPath: def.Path,
  //     SrcRepo: srcRepo,
  //     SrcUnit: srcUnit,
  //     SrcPath: srcPath,
  //   })
  // }

  out.Defs.push(def);

  return out;
}

// strHasPrefix returns whether prefix is a prefix of s.
function strHasPrefix(s, prefix) {
  return s && s.indexOf(prefix) === 0;
}

// strContains returns true if substr is within s.
function strContains(s, substr) {
  return s && s.indexOf(substr) !== -1;
}

// strHasSuffix returns true if s has suffix suffix.
function strHasSuffix(s, suffix) {
  return s && s.indexOf(suffix, s.length - suffix.length) !== -1;
}

// kindOfJSGDef returns the "generic" (cross-language) kind of jdef.
function kindOfJSGDef(jdef)  {
  var sk = jsKind(jdef);
  switch (sk) {
  case "property":
    return "field";
  case "prototype":
    return "type";
  case "commonjs-module":
  case "amd-module":
    return "module";
  case "npm-package":
    return "package";
  }
  return sk;
}

// jsKind returns the JavaScript-specific kind of jdef.
function jsKind(jdef) {
  if (jdef.data) {
    if (jdef.data.nodejs && jdef.data.nodejs.moduleExports) return "commonjs-module";
    if (jdef.data.amd && jdef.data.amd.module) return "amd-module";
  }
  if (strHasSuffix(jdef.key.path, ".prototype")) return "prototype";
  if (strHasPrefix(jdef.type, "fn(")) return "func";
  if (jdef.key.path.split(".").length > 2) return "property";
  return "var";
}

function lastScopePathComponent(scopePath) {
  var lastDot = scopePath.lastIndexOf(".");
  if (lastDot == -1) return scopePath;
  if (lastDot == scopePath.length - 1) return lastScopePathComponent(scopePath.slice(0,lastDot)) + ".";
  return scopePath.slice(lastDot+1);
}

// parseSpan parses spans like "123-456" to [123,456].
function parseSpan(span) {
  if (!span) return [0,0];
  var parts = span.split("-");
  if (parts.length != 2) throw new Error("parseSpan expects format '123-456'");
  return [parseInt(parts[0]), parseInt(parts[1])];
}

function ErrSkipResolve() {}

// convertRef converts from a jsg ref to a srclib Ref.
function convertRef(jref) {
  try {
    var resolved = resolveTarget(jref.target);
  } catch (e) {
    if (e instanceof ErrSkipResolve) return null;
    throw e;
  }

  var span = parseSpan(jref.span);

  return {
    DefRepo:     resolved.repoURL,
    DefUnitType: resolved.unitType || "",
    DefUnit:     resolved.unit,
    DefPath:     resolved.path,
    Def:            jref.def,
    File:           jref.file,
    Start:          span[0],
    End:            span[1],
  }
}

function resolveTarget(t) {
  try {
    var repo = resolveTargetRepository(t);
  } catch (e) {
    if (t.origin == "ecma5" || t.origin == "browser") throw new ErrSkipResolve;
    throw e;
  }

  return {repoURL: repo.repoURL, unit: repo.unit, path: keyToDefPath(makeTargetDefPath(t))};
}

function resolveTargetModuleRelativeToNPMPackage(t) {
  // func (t RefTarget) ModuleRelativeToNPMPackage() (string, error) {
  if (!t.npmPackage) throw new Error("not an NPM package: " + JSON.stringify(t));
  return path.relative(t.npmPackage.dir, t.module);
}

function resolveTargetRepository(t) {
  // func (t *RefTarget) Repository() (url string, unit string, vcs repo.VCS, err error) {
  if (t.npmPackage && t.npmPackage.repository) {
    return {repoURL: t.npmPackage.repository.url, unit: t.npmPackage.name, repoType: t.npmPackage.repository.type};
  }
  if (t.origin == "node" || t.nodejsCoreModule) {
    return {repoURL: "https://github.com/joyent/node.git", unit: "node", repoType: "git"};
  }
  if (!t.abstract) {
    // Current repository
    return {repoURL: "", unit: "", repoType: ""};
  }
  throw new Error("couldn't determine target repository: " + JSON.stringify(t));
}

function makeTargetDefPath(t) {
  // func (t *RefTarget) DefPath() (*DefPath, error) {
  var defPathKey = {namespace: t.namespace, module: t.module, path: t.path};
  if (t.origin == "node" || t.namespace == "commonjs") {
    defPathKey.module = defPathKey.module.replace(/\.js$/, '') + ".js";
  }
  if (t.nodejsCoreModule) {
    defPathKey.module = "lib/" + t.nodejsCoreModule + ".js"
  }
  if (t.npmPackage) {
    defPathKey.module = resolveTargetModuleRelativeToNPMPackage(t);
  }
  return defPathKey
}
<commit_msg>larger maxBuffer for jsg output<commit_after>var execFile = require("child_process").execFile;
var path = require("path");

// run jsg on srcunit (a CommonJSPackage), calling cb(err, graphData).
module.exports.run = function(dir, srcunit, cb) {
  var args = [path.join(__dirname, "../node_modules/jsg/bin/jsg")];

  // add plugins from the source unit config
  if (srcunit.Config && srcunit.Config.jsg && srcunit.Config.jsg.plugins) {
    Object.keys(srcunit.Config.jsg.plugins).forEach(function(pluginName) {
      var opts = srcunit.Config.jsg.plugins[pluginName];

      // perform variable substitutions
      // TODO(sqs): document these
      var substs = {"JSG_DIR": path.join(__dirname, "../node_modules/jsg")};
      Object.keys(substs).forEach(function(varName) {
        pluginName = pluginName.replace("$(" + varName + ")", substs[varName]);
        if (pluginName == "node" && opts.coreModulesDir) {
          opts.coreModulesDir = opts.coreModulesDir.replace("$(" + varName + ")", substs[varName]);
        }
      });

      args.push("--plugin", pluginName+"="+JSON.stringify(opts));
    });
  }

  srcunit.Files.forEach(function(f) {
    args.push(path.join(dir, f));
  });

  console.error("Exec: ", args);
  execFile(process.execPath /* node */, args, {maxBuffer: 250*1024*1024}, function(err, stdout, stderr) {
    if (stderr) console.error(stderr);
    if (err) {
      cb(err, null);
      return;
    }

    console.error("Converting to srclib format...");
    var jsgData = JSON.parse(stdout);

    var graphData = convertJSGData(jsgData);

    cb(null, graphData);
  });
};

// convertJSGData converts from jsg output format to srclib output format.
function convertJSGData(data) {
  var out = {
    Defs: [],
    Refs: [],
    Docs: [],
    Propg: [], // TODO(sqs): add propg support, and check that this is the right field name
  };

  data.symbols.forEach(function(jdef) {
    var defData = convertDef(jdef);
    if (defData) {
      out.Defs.push.apply(out.Defs, defData.Defs);
      out.Refs.push.apply(out.Refs, defData.Refs);
      out.Propg.push.apply(out.Propg, defData.Propgs);
      out.Docs.push.apply(out.Docs, defData.Docs);
    }
  });

  data.refs.forEach(function(jref) {
    var ref = convertRef(jref);
    if (ref) {
      out.Refs.push(ref);
    }
  });

  return out;
}

// keyToDefPath converts from a jsg key to a srclib def path.
function keyToDefPath(key) {
  key.path = JSON.stringify(key.path).slice(1,-1); // escape string
  if (!key.module) return [key.namespace, "-", key.path].join("/");
  if (!key.path) return [key.namespace, key.module].join("/");
  return [key.namespace, key.module, "-", key.path.replace(/\./g, "/")].join("/");
}

// TODO implement
function keyToDefTreePath(key) {
  key.path = key.path.replace(/\/\//g, "/"); // hack so we don't break on paths containing "//"
  key.path = JSON.stringify(key.path).slice(1,-1); // escape string

  var namespaceComponents = key.namespace.split("/").map(function(c) { return "-" + c; });
  var ghostedNamespace = namespaceComponents.join("/");

  if (!key.module) return [ghostedNamespace, "-", key.path].join("/");
  if (!key.path) return [ghostedNamespace, key.module].join("/");
  return [ghostedNamespace, key.module, "-", key.path.replace(/\./g, "/").replace(/\/\//g, "/")].join("/");
}

// convertDef returns an object {Defs: [...], Refs: [...], Docs: [...],
// Propg: [...]} whose map value arrays should be appended to the whole output
// (convertJSGData "out").
function convertDef(jdef) {
  var out = {
    Defs: [],
    Refs: [],
    Docs: [],
    Propg: [], // TODO(sqs): add propg support, and check that this is the right field name
  };

  // unexported if it has (or is underneath) a name prefixed with "_" or that
  // contains "<i>" (the array element marker)
  var exported = jdef.exported && !strHasPrefix(jdef.key.path, "_") && !strContains(jdef.key.path, "._") && !strContains(jdef.key.path, "<i>");

  var isFunc = strHasPrefix(jdef.type, "fn(");
  var path = keyToDefPath(jdef.key);
  var treePath = keyToDefTreePath(jdef.key);

  // JavaScript def
  var def = {
    Path:      path,
    TreePath:  treePath,
    Kind:      kindOfJSGDef(jdef),
    Exported:  exported,
    Callable:  isFunc,
  };

  var defData = {
    Kind:          jsKind(jdef),
    Key:           jdef.key,
    jsgDefData: jdef.data,
    Type:          jdef.type,
    IsFunc:        isFunc,
  };
  def.Data = defData;

  if (defData.Kind == "amd-module" || defData.Kind == "commonjs-module") {
    // File
    var moduleFile = jdef.key.module;
    var moduleName = jdef.key.module.replace(/\.js$/, "");
    def.Name = moduleName;
    def.File = moduleFile;
    def.DefStart = 0;
    def.DefEnd = 0; // TODO(sqs): get filesize
    def.Exported = true
  } else {
    def.Name = lastScopePathComponent(jdef.key.path)
    def.File = jdef.file

    if (jdef.defn) {
      var defnSpan = parseSpan(jdef.defn);
      def.DefStart = defnSpan[0];
      def.DefEnd = defnSpan[1];
    }
  }

  // HACK TODO(sqs): some avals have an origin in this project but a file
  // outside of it, and they refer to defs outside of this project. but
  // because the origin is in this project, they get emitted as defs in
  // this project. fix this in jsg dump.js (most likely).
  if (strContains(def.Path, "/node_core_modules/")) {
    console.error("skipping def key path in node_core_modules:", def.Path);
    return;
  }

  if (jdef.doc) {
    out.Docs.push({
      Path:      def.Path,
      Format:    "",
      Data:      jdef.doc.trim().replace(/^\* /, ''),
    })
  }

  // TODO(sqs): implement propgs
  // for _, recv = range jdef.Recv {
  //   srcRepo, srcUnit, srcPath, err = recv.Resolve()
  //   if err == ErrSkipResolve {
  //     continue
  //   }
  //   if err != nil {
  //     return nil, nil, nil, nil, err
  //   }
  //   propgs = append(propgs, &graph.Propagate{
  //     DstPath: def.Path,
  //     SrcRepo: srcRepo,
  //     SrcUnit: srcUnit,
  //     SrcPath: srcPath,
  //   })
  // }

  out.Defs.push(def);

  return out;
}

// strHasPrefix returns whether prefix is a prefix of s.
function strHasPrefix(s, prefix) {
  return s && s.indexOf(prefix) === 0;
}

// strContains returns true if substr is within s.
function strContains(s, substr) {
  return s && s.indexOf(substr) !== -1;
}

// strHasSuffix returns true if s has suffix suffix.
function strHasSuffix(s, suffix) {
  return s && s.indexOf(suffix, s.length - suffix.length) !== -1;
}

// kindOfJSGDef returns the "generic" (cross-language) kind of jdef.
function kindOfJSGDef(jdef)  {
  var sk = jsKind(jdef);
  switch (sk) {
  case "property":
    return "field";
  case "prototype":
    return "type";
  case "commonjs-module":
  case "amd-module":
    return "module";
  case "npm-package":
    return "package";
  }
  return sk;
}

// jsKind returns the JavaScript-specific kind of jdef.
function jsKind(jdef) {
  if (jdef.data) {
    if (jdef.data.nodejs && jdef.data.nodejs.moduleExports) return "commonjs-module";
    if (jdef.data.amd && jdef.data.amd.module) return "amd-module";
  }
  if (strHasSuffix(jdef.key.path, ".prototype")) return "prototype";
  if (strHasPrefix(jdef.type, "fn(")) return "func";
  if (jdef.key.path.split(".").length > 2) return "property";
  return "var";
}

function lastScopePathComponent(scopePath) {
  var lastDot = scopePath.lastIndexOf(".");
  if (lastDot == -1) return scopePath;
  if (lastDot == scopePath.length - 1) return lastScopePathComponent(scopePath.slice(0,lastDot)) + ".";
  return scopePath.slice(lastDot+1);
}

// parseSpan parses spans like "123-456" to [123,456].
function parseSpan(span) {
  if (!span) return [0,0];
  var parts = span.split("-");
  if (parts.length != 2) throw new Error("parseSpan expects format '123-456'");
  return [parseInt(parts[0]), parseInt(parts[1])];
}

function ErrSkipResolve() {}

// convertRef converts from a jsg ref to a srclib Ref.
function convertRef(jref) {
  try {
    var resolved = resolveTarget(jref.target);
  } catch (e) {
    if (e instanceof ErrSkipResolve) return null;
    throw e;
  }

  var span = parseSpan(jref.span);

  return {
    DefRepo:     resolved.repoURL,
    DefUnitType: resolved.unitType || "",
    DefUnit:     resolved.unit,
    DefPath:     resolved.path,
    Def:            jref.def,
    File:           jref.file,
    Start:          span[0],
    End:            span[1],
  }
}

function resolveTarget(t) {
  try {
    var repo = resolveTargetRepository(t);
  } catch (e) {
    if (t.origin == "ecma5" || t.origin == "browser") throw new ErrSkipResolve;
    throw e;
  }

  return {repoURL: repo.repoURL, unit: repo.unit, path: keyToDefPath(makeTargetDefPath(t))};
}

function resolveTargetModuleRelativeToNPMPackage(t) {
  // func (t RefTarget) ModuleRelativeToNPMPackage() (string, error) {
  if (!t.npmPackage) throw new Error("not an NPM package: " + JSON.stringify(t));
  return path.relative(t.npmPackage.dir, t.module);
}

function resolveTargetRepository(t) {
  // func (t *RefTarget) Repository() (url string, unit string, vcs repo.VCS, err error) {
  if (t.npmPackage && t.npmPackage.repository) {
    return {repoURL: t.npmPackage.repository.url, unit: t.npmPackage.name, repoType: t.npmPackage.repository.type};
  }
  if (t.origin == "node" || t.nodejsCoreModule) {
    return {repoURL: "https://github.com/joyent/node.git", unit: "node", repoType: "git"};
  }
  if (!t.abstract) {
    // Current repository
    return {repoURL: "", unit: "", repoType: ""};
  }
  throw new Error("couldn't determine target repository: " + JSON.stringify(t));
}

function makeTargetDefPath(t) {
  // func (t *RefTarget) DefPath() (*DefPath, error) {
  var defPathKey = {namespace: t.namespace, module: t.module, path: t.path};
  if (t.origin == "node" || t.namespace == "commonjs") {
    defPathKey.module = defPathKey.module.replace(/\.js$/, '') + ".js";
  }
  if (t.nodejsCoreModule) {
    defPathKey.module = "lib/" + t.nodejsCoreModule + ".js"
  }
  if (t.npmPackage) {
    defPathKey.module = resolveTargetModuleRelativeToNPMPackage(t);
  }
  return defPathKey
}
<|endoftext|>


<commit_before>import {Box, Flex} from '@chakra-ui/core'
import dynamic from 'next/dynamic'
import React from 'react'

import Sidebar from '../components/sidebar'
import useRouteChanging from '../hooks/use-route-changing'
import withAuth from '../with-auth'
import withRedux from '../with-redux'

// Cannot be rendered server side
const LeafletContext = dynamic(() => import('../components/map/context'), {
  ssr: false
})
const Map = dynamic(() => import('../components/map'), {ssr: false})

// Created to prevent prop drilling `setMapChildren`
export const MapChildrenContext = React.createContext(() => {})

/**
 * Components are rendered this way so that the map does not get unmounted
 * and remounted on each page change. There is probably a better way to do this
 * but I have not figured out a better solution yet.
 */
export default withAuth(
  withRedux(function MapLayout(p) {
    const [routeChanging] = useRouteChanging()
    const [mapChildren, setMapChildren] = React.useState()
    const [leafletContext, setLeafletContext] = React.useState()

    return (
      <Flex pointerEvents={routeChanging ? 'none' : 'inherit'}>
        <style jsx global>{`
          body {
            height: 100vh;
            overflow: hidden;
            width: 100vw;
          }
        `}</style>
        <Sidebar />
        <Box
          borderRight='1px solid #ddd'
          bg='#fff'
          opacity={routeChanging ? 0.4 : 1}
          minWidth='321px'
        >
          <LeafletContext value={leafletContext}>
            <MapChildrenContext.Provider value={setMapChildren}>
              {p.children}
            </MapChildrenContext.Provider>
          </LeafletContext>
        </Box>
        <Box flexGrow='1' opacity={routeChanging ? 0.4 : 1} position='relative'>
          <Map setLeafletContext={setLeafletContext}>{mapChildren}</Map>
        </Box>
      </Flex>
    )
  })
)
<commit_msg>Ensure map is loaded before rendering main content<commit_after>import {Box, Flex} from '@chakra-ui/core'
import dynamic from 'next/dynamic'
import React from 'react'

import FullSpinner from 'lib/components/full-spinner'
import Sidebar from 'lib/components/sidebar'
import useRouteChanging from 'lib/hooks/use-route-changing'
import withAuth from 'lib/with-auth'
import withRedux from 'lib/with-redux'

// Cannot be rendered server side
const LeafletContext = dynamic(() => import('lib/components/map/context'), {
  ssr: false
})
const Map = dynamic(() => import('lib/components/map'), {ssr: false})

// Created to prevent prop drilling `setMapChildren`
export const MapChildrenContext = React.createContext(() => {})

/**
 * Components are rendered this way so that the map does not get unmounted
 * and remounted on each page change. There is probably a better way to do this
 * but I have not figured out a better solution yet.
 */
export default withAuth(
  withRedux(function MapLayout(p) {
    const [routeChanging] = useRouteChanging()
    const [mapChildren, setMapChildren] = React.useState()
    const [leafletContext, setLeafletContext] = React.useState(null)

    return (
      <Flex pointerEvents={routeChanging ? 'none' : 'inherit'}>
        <style jsx global>{`
          body {
            height: 100vh;
            overflow: hidden;
            width: 100vw;
          }
        `}</style>
        <Sidebar />
        <Box
          borderRight='1px solid #ddd'
          bg='#fff'
          opacity={routeChanging ? 0.4 : 1}
          minWidth='321px'
        >
          {leafletContext ? (
            <LeafletContext value={leafletContext}>
              <MapChildrenContext.Provider value={setMapChildren}>
                {p.children}
              </MapChildrenContext.Provider>
            </LeafletContext>
          ) : (
            <FullSpinner />
          )}
        </Box>
        <Box flexGrow='1' opacity={routeChanging ? 0.4 : 1} position='relative'>
          <Map setLeafletContext={setLeafletContext}>{mapChildren}</Map>
        </Box>
      </Flex>
    )
  })
)
<|endoftext|>


<commit_before>var through = require('through3')
  , LF = '\n'.charCodeAt(0);

/**
 *  Reads stream buffers and writes arrays of lines.
 *
 *  Designed to be piped to another transform stream that
 *  operates on the array of lines.
 *
 *  ## Options
 *
 *  @param encoding The encoding to use when converting buffers to strings.
 */
function LineStream(options) {
  options = options || {};
  this.encoding = options.encoding || 'utf8';
  this.eol = /\r?\n/;
}

/**
 *  Transform function.
 */
function transform(chunk, encoding, cb) {
  var str, lines, i = chunk.length - 1, b;

  if(this.buffer && this.buffer.length) {
    chunk = Buffer.concat(
      [this.buffer, chunk], this.buffer.length + chunk.length);
  }

  // end with line feed, safe to split the lot
  if(chunk[chunk.length - 1] === LF) {
    str = chunk.toString(this.encoding);
  }else{
    // reverse search for line feed
    while((b = chunk[i]) !== undefined) {
      if(b === LF) {
        // get what we can split now
        str = chunk.toString(this.encoding, 0, i);
        // stash the remainder for the next transform or flush
        this.buffer = chunk.slice(i);
        break;
      }
      i--;
    }
  }

  // no newline found, possibly very long line
  if(!str) {
    this.buffer = !this.buffer
      ? chunk
      : Buffer.concat([this.buffer, chunk], this.buffer.length + chunk.length);
    return cb();
  }

  lines = str.split(this.eol);
  this.push(lines);
  this.emit('lines', lines);
  cb();
}

function flush(cb) {
  var lines;
  // unterminated last line, need to flush it
  if(this.buffer) {
    lines = [this.buffer.toString(this.encoding)];
    this.push(lines);
    this.emit('lines', lines);
  }
  this.buffer = null;
  cb();
}

module.exports = through.transform(transform, flush, {ctor: LineStream});
<commit_msg>Rename constructor.<commit_after>var through = require('through3')
  , LF = '\n'.charCodeAt(0);

/**
 *  Reads stream buffers and writes arrays of lines.
 *
 *  Designed to be piped to another transform stream that
 *  operates on the array of lines.
 *
 *  ## Options
 *
 *  @param encoding The encoding to use when converting buffers to strings.
 */
function Line(options) {
  options = options || {};
  this.encoding = options.encoding || 'utf8';
  this.eol = /\r?\n/;
}

/**
 *  Transform function.
 */
function transform(chunk, encoding, cb) {
  var str, lines, i = chunk.length - 1, b;

  if(this.buffer && this.buffer.length) {
    chunk = Buffer.concat(
      [this.buffer, chunk], this.buffer.length + chunk.length);
  }

  // end with line feed, safe to split the lot
  if(chunk[chunk.length - 1] === LF) {
    str = chunk.toString(this.encoding);
  }else{
    // reverse search for line feed
    while((b = chunk[i]) !== undefined) {
      if(b === LF) {
        // get what we can split now
        str = chunk.toString(this.encoding, 0, i);
        // stash the remainder for the next transform or flush
        this.buffer = chunk.slice(i);
        break;
      }
      i--;
    }
  }

  // no newline found, possibly very long line
  if(!str) {
    this.buffer = !this.buffer
      ? chunk
      : Buffer.concat([this.buffer, chunk], this.buffer.length + chunk.length);
    return cb();
  }

  lines = str.split(this.eol);
  this.push(lines);
  this.emit('lines', lines);
  cb();
}

function flush(cb) {
  var lines;
  // unterminated last line, need to flush it
  if(this.buffer) {
    lines = [this.buffer.toString(this.encoding)];
    this.push(lines);
    this.emit('lines', lines);
  }
  this.buffer = null;
  cb();
}

module.exports = through.transform(transform, flush, {ctor: Line});
<|endoftext|>


<commit_before>'use strict';

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

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

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

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _baseStyles = require('./baseStyles');

var _baseStyles2 = _interopRequireDefault(_baseStyles);

var _BurgerIcon = require('./BurgerIcon');

var _BurgerIcon2 = _interopRequireDefault(_BurgerIcon);

var _CrossIcon = require('./CrossIcon');

var _CrossIcon2 = _interopRequireDefault(_CrossIcon);

exports['default'] = function (styles) {
  var Menu = (function (_Component) {
    _inherits(Menu, _Component);

    function Menu(props) {
      _classCallCheck(this, Menu);

      _get(Object.getPrototypeOf(Menu.prototype), 'constructor', this).call(this, props);
      this.state = {
        isOpen: false
      };
    }

    _createClass(Menu, [{
      key: 'toggleMenu',
      value: function toggleMenu() {
        var _this = this;

        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
        var isOpen = options.isOpen;
        var noStateChange = options.noStateChange;

        var newState = {
          isOpen: typeof isOpen !== 'undefined' ? isOpen : !this.state.isOpen
        };

        this.applyWrapperStyles();

        this.setState(newState, function () {
          !noStateChange && _this.props.onStateChange(newState);

          // For accessibility reasons, ensures that when we toggle open,
          // we focus the first menu item if one exists.
          if (newState.isOpen) {
            var firstItem = document.querySelector('.bm-item');
            if (firstItem) {
              firstItem.focus();
            }
          } else {
            document.activeElement.blur();
          }

          // Timeout ensures wrappers are cleared after animation finishes.
          _this.timeoutId && clearTimeout(_this.timeoutId);
          _this.timeoutId = setTimeout(function () {
            _this.timeoutId = null;
            if (!newState.isOpen) {
              _this.applyWrapperStyles(false);
            }
          }, 500);
        });
      }

      // Applies component-specific styles to external wrapper elements.
    }, {
      key: 'applyWrapperStyles',
      value: function applyWrapperStyles() {
        var set = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];

        if (this.props.bodyClassName) {
          var body = document.querySelector('body');
          body.classList[set ? 'add' : 'remove'](this.props.bodyClassName);
        }

        if (styles.pageWrap && this.props.pageWrapId) {
          this.handleExternalWrapper(this.props.pageWrapId, styles.pageWrap, set);
        }

        if (styles.outerContainer && this.props.outerContainerId) {
          this.handleExternalWrapper(this.props.outerContainerId, styles.outerContainer, set);
        }
      }

      // Sets or unsets styles on DOM elements outside the menu component.
      // This is necessary for correct page interaction with some of the menus.
      // Throws and returns if the required external elements don't exist,
      // which means any external page animations won't be applied.
    }, {
      key: 'handleExternalWrapper',
      value: function handleExternalWrapper(id, wrapperStyles, set) {
        var html = document.querySelector('html');
        var body = document.querySelector('body');
        var wrapper = document.getElementById(id);

        if (!wrapper) {
          console.error("Element with ID '" + id + "' not found");
          return;
        }

        var builtStyles = this.getStyle(wrapperStyles);

        for (var prop in builtStyles) {
          if (builtStyles.hasOwnProperty(prop)) {
            wrapper.style[prop] = set ? builtStyles[prop] : '';
          }
        }

        // Prevent any horizontal scroll.
        [html, body].forEach(function (element) {
          element.style['overflow-x'] = set ? 'hidden' : '';
        });
      }

      // Builds styles incrementally for a given element.
    }, {
      key: 'getStyles',
      value: function getStyles(el, index, inline) {
        var propName = 'bm' + el.replace(el.charAt(0), el.charAt(0).toUpperCase());

        // Set base styles.
        var output = _baseStyles2['default'][el] ? this.getStyle(_baseStyles2['default'][el]) : {};

        // Add animation-specific styles.
        if (styles[el]) {
          output = _extends({}, output, this.getStyle(styles[el], index + 1));
        }

        // Add custom styles.
        if (this.props.styles[propName]) {
          output = _extends({}, output, this.props.styles[propName]);
        }

        // Add element inline styles.
        if (inline) {
          output = _extends({}, output, inline);
        }

        return output;
      }
    }, {
      key: 'getStyle',
      value: function getStyle(style, index) {
        var width = this.props.width;

        var formattedWidth = typeof width !== 'string' ? width + 'px' : width;
        return style(this.state.isOpen, formattedWidth, this.props.right, index);
      }
    }, {
      key: 'listenForClose',
      value: function listenForClose(e) {
        e = e || window.event;

        if (this.state.isOpen && (e.key === 'Escape' || e.keyCode === 27)) {
          this.toggleMenu();
        }
      }
    }, {
      key: 'shouldDisableOverlayClick',
      value: function shouldDisableOverlayClick() {
        if (typeof this.props.disableOverlayClick === 'function') {
          return this.props.disableOverlayClick();
        } else {
          return this.props.disableOverlayClick;
        }
      }
    }, {
      key: 'componentWillMount',
      value: function componentWillMount() {
        if (!styles) {
          throw new Error('No styles supplied');
        }
      }
    }, {
      key: 'componentDidMount',
      value: function componentDidMount() {
        // Bind ESC key handler (unless disabled or custom function supplied).
        if (this.props.customOnKeyDown) {
          window.onkeydown = this.props.customOnKeyDown;
        } else if (!this.props.disableCloseOnEsc) {
          window.onkeydown = this.listenForClose.bind(this);
        }

        // Allow initial open state to be set by props.
        if (this.props.isOpen) {
          this.toggleMenu({ isOpen: true, noStateChange: true });
        }
      }
    }, {
      key: 'componentWillUnmount',
      value: function componentWillUnmount() {
        window.onkeydown = null;

        this.applyWrapperStyles(false);
      }
    }, {
      key: 'componentDidUpdate',
      value: function componentDidUpdate() {
        var _this2 = this;

        if (styles.svg) {
          (function () {
            var morphShape = _reactDom2['default'].findDOMNode(_this2, 'bm-morph-shape');
            var path = styles.svg.lib(morphShape).select('path');

            if (_this2.state.isOpen) {
              // Animate SVG path.
              styles.svg.animate(path);
            } else {
              // Reset path (timeout ensures animation happens off screen).
              setTimeout(function () {
                path.attr('d', styles.svg.pathInitial);
              }, 300);
            }
          })();
        }
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        if (typeof nextProps.isOpen !== 'undefined' && nextProps.isOpen !== this.state.isOpen) {
          this.toggleMenu();
        }
      }
    }, {
      key: 'render',
      value: function render() {
        var _this3 = this;

        return _react2['default'].createElement(
          'div',
          null,
          !this.props.noOverlay && _react2['default'].createElement('div', {
            className: ('bm-overlay ' + this.props.overlayClassName).trim(),
            onClick: function () {
              return !_this3.shouldDisableOverlayClick() && _this3.toggleMenu();
            },
            style: this.getStyles('overlay')
          }),
          _react2['default'].createElement(
            'div',
            {
              id: this.props.id,
              className: ('bm-menu-wrap ' + this.props.className).trim(),
              style: this.getStyles('menuWrap')
            },
            styles.svg && _react2['default'].createElement(
              'div',
              {
                className: ('bm-morph-shape ' + this.props.morphShapeClassName).trim(),
                style: this.getStyles('morphShape')
              },
              _react2['default'].createElement(
                'svg',
                {
                  width: '100%',
                  height: '100%',
                  viewBox: '0 0 100 800',
                  preserveAspectRatio: 'none'
                },
                _react2['default'].createElement('path', { d: styles.svg.pathInitial })
              )
            ),
            _react2['default'].createElement(
              'div',
              {
                className: ('bm-menu ' + this.props.menuClassName).trim(),
                style: this.getStyles('menu')
              },
              _react2['default'].createElement(
                'nav',
                {
                  className: ('bm-item-list ' + this.props.itemListClassName).trim(),
                  style: this.getStyles('itemList')
                },
                _react2['default'].Children.map(this.props.children, function (item, index) {
                  if (item) {
                    var classList = ['bm-item', _this3.props.itemClassName, item.props.className].filter(function (className) {
                      return !!className;
                    }).join(' ');
                    var extraProps = {
                      key: index,
                      className: classList,
                      style: _this3.getStyles('item', index, item.props.style),
                      tabIndex: _this3.state.isOpen ? 0 : -1
                    };
                    return _react2['default'].cloneElement(item, extraProps);
                  }
                })
              )
            ),
            this.props.customCrossIcon !== false && _react2['default'].createElement(
              'div',
              { style: this.getStyles('closeButton') },
              _react2['default'].createElement(_CrossIcon2['default'], {
                onClick: function () {
                  return _this3.toggleMenu();
                },
                styles: this.props.styles,
                customIcon: this.props.customCrossIcon,
                className: this.props.crossButtonClassName,
                crossClassName: this.props.crossClassName,
                tabIndex: this.state.isOpen ? 0 : -1
              })
            )
          ),
          this.props.customBurgerIcon !== false && _react2['default'].createElement(
            'div',
            { style: this.getStyles('burgerIcon') },
            _react2['default'].createElement(_BurgerIcon2['default'], {
              onClick: function () {
                return _this3.toggleMenu();
              },
              styles: this.props.styles,
              customIcon: this.props.customBurgerIcon,
              className: this.props.burgerButtonClassName,
              barClassName: this.props.burgerBarClassName
            })
          )
        );
      }
    }]);

    return Menu;
  })(_react.Component);

  Menu.propTypes = {
    bodyClassName: _propTypes2['default'].string,
    burgerBarClassName: _propTypes2['default'].string,
    burgerButtonClassName: _propTypes2['default'].string,
    crossButtonClassName: _propTypes2['default'].string,
    crossClassName: _propTypes2['default'].string,
    customBurgerIcon: _propTypes2['default'].oneOfType([_propTypes2['default'].element, _propTypes2['default'].oneOf([false])]),
    customCrossIcon: _propTypes2['default'].oneOfType([_propTypes2['default'].element, _propTypes2['default'].oneOf([false])]),
    customOnKeyDown: _propTypes2['default'].func,
    disableCloseOnEsc: _propTypes2['default'].bool,
    disableOverlayClick: _propTypes2['default'].oneOfType([_propTypes2['default'].bool, _propTypes2['default'].func]),
    id: _propTypes2['default'].string,
    isOpen: _propTypes2['default'].bool,
    itemClassName: _propTypes2['default'].string,
    itemListClassName: _propTypes2['default'].string,
    menuClassName: _propTypes2['default'].string,
    morphShapeClassName: _propTypes2['default'].string,
    noOverlay: _propTypes2['default'].bool,
    onStateChange: _propTypes2['default'].func,
    outerContainerId: styles && styles.outerContainer ? _propTypes2['default'].string.isRequired : _propTypes2['default'].string,
    overlayClassName: _propTypes2['default'].string,
    pageWrapId: styles && styles.pageWrap ? _propTypes2['default'].string.isRequired : _propTypes2['default'].string,
    right: _propTypes2['default'].bool,
    styles: _propTypes2['default'].object,
    width: _propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].string])
  };

  Menu.defaultProps = {
    bodyClassName: '',
    burgerBarClassName: '',
    burgerButtonClassName: '',
    className: '',
    crossButtonClassName: '',
    crossClassName: '',
    disableCloseOnEsc: false,
    id: '',
    itemClassName: '',
    itemListClassName: '',
    menuClassName: '',
    morphShapeClassName: '',
    noOverlay: false,
    onStateChange: function onStateChange() {},
    outerContainerId: '',
    overlayClassName: '',
    pageWrapId: '',
    styles: {},
    width: 300
  };

  return Menu;
};

module.exports = exports['default'];<commit_msg>only blur activeElement if defined<commit_after>'use strict';

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

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

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

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _baseStyles = require('./baseStyles');

var _baseStyles2 = _interopRequireDefault(_baseStyles);

var _BurgerIcon = require('./BurgerIcon');

var _BurgerIcon2 = _interopRequireDefault(_BurgerIcon);

var _CrossIcon = require('./CrossIcon');

var _CrossIcon2 = _interopRequireDefault(_CrossIcon);

exports['default'] = function (styles) {
  var Menu = (function (_Component) {
    _inherits(Menu, _Component);

    function Menu(props) {
      _classCallCheck(this, Menu);

      _get(Object.getPrototypeOf(Menu.prototype), 'constructor', this).call(this, props);
      this.state = {
        isOpen: false
      };
    }

    _createClass(Menu, [{
      key: 'toggleMenu',
      value: function toggleMenu() {
        var _this = this;

        var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
        var isOpen = options.isOpen;
        var noStateChange = options.noStateChange;

        var newState = {
          isOpen: typeof isOpen !== 'undefined' ? isOpen : !this.state.isOpen
        };

        this.applyWrapperStyles();

        this.setState(newState, function () {
          !noStateChange && _this.props.onStateChange(newState);

          // For accessibility reasons, ensures that when we toggle open,
          // we focus the first menu item if one exists.
          if (newState.isOpen) {
            var firstItem = document.querySelector('.bm-item');
            if (firstItem) {
              firstItem.focus();
            }
          } else if (document.activeElement) {
            document.activeElement.blur();
          } else {
            document.body.blur();
          }

          // Timeout ensures wrappers are cleared after animation finishes.
          _this.timeoutId && clearTimeout(_this.timeoutId);
          _this.timeoutId = setTimeout(function () {
            _this.timeoutId = null;
            if (!newState.isOpen) {
              _this.applyWrapperStyles(false);
            }
          }, 500);
        });
      }

      // Applies component-specific styles to external wrapper elements.
    }, {
      key: 'applyWrapperStyles',
      value: function applyWrapperStyles() {
        var set = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];

        if (this.props.bodyClassName) {
          var body = document.querySelector('body');
          body.classList[set ? 'add' : 'remove'](this.props.bodyClassName);
        }

        if (styles.pageWrap && this.props.pageWrapId) {
          this.handleExternalWrapper(this.props.pageWrapId, styles.pageWrap, set);
        }

        if (styles.outerContainer && this.props.outerContainerId) {
          this.handleExternalWrapper(this.props.outerContainerId, styles.outerContainer, set);
        }
      }

      // Sets or unsets styles on DOM elements outside the menu component.
      // This is necessary for correct page interaction with some of the menus.
      // Throws and returns if the required external elements don't exist,
      // which means any external page animations won't be applied.
    }, {
      key: 'handleExternalWrapper',
      value: function handleExternalWrapper(id, wrapperStyles, set) {
        var html = document.querySelector('html');
        var body = document.querySelector('body');
        var wrapper = document.getElementById(id);

        if (!wrapper) {
          console.error("Element with ID '" + id + "' not found");
          return;
        }

        var builtStyles = this.getStyle(wrapperStyles);

        for (var prop in builtStyles) {
          if (builtStyles.hasOwnProperty(prop)) {
            wrapper.style[prop] = set ? builtStyles[prop] : '';
          }
        }

        // Prevent any horizontal scroll.
        [html, body].forEach(function (element) {
          element.style['overflow-x'] = set ? 'hidden' : '';
        });
      }

      // Builds styles incrementally for a given element.
    }, {
      key: 'getStyles',
      value: function getStyles(el, index, inline) {
        var propName = 'bm' + el.replace(el.charAt(0), el.charAt(0).toUpperCase());

        // Set base styles.
        var output = _baseStyles2['default'][el] ? this.getStyle(_baseStyles2['default'][el]) : {};

        // Add animation-specific styles.
        if (styles[el]) {
          output = _extends({}, output, this.getStyle(styles[el], index + 1));
        }

        // Add custom styles.
        if (this.props.styles[propName]) {
          output = _extends({}, output, this.props.styles[propName]);
        }

        // Add element inline styles.
        if (inline) {
          output = _extends({}, output, inline);
        }

        return output;
      }
    }, {
      key: 'getStyle',
      value: function getStyle(style, index) {
        var width = this.props.width;

        var formattedWidth = typeof width !== 'string' ? width + 'px' : width;
        return style(this.state.isOpen, formattedWidth, this.props.right, index);
      }
    }, {
      key: 'listenForClose',
      value: function listenForClose(e) {
        e = e || window.event;

        if (this.state.isOpen && (e.key === 'Escape' || e.keyCode === 27)) {
          this.toggleMenu();
        }
      }
    }, {
      key: 'shouldDisableOverlayClick',
      value: function shouldDisableOverlayClick() {
        if (typeof this.props.disableOverlayClick === 'function') {
          return this.props.disableOverlayClick();
        } else {
          return this.props.disableOverlayClick;
        }
      }
    }, {
      key: 'componentWillMount',
      value: function componentWillMount() {
        if (!styles) {
          throw new Error('No styles supplied');
        }
      }
    }, {
      key: 'componentDidMount',
      value: function componentDidMount() {
        // Bind ESC key handler (unless disabled or custom function supplied).
        if (this.props.customOnKeyDown) {
          window.onkeydown = this.props.customOnKeyDown;
        } else if (!this.props.disableCloseOnEsc) {
          window.onkeydown = this.listenForClose.bind(this);
        }

        // Allow initial open state to be set by props.
        if (this.props.isOpen) {
          this.toggleMenu({ isOpen: true, noStateChange: true });
        }
      }
    }, {
      key: 'componentWillUnmount',
      value: function componentWillUnmount() {
        window.onkeydown = null;

        this.applyWrapperStyles(false);
      }
    }, {
      key: 'componentDidUpdate',
      value: function componentDidUpdate() {
        var _this2 = this;

        if (styles.svg) {
          (function () {
            var morphShape = _reactDom2['default'].findDOMNode(_this2, 'bm-morph-shape');
            var path = styles.svg.lib(morphShape).select('path');

            if (_this2.state.isOpen) {
              // Animate SVG path.
              styles.svg.animate(path);
            } else {
              // Reset path (timeout ensures animation happens off screen).
              setTimeout(function () {
                path.attr('d', styles.svg.pathInitial);
              }, 300);
            }
          })();
        }
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        if (typeof nextProps.isOpen !== 'undefined' && nextProps.isOpen !== this.state.isOpen) {
          this.toggleMenu();
        }
      }
    }, {
      key: 'render',
      value: function render() {
        var _this3 = this;

        return _react2['default'].createElement(
          'div',
          null,
          !this.props.noOverlay && _react2['default'].createElement('div', {
            className: ('bm-overlay ' + this.props.overlayClassName).trim(),
            onClick: function () {
              return !_this3.shouldDisableOverlayClick() && _this3.toggleMenu();
            },
            style: this.getStyles('overlay')
          }),
          _react2['default'].createElement(
            'div',
            {
              id: this.props.id,
              className: ('bm-menu-wrap ' + this.props.className).trim(),
              style: this.getStyles('menuWrap')
            },
            styles.svg && _react2['default'].createElement(
              'div',
              {
                className: ('bm-morph-shape ' + this.props.morphShapeClassName).trim(),
                style: this.getStyles('morphShape')
              },
              _react2['default'].createElement(
                'svg',
                {
                  width: '100%',
                  height: '100%',
                  viewBox: '0 0 100 800',
                  preserveAspectRatio: 'none'
                },
                _react2['default'].createElement('path', { d: styles.svg.pathInitial })
              )
            ),
            _react2['default'].createElement(
              'div',
              {
                className: ('bm-menu ' + this.props.menuClassName).trim(),
                style: this.getStyles('menu')
              },
              _react2['default'].createElement(
                'nav',
                {
                  className: ('bm-item-list ' + this.props.itemListClassName).trim(),
                  style: this.getStyles('itemList')
                },
                _react2['default'].Children.map(this.props.children, function (item, index) {
                  if (item) {
                    var classList = ['bm-item', _this3.props.itemClassName, item.props.className].filter(function (className) {
                      return !!className;
                    }).join(' ');
                    var extraProps = {
                      key: index,
                      className: classList,
                      style: _this3.getStyles('item', index, item.props.style),
                      tabIndex: _this3.state.isOpen ? 0 : -1
                    };
                    return _react2['default'].cloneElement(item, extraProps);
                  }
                })
              )
            ),
            this.props.customCrossIcon !== false && _react2['default'].createElement(
              'div',
              { style: this.getStyles('closeButton') },
              _react2['default'].createElement(_CrossIcon2['default'], {
                onClick: function () {
                  return _this3.toggleMenu();
                },
                styles: this.props.styles,
                customIcon: this.props.customCrossIcon,
                className: this.props.crossButtonClassName,
                crossClassName: this.props.crossClassName,
                tabIndex: this.state.isOpen ? 0 : -1
              })
            )
          ),
          this.props.customBurgerIcon !== false && _react2['default'].createElement(
            'div',
            { style: this.getStyles('burgerIcon') },
            _react2['default'].createElement(_BurgerIcon2['default'], {
              onClick: function () {
                return _this3.toggleMenu();
              },
              styles: this.props.styles,
              customIcon: this.props.customBurgerIcon,
              className: this.props.burgerButtonClassName,
              barClassName: this.props.burgerBarClassName
            })
          )
        );
      }
    }]);

    return Menu;
  })(_react.Component);

  Menu.propTypes = {
    bodyClassName: _propTypes2['default'].string,
    burgerBarClassName: _propTypes2['default'].string,
    burgerButtonClassName: _propTypes2['default'].string,
    crossButtonClassName: _propTypes2['default'].string,
    crossClassName: _propTypes2['default'].string,
    customBurgerIcon: _propTypes2['default'].oneOfType([_propTypes2['default'].element, _propTypes2['default'].oneOf([false])]),
    customCrossIcon: _propTypes2['default'].oneOfType([_propTypes2['default'].element, _propTypes2['default'].oneOf([false])]),
    customOnKeyDown: _propTypes2['default'].func,
    disableCloseOnEsc: _propTypes2['default'].bool,
    disableOverlayClick: _propTypes2['default'].oneOfType([_propTypes2['default'].bool, _propTypes2['default'].func]),
    id: _propTypes2['default'].string,
    isOpen: _propTypes2['default'].bool,
    itemClassName: _propTypes2['default'].string,
    itemListClassName: _propTypes2['default'].string,
    menuClassName: _propTypes2['default'].string,
    morphShapeClassName: _propTypes2['default'].string,
    noOverlay: _propTypes2['default'].bool,
    onStateChange: _propTypes2['default'].func,
    outerContainerId: styles && styles.outerContainer ? _propTypes2['default'].string.isRequired : _propTypes2['default'].string,
    overlayClassName: _propTypes2['default'].string,
    pageWrapId: styles && styles.pageWrap ? _propTypes2['default'].string.isRequired : _propTypes2['default'].string,
    right: _propTypes2['default'].bool,
    styles: _propTypes2['default'].object,
    width: _propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].string])
  };

  Menu.defaultProps = {
    bodyClassName: '',
    burgerBarClassName: '',
    burgerButtonClassName: '',
    className: '',
    crossButtonClassName: '',
    crossClassName: '',
    disableCloseOnEsc: false,
    id: '',
    itemClassName: '',
    itemListClassName: '',
    menuClassName: '',
    morphShapeClassName: '',
    noOverlay: false,
    onStateChange: function onStateChange() {},
    outerContainerId: '',
    overlayClassName: '',
    pageWrapId: '',
    styles: {},
    width: 300
  };

  return Menu;
};

module.exports = exports['default'];<|endoftext|>