<commit_before>'use strict';

const path = require('path');
const fs = require('fs');
const child = require('child_process');
const Conf = require('conf');
const inquirer = require('inquirer');
const env = require('yeoman-environment').createEnv();
const chalk = require('chalk');
const figures = require('figures');
const get = require('lodash.get');
const minimist = require('minimist');
const updateNotifier = require('update-notifier');
const asciiLogo = require('@ngx-rocket/ascii-logo');
const fuzzyRun = require('fuzz-run');
const pkg = require('../package.json');

const addonKey = 'ngx-rocket-addon';
const disabledAddons = 'disabledAddons';
const blacklistedNpmAddons = ['generator-ngx-rocket', 'generator-ngx-rocket-addon'];
const appName = path.basename(process.argv[1]);
const help = `${chalk.bold(`Usage:`)} ${appName} ${chalk.blue(`[new|update|config|list|<script>]`)} [options]\n`;
const detailedHelp = `
${chalk.blue('n, new')} [name]
  Creates a new app.
  -a, --addon                 Creates an add-on instead.
  --packageManager <yarn|npm> Uses specified package manager.
  --automate <json_file>      Automates prompt answers using JSON file.
  --tools                     Generates only the toolchain

${chalk.blue('u, update')}
  Updates an existing app or add-on.
  --tools                     Updates only the toolchain

${chalk.blue('c, config')}
  Configures add-ons to use for new apps.
  All available add-ons are used by default.

${chalk.blue('l, list')}
  Lists available add-ons.
  -n, --npm    Show installable add-ons on NPM

${chalk.blue('<script>')}
  Runs specified script from your ${chalk.bold(`package.json`)}.
  Works like ${chalk.bold(`npm run <script>`)} with fuzzy matching
`;

class NgxCli {
  constructor(args) {
    this._args = args;
    this._options = minimist(args, {
      boolean: ['help', 'npm', 'addon', 'packageManager'],
      alias: {
        n: 'npm',
        a: 'addon'
      }
    });
    this._config = new Conf({
      defaults: {
        disabledAddons: {}
      }
    });

    env.register(require.resolve('..'), 'ngx-rocket');
  }

  run() {
    updateNotifier({pkg}).notify();

    if (this._options.help) {
      return this._help(true);
    }

    switch (this._args[0]) {
      case 'n':
      case 'new':
        return this.generate(false, this._args.slice(1), this._options.addon);
      case 'u':
      case 'update':
        return this.generate(true, this._args.slice(1), this._options.addon);
      case 'c':
      case 'config':
        return this.configure();
      case 'l':
      case 'list':
        return this.list(this._options.npm);
      default:
        this.runScript(this._args);
    }
  }

  runScript(args) {
    if (!args[0]) {
      return this._help();
    }

    const packageManager = this._packageManager();
    fuzzyRun(args, packageManager);
  }

  async generate(update, args, addon) {
    if (!update) {
      console.log(asciiLogo(pkg.version));
    } else if (fs.existsSync('.yo-rc.json')) {
      const rc = JSON.parse(fs.readFileSync('.yo-rc.json'));
      addon = Boolean(get(rc, 'generator-ngx-rocket.props.isAddon'));
    } else {
      this._exit(`No existing app found, use ${chalk.blue('ngx new')} instead`);
    }

    if (addon) {
      args = args.filter(arg => arg !== '--addon' && arg !== '-a');
      env.lookup(() =>
        env.run(['ngx-rocket:addon'].concat(args), {
          update,
          packageManager: this._packageManager(),
          'skip-welcome': true
        })
      );
    } else {
      const disabled = this._config.get(disabledAddons);
      let addons = await this._findAddons();
      addons = addons.filter(addon => !disabled[addon]);

      await new Promise(resolve =>
        env.lookup(() =>
          env.run(
            ['ngx-rocket'].concat(args),
            {
              update,
              packageManager: this._packageManager(),
              addons: addons.join(' '),
              'skip-welcome': true
            },
            resolve
          )
        )
      );
      console.log();
    }
  }

  async configure() {
    const addons = await this._findAddons();
    const disabled = this._config.get(disabledAddons);
    const answers = await inquirer.prompt({
      type: 'checkbox',
      name: 'addons',
      message: 'Choose add-ons to use for new apps',
      choices: addons.map(addon => ({
        name: addon,
        checked: !disabled[addon]
      }))
    });

    this._config.set(
      disabledAddons,
      addons
        .filter(addon => !answers.addons.includes(addon))
        .reduce((r, addon) => {
          r[addon] = true;
          return r;
        }, {})
    );
    console.log('Configuration saved.');
  }

  async list(npm) {
    let addons;
    if (npm) {
      addons = await Promise.resolve(child.execSync(`npm search ${addonKey} --json`, {stdio: [0, null, 2]}));
      addons = addons ? JSON.parse(addons) : [];
      addons = addons.filter(addon => blacklistedNpmAddons.indexOf(addon.name) === -1);
    } else {
      addons = await this._findAddons();
    }

    const disabled = this._config.get(disabledAddons);
    console.log(chalk.blue(`Available add-ons${npm ? ' on NPM' : ''}:`));

    if (addons.length === 0) {
      console.log('  No add-ons found.');
    } else if (npm) {
      addons.forEach(addon => console.log(`  ${addon.name}@${addon.version} - ${addon.description}`));
    } else {
      addons.forEach(addon => console.log(`${chalk.green(disabled[addon] ? ' ' : figures.tick)} ${addon}`));
    }
  }

  _findAddons() {
    return new Promise(resolve => {
      env.lookup(() => {
        const generators = env.getGeneratorsMeta();
        const addons = Object.keys(generators)
          .map(alias => generators[alias])
          .filter(generator => {
            const packagePath = this._findPackageJson(generator.resolved);
            const keywords = require(packagePath).keywords || [];
            return keywords.includes(addonKey);
          })
          .map(generator => generator.namespace.replace(/(.*?):app$/, '$1'));
        resolve(addons);
      });
    });
  }

  _findPackageJson(basePath) {
    const find = components => {
      if (components.length === 0) {
        return null;
      }

      const dir = path.join(...components);
      const packageFile = path.join(dir, 'package.json');
      return fs.existsSync(packageFile) ? packageFile : find(components.slice(0, -1));
    };

    const components = basePath.split(/[/\\]/);
    if (components.length !== 0 && components[0].length === 0) {
      // When path starts with a slash, the first path component is empty string
      components[0] = path.sep;
    }

    return find(components);
  }

  _packageManager() {
    if (this._options.packageManager) {
      return this._options.packageManager === 'yarn' ? 'yarn' : 'npm';
    }

    let pm = null;
    try {
      const rc = require(path.join(process.cwd(), '.yo-rc.json'));
      pm = rc['generator-ngx-rocket'].props.packageManager;
    } catch (error) {
      // Do nothing
    }

    return pm || process.env.NGX_PACKAGE_MANAGER || 'npm';
  }

  _help(details) {
    console.log(asciiLogo(pkg.version));
    this._exit(help + (details ? detailedHelp : `Use ${chalk.white(`--help`)} for more info.\n`));
  }

  _exit(error, code = 1) {
    console.error(error);
    // eslint-disable-next-line unicorn/no-process-exit
    process.exit(code);
  }
}

module.exports = NgxCli;
<commit_msg>Set project name explicitly in the CLI (fix #421)<commit_after>'use strict';

const path = require('path');
const fs = require('fs');
const child = require('child_process');
const Conf = require('conf');
const inquirer = require('inquirer');
const env = require('yeoman-environment').createEnv();
const chalk = require('chalk');
const figures = require('figures');
const get = require('lodash.get');
const minimist = require('minimist');
const updateNotifier = require('update-notifier');
const asciiLogo = require('@ngx-rocket/ascii-logo');
const fuzzyRun = require('fuzz-run');
const pkg = require('../package.json');

const addonKey = 'ngx-rocket-addon';
const disabledAddons = 'disabledAddons';
const blacklistedNpmAddons = ['generator-ngx-rocket', 'generator-ngx-rocket-addon'];
const appName = path.basename(process.argv[1]);
const help = `${chalk.bold(`Usage:`)} ${appName} ${chalk.blue(`[new|update|config|list|<script>]`)} [options]\n`;
const detailedHelp = `
${chalk.blue('n, new')} [name]
  Creates a new app.
  -a, --addon                 Creates an add-on instead.
  --packageManager <yarn|npm> Uses specified package manager.
  --automate <json_file>      Automates prompt answers using JSON file.
  --tools                     Generates only the toolchain

${chalk.blue('u, update')}
  Updates an existing app or add-on.
  --tools                     Updates only the toolchain

${chalk.blue('c, config')}
  Configures add-ons to use for new apps.
  All available add-ons are used by default.

${chalk.blue('l, list')}
  Lists available add-ons.
  -n, --npm    Show installable add-ons on NPM

${chalk.blue('<script>')}
  Runs specified script from your ${chalk.bold(`package.json`)}.
  Works like ${chalk.bold(`npm run <script>`)} with fuzzy matching
`;

class NgxCli {
  constructor(args) {
    this._args = args;
    this._options = minimist(args, {
      boolean: ['help', 'npm', 'addon', 'packageManager'],
      alias: {
        n: 'npm',
        a: 'addon'
      }
    });
    this._config = new Conf({
      projectName: 'generator-ngx-rocket',
      defaults: {
        disabledAddons: {}
      }
    });

    env.register(require.resolve('..'), 'ngx-rocket');
  }

  run() {
    updateNotifier({pkg}).notify();

    if (this._options.help) {
      return this._help(true);
    }

    switch (this._args[0]) {
      case 'n':
      case 'new':
        return this.generate(false, this._args.slice(1), this._options.addon);
      case 'u':
      case 'update':
        return this.generate(true, this._args.slice(1), this._options.addon);
      case 'c':
      case 'config':
        return this.configure();
      case 'l':
      case 'list':
        return this.list(this._options.npm);
      default:
        this.runScript(this._args);
    }
  }

  runScript(args) {
    if (!args[0]) {
      return this._help();
    }

    const packageManager = this._packageManager();
    fuzzyRun(args, packageManager);
  }

  async generate(update, args, addon) {
    if (!update) {
      console.log(asciiLogo(pkg.version));
    } else if (fs.existsSync('.yo-rc.json')) {
      const rc = JSON.parse(fs.readFileSync('.yo-rc.json'));
      addon = Boolean(get(rc, 'generator-ngx-rocket.props.isAddon'));
    } else {
      this._exit(`No existing app found, use ${chalk.blue('ngx new')} instead`);
    }

    if (addon) {
      args = args.filter(arg => arg !== '--addon' && arg !== '-a');
      env.lookup(() =>
        env.run(['ngx-rocket:addon'].concat(args), {
          update,
          packageManager: this._packageManager(),
          'skip-welcome': true
        })
      );
    } else {
      const disabled = this._config.get(disabledAddons);
      let addons = await this._findAddons();
      addons = addons.filter(addon => !disabled[addon]);

      await new Promise(resolve =>
        env.lookup(() =>
          env.run(
            ['ngx-rocket'].concat(args),
            {
              update,
              packageManager: this._packageManager(),
              addons: addons.join(' '),
              'skip-welcome': true
            },
            resolve
          )
        )
      );
      console.log();
    }
  }

  async configure() {
    const addons = await this._findAddons();
    const disabled = this._config.get(disabledAddons);
    const answers = await inquirer.prompt({
      type: 'checkbox',
      name: 'addons',
      message: 'Choose add-ons to use for new apps',
      choices: addons.map(addon => ({
        name: addon,
        checked: !disabled[addon]
      }))
    });

    this._config.set(
      disabledAddons,
      addons
        .filter(addon => !answers.addons.includes(addon))
        .reduce((r, addon) => {
          r[addon] = true;
          return r;
        }, {})
    );
    console.log('Configuration saved.');
  }

  async list(npm) {
    let addons;
    if (npm) {
      addons = await Promise.resolve(child.execSync(`npm search ${addonKey} --json`, {stdio: [0, null, 2]}));
      addons = addons ? JSON.parse(addons) : [];
      addons = addons.filter(addon => blacklistedNpmAddons.indexOf(addon.name) === -1);
    } else {
      addons = await this._findAddons();
    }

    const disabled = this._config.get(disabledAddons);
    console.log(chalk.blue(`Available add-ons${npm ? ' on NPM' : ''}:`));

    if (addons.length === 0) {
      console.log('  No add-ons found.');
    } else if (npm) {
      addons.forEach(addon => console.log(`  ${addon.name}@${addon.version} - ${addon.description}`));
    } else {
      addons.forEach(addon => console.log(`${chalk.green(disabled[addon] ? ' ' : figures.tick)} ${addon}`));
    }
  }

  _findAddons() {
    return new Promise(resolve => {
      env.lookup(() => {
        const generators = env.getGeneratorsMeta();
        const addons = Object.keys(generators)
          .map(alias => generators[alias])
          .filter(generator => {
            const packagePath = this._findPackageJson(generator.resolved);
            const keywords = require(packagePath).keywords || [];
            return keywords.includes(addonKey);
          })
          .map(generator => generator.namespace.replace(/(.*?):app$/, '$1'));
        resolve(addons);
      });
    });
  }

  _findPackageJson(basePath) {
    const find = components => {
      if (components.length === 0) {
        return null;
      }

      const dir = path.join(...components);
      const packageFile = path.join(dir, 'package.json');
      return fs.existsSync(packageFile) ? packageFile : find(components.slice(0, -1));
    };

    const components = basePath.split(/[/\\]/);
    if (components.length !== 0 && components[0].length === 0) {
      // When path starts with a slash, the first path component is empty string
      components[0] = path.sep;
    }

    return find(components);
  }

  _packageManager() {
    if (this._options.packageManager) {
      return this._options.packageManager === 'yarn' ? 'yarn' : 'npm';
    }

    let pm = null;
    try {
      const rc = require(path.join(process.cwd(), '.yo-rc.json'));
      pm = rc['generator-ngx-rocket'].props.packageManager;
    } catch (error) {
      // Do nothing
    }

    return pm || process.env.NGX_PACKAGE_MANAGER || 'npm';
  }

  _help(details) {
    console.log(asciiLogo(pkg.version));
    this._exit(help + (details ? detailedHelp : `Use ${chalk.white(`--help`)} for more info.\n`));
  }

  _exit(error, code = 1) {
    console.error(error);
    // eslint-disable-next-line unicorn/no-process-exit
    process.exit(code);
  }
}

module.exports = NgxCli;
<|endoftext|>


<commit_before>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

const fs = require("fs");
const tmp = require("tmp");
const graph_sorter = require("./graph_sorter");
const TIMESTEP = 1000 * 1000;

function toSeconds(v) {
	return v / 1000 / 1000;
}

function timeutil(start, x) {
	return toSeconds(x - start.startTime);
}

function handlePercentage(summary, outFile, mode, doneCb) {
	let jobList = summary.jobs;

	let time = timeutil.bind(this, jobList[0]);

	let coverageLines = "0, 0\n";

	let lastCoverage = 0;

	jobList.forEach(x => {
		coverageLines += "" + time(x.endTime) + ", " + Math.max(graph_sorter.aggregateCoverage(x)[mode], lastCoverage) + "\n";
		lastCoverage = graph_sorter.aggregateCoverage(x)[mode];
	});

	fs.writeFile(outFile, coverageLines, doneCb);
}

function handlePerSecond(summary, outFile, doneCb) {
	let jobList = summary.jobs;
	let startTime = jobList[0].startTime;
	let endTime = jobList[jobList.length - 1].endTime;
	let time = timeutil.bind(this, jobList[0]);
	let intervalLines = "0, 0\n";

	for (let i = startTime; i < endTime; i += TIMESTEP) {
		let jobsInInterval = jobList.filter(x => x.endTime >= i && x.endTime <= (i + TIMESTEP)).length;
		intervalLines += "" + time(i) + ", " + jobsInInterval + "\n";
	}

	fs.writeFile(outFile, intervalLines, doneCb);
}

function buildGraphData(summary, done) {

	const COVERAGE_MODES = ["lines", "terms"];

	let coverageFiles = COVERAGE_MODES.map(() => tmp.fileSync());
	let rateOutFile = tmp.fileSync();

	let finished = 0;

	function finishedCallback() {
		finished++;

		if (finished == coverageFiles.length + 1) {
			done({
				coverage: coverageFiles,
				rate: rateOutFile
			});
		}
	}

	COVERAGE_MODES.forEach((mode, idx) => handlePercentage(summary, coverageFiles[idx].name, mode, finishedCallback));
	handlePerSecond(summary, rateOutFile.name, finishedCallback);
}

module.exports = buildGraphData;
<commit_msg>Update the dashboard<commit_after>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

const fs = require("fs");
const tmp = require("tmp");
const graph_sorter = require("./graph_sorter");
const TIMESTEP = 1000;

function toSeconds(v) {
	return v / 1000;
}

function timeutil(start, x) {
	return toSeconds(x - start.startTime);
}

function handlePercentage(summary, outFile, mode, doneCb) {
	const jobList = summary.jobs;
	const time = timeutil.bind(this, jobList[0]);
	let coverageLines = "0, 0\n";
	let lastCoverage = 0;

	jobList.forEach(x => {
		coverageLines += "" + time(x.endTime) + ", " + Math.max(graph_sorter.aggregateCoverage(x)[mode], lastCoverage) + "\n";
		lastCoverage = graph_sorter.aggregateCoverage(x)[mode];
	});

	fs.writeFile(outFile, coverageLines, doneCb);
}

function handlePerSecond(summary, outFile, doneCb) {
	let jobList = summary.jobs;
	let startTime = jobList[0].startTime;
	let endTime = jobList[jobList.length - 1].endTime;
	let time = timeutil.bind(this, jobList[0]);
	let intervalLines = "0, 0\n";

	for (let i = startTime; i < endTime; i += TIMESTEP) {
		let jobsInInterval = jobList.filter(x => x.endTime >= i && x.endTime <= (i + TIMESTEP)).length;
		intervalLines += "" + time(i) + ", " + jobsInInterval + "\n";
	}

	fs.writeFile(outFile, intervalLines, doneCb);
}

function buildGraphData(summary, done) {

	const COVERAGE_MODES = ["lines"];

	let coverageFiles = COVERAGE_MODES.map(() => tmp.fileSync());
	let rateOutFile = tmp.fileSync();

	let finished = 0;

	function finishedCallback() {
		finished++;

		if (finished == coverageFiles.length + 1) {
			done({
				coverage: coverageFiles,
				rate: rateOutFile
			});
		}
	}

	COVERAGE_MODES.forEach((mode, idx) => handlePercentage(summary, coverageFiles[idx].name, mode, finishedCallback));
	handlePerSecond(summary, rateOutFile.name, finishedCallback);
}

module.exports = buildGraphData;
<|endoftext|>


<commit_before><commit_msg>PR feedback<commit_after><|endoftext|>


<commit_before>/*!
 * Copyright 2012 The Toolkitchen Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
function PointerEvent(e,t){var n=document.createEvent("MouseEvent");return n.__proto__=PointerEvent.prototype,n.initPointerEvent(e,t),n}PointerEvent.prototype.__proto__=MouseEvent.prototype,PointerEvent.prototype.initPointerEvent=function(e,t){var n={bubbles:!1,cancelable:!1,view:null,detail:null,screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:-1,buttons:null,which:0,relatedTarget:null,pointerId:-1,width:0,height:0,pressure:0,tiltX:0,tiltY:0,pointerType:"unavailable",hwTimestamp:0,isPrimary:!1};for(var r in t)r in n&&(n[r]=t[r]);var i;n.buttons!==null?i=n.buttons?n.button:-1:i=n.which?n.button:-1,Object.defineProperties(this,{pointerId:{value:n.pointerId,enumerable:!0},width:{value:n.width,enumerable:!0},height:{value:n.height,enumerable:!0},pressure:{value:n.pressure,enumerable:!0},tiltX:{value:n.tiltX,enumerable:!0},tiltY:{value:n.tiltY,enumerable:!0},pointerType:{value:n.pointerType,enumerable:!0},hwTimestamp:{value:n.hwTimestamp,enumerable:!0},isPrimary:{value:n.isPrimary,enumerable:!0}}),this.initMouseEvent(e,n.bubbles,n.cancelable,n.view,n.detail,n.screenX,n.screenY,n.clientX,n.clientY,n.ctrlKey,n.altKey,n.shiftKey,n.metaKey,i,n.relatedTarget)};var SideTable;typeof WeakMap!="undefined"?SideTable=WeakMap:(SideTable=function(e){this.name="__$"+e+"$__"},SideTable.prototype={set:function(e,t){Object.defineProperty(e,this.name,{value:t,writable:!0})},get:function(e){return e[this.name]}}),function(e){e=e||{},Function.prototype.bind||(Function.prototype.bind=function(t){var n=e.toArray(arguments,1),r=this;return function(){var i=e.toArray(arguments,0);return r.apply(t,n.concat(i))}}),e.toArray=function(e,t){return Array.prototype.slice.call(e,t||0)},window.__PointerEventShim__=e}(window.__PointerEventShim__),function(e){var t={pointers:[],addPointer:function(e){var t={id:e};return this.pointers.push(t),t},removePointer:function(e){var t=this.getPointerIndex(e);if(t>-1)return this.pointers.splice(t,1)[0]},getPointerById:function(e){return this.pointers[this.getPointerIndex(e)]},getPointerIndex:function(e){for(var t=0,n=this.pointers.length,r;t<n&&(r=this.pointers[t]);t++)if(r.id===e)return t;return-1}};e.pointermap=t}(window.__PointerEventShim__),function(e){var t={targets:new SideTable("target"),handledEvents:new SideTable("pointer"),events:[],eventMap:{},eventSources:{},registerSource:function(e,t){var n=t;this.events=n.events,this.events.forEach(function(e){n[e]&&(this.eventMap[e]=n[e].bind(n))},this),this.eventSources[e]=n},registerTarget:function(e){this.listen(this.events,e)},unregisterTarget:function(e){this.unlisten(this.events,e)},down:function(e){this.fireEvent("pointerdown",e)},move:function(e){this.fireEvent("pointermove",e)},up:function(e){this.fireEvent("pointerup",e)},enter:function(e){this.fireEvent("pointerenter",e)},leave:function(e){this.fireEvent("pointerleave",e)},over:function(e){this.fireEvent("pointerover",e)},out:function(e){this.fireEvent("pointerout",e)},cancel:function(e){this.fireEvent("pointercancel",e)},eventHandler:function(e){if(this.handledEvents.get(e))return;var t=e.type,n=this.eventMap&&this.eventMap[t];n&&n(e),this.handledEvents.set(e,!0)},listen:function(e,t){e.forEach(function(e){this.addEvent(e,this.boundHandler,!1,t)},this)},unlisten:function(e){e.forEach(function(e){this.removeEvent(e,this.boundHandler,!1,inTarget)},this)},addEvent:function(e,t,n,r){r.addEventListener(e,t,n)},removeEvent:function(e,t,n,r){r.removeEventListener(e,t,n)},makeEvent:function(e,t){var n=new PointerEvent(e,t);return this.targets.set(n,this.targets.get(t)||t.target),n},fireEvent:function(e,t){var n=this.makeEvent(e,t);return this.dispatchEvent(n)},cloneEvent:function(e){var t={};for(var n in e)t[n]=e[n];return t},getTarget:function(e){return this.captureInfo&&this.captureInfo.id===e.pointerId?this.captureInfo.target:this.targets.get(e)},dispatchEvent:function(e){var t=this.getTarget(e);if(t)return t.dispatchEvent(e)}};t.boundHandler=t.eventHandler.bind(t),e.dispatcher=t,e.register=function(e){t.registerTarget(e)},e.unregister=function(e){t.unregisterTarget(e)}}(window.__PointerEventShim__),function(e){var t=e.dispatcher,n=e.pointermap,r=Array.prototype.map.call.bind(Array.prototype.map),i={events:["touchstart","touchmove","touchend","touchcancel"],POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(e){return this.firstTouch===e.identifier},removePrimaryTouch:function(e){this.isPrimaryTouch(e)&&(this.firstTouch=null)},touchToPointer:function(e){var n=t.cloneEvent(e);return n.pointerId=e.identifier+2,n.target=this.findTarget(n),n.bubbles=!0,n.cancelable=!0,n.button=0,n.buttons=1,n.isPrimary=this.isPrimaryTouch(e),n.pointerType=this.POINTER_TYPE,n},processTouches:function(e,t){var n=e.changedTouches,i=r(n,this.touchToPointer,this);i.forEach(t,this)},findTarget:function(e){return document.elementFromPoint(e.clientX,e.clientY)},touchstart:function(e){this.firstTouch===null&&(this.firstTouch=e.changedTouches[0].identifier),this.processTouches(e,this.overDown)},overDown:function(e){var r=n.addPointer(e.pointerId);t.over(e),t.down(e),r.out=e},touchmove:function(e){e.preventDefault(),this.processTouches(e,this.moveOverOut)},moveOverOut:function(e){var r=e,i=n.getPointerById(r.pointerId),s=i.out;t.move(r),s&&s.target!==r.target&&(s.relatedTarget=r.target,r.relatedTarget=s.target,t.out(s),t.over(r)),i.out=r},touchend:function(e){this.processTouches(e,this.upOut)},upOut:function(e){t.up(e),t.out(e),n.removePointer(e.pointerId),this.removePrimaryTouch(e)},touchcancel:function(e){this.processTouches(e,this.cancelOut)},cancelOut:function(e){t.cancel(e),t.out(e),n.removePointer(e.pointerId),this.removePrimaryTouch(e)}},s={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],prepareEvent:function(e){var n=t.cloneEvent(e);return n.pointerId=this.POINTER_ID,n.isPrimary=!0,n.pointerType=this.POINTER_TYPE,n},mousedown:function(e){if(n.getPointerIndex(this.POINTER_ID)==-1){var r=this.prepareEvent(e),i=n.addPointer(this.POINTER_ID);i.button=e.button,t.down(r)}},mousemove:function(e){var n=this.prepareEvent(e);t.move(n)},mouseup:function(e){var r=n.getPointerById(this.POINTER_ID);if(r&&r.button===e.button){var i=this.prepareEvent(e);t.up(i),n.removePointer(this.POINTER_ID)}},mouseover:function(e){var n=this.prepareEvent(e);t.over(n)},mouseout:function(e){var n=this.prepareEvent(e);t.out(n)}};window.navigator.pointerEnabled===undefined&&("ontouchstart"in window?t.registerSource("touch",i):t.registerSource("mouse",s),t.registerTarget(document),Object.defineProperty(window.navigator,"pointerEnabled",{value:!0,enumerable:!0}))}(window.__PointerEventShim__);<commit_msg>Update build for IE 10<commit_after>/*!
 * Copyright 2012 The Toolkitchen Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
function PointerEvent(e,t){var n=document.createEvent("MouseEvent");return Object.__proto__?(n.__proto__=PointerEvent.prototype,n.initPointerEvent(e,t)):PointerEvent.prototype.initPointerEvent.call(n,e,t),n}PointerEvent.prototype.__proto__=MouseEvent.prototype,PointerEvent.prototype.initPointerEvent=function(e,t){var n={bubbles:!1,cancelable:!1,view:null,detail:null,screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:-1,buttons:null,which:0,relatedTarget:null,pointerId:-1,width:0,height:0,pressure:0,tiltX:0,tiltY:0,pointerType:"unavailable",hwTimestamp:0,isPrimary:!1};for(var r in t)r in n&&(n[r]=t[r]);var i;n.buttons!==null?i=n.buttons?n.button:-1:i=n.which?n.button:-1,Object.defineProperties(this,{pointerId:{value:n.pointerId,enumerable:!0},width:{value:n.width,enumerable:!0},height:{value:n.height,enumerable:!0},pressure:{value:n.pressure,enumerable:!0},tiltX:{value:n.tiltX,enumerable:!0},tiltY:{value:n.tiltY,enumerable:!0},pointerType:{value:n.pointerType,enumerable:!0},hwTimestamp:{value:n.hwTimestamp,enumerable:!0},isPrimary:{value:n.isPrimary,enumerable:!0}}),this.initMouseEvent(e,n.bubbles,n.cancelable,n.view,n.detail,n.screenX,n.screenY,n.clientX,n.clientY,n.ctrlKey,n.altKey,n.shiftKey,n.metaKey,i,n.relatedTarget)};var SideTable;typeof WeakMap!="undefined"&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:(SideTable=function(e){this.name="__$"+e+"$__"},SideTable.prototype={set:function(e,t){Object.defineProperty(e,this.name,{value:t,writable:!0})},get:function(e){return e[this.name]}}),function(e){e=e||{},Function.prototype.bind||(Function.prototype.bind=function(t){var n=e.toArray(arguments,1),r=this;return function(){var i=e.toArray(arguments,0);return r.apply(t,n.concat(i))}}),e.toArray=function(e,t){return Array.prototype.slice.call(e,t||0)},window.__PointerEventShim__=e}(window.__PointerEventShim__),function(e){var t={pointers:[],addPointer:function(e){var t={id:e};return this.pointers.push(t),t},removePointer:function(e){var t=this.getPointerIndex(e);if(t>-1)return this.pointers.splice(t,1)[0]},getPointerById:function(e){return this.pointers[this.getPointerIndex(e)]},getPointerIndex:function(e){for(var t=0,n=this.pointers.length,r;t<n&&(r=this.pointers[t]);t++)if(r.id===e)return t;return-1}};e.pointermap=t}(window.__PointerEventShim__),function(e){var t={targets:new SideTable("target"),handledEvents:new SideTable("pointer"),events:[],eventMap:{},eventSources:{},registerSource:function(e,t){var n=t;this.events=n.events,this.events.forEach(function(e){n[e]&&(this.eventMap[e]=n[e].bind(n))},this),this.eventSources[e]=n},registerTarget:function(e){this.listen(this.events,e)},unregisterTarget:function(e){this.unlisten(this.events,e)},down:function(e){this.fireEvent("pointerdown",e)},move:function(e){this.fireEvent("pointermove",e)},up:function(e){this.fireEvent("pointerup",e)},enter:function(e){this.fireEvent("pointerenter",e)},leave:function(e){this.fireEvent("pointerleave",e)},over:function(e){this.fireEvent("pointerover",e)},out:function(e){this.fireEvent("pointerout",e)},cancel:function(e){this.fireEvent("pointercancel",e)},eventHandler:function(e){if(this.handledEvents.get(e))return;var t=e.type,n=this.eventMap&&this.eventMap[t];n&&n(e),this.handledEvents.set(e,!0)},listen:function(e,t){e.forEach(function(e){this.addEvent(e,this.boundHandler,!1,t)},this)},unlisten:function(e){e.forEach(function(e){this.removeEvent(e,this.boundHandler,!1,inTarget)},this)},addEvent:function(e,t,n,r){r.addEventListener(e,t,n)},removeEvent:function(e,t,n,r){r.removeEventListener(e,t,n)},makeEvent:function(e,t){var n=new PointerEvent(e,t);return this.targets.set(n,this.targets.get(t)||t.target),n},fireEvent:function(e,t){var n=this.makeEvent(e,t);return this.dispatchEvent(n)},cloneEvent:function(e){var t={};for(var n in e)t[n]=e[n];return t},getTarget:function(e){return this.captureInfo&&this.captureInfo.id===e.pointerId?this.captureInfo.target:this.targets.get(e)},dispatchEvent:function(e){var t=this.getTarget(e);if(t)return t.dispatchEvent(e)}};t.boundHandler=t.eventHandler.bind(t),e.dispatcher=t,e.register=function(e){t.registerTarget(e)},e.unregister=function(e){t.unregisterTarget(e)}}(window.__PointerEventShim__),function(e){var t=e.dispatcher,n=e.pointermap,r=Array.prototype.map.call.bind(Array.prototype.map),i={events:["touchstart","touchmove","touchend","touchcancel"],POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(e){return this.firstTouch===e.identifier},removePrimaryTouch:function(e){this.isPrimaryTouch(e)&&(this.firstTouch=null)},touchToPointer:function(e){var n=t.cloneEvent(e);return n.pointerId=e.identifier+2,n.target=this.findTarget(n),n.bubbles=!0,n.cancelable=!0,n.button=0,n.buttons=1,n.isPrimary=this.isPrimaryTouch(e),n.pointerType=this.POINTER_TYPE,n},processTouches:function(e,t){var n=e.changedTouches,i=r(n,this.touchToPointer,this);i.forEach(t,this)},findTarget:function(e){return document.elementFromPoint(e.clientX,e.clientY)},touchstart:function(e){this.firstTouch===null&&(this.firstTouch=e.changedTouches[0].identifier),this.processTouches(e,this.overDown)},overDown:function(e){var r=n.addPointer(e.pointerId);t.over(e),t.down(e),r.out=e},touchmove:function(e){e.preventDefault(),this.processTouches(e,this.moveOverOut)},moveOverOut:function(e){var r=e,i=n.getPointerById(r.pointerId),s=i.out;t.move(r),s&&s.target!==r.target&&(s.relatedTarget=r.target,r.relatedTarget=s.target,t.out(s),t.over(r)),i.out=r},touchend:function(e){this.processTouches(e,this.upOut)},upOut:function(e){t.up(e),t.out(e),n.removePointer(e.pointerId),this.removePrimaryTouch(e)},touchcancel:function(e){this.processTouches(e,this.cancelOut)},cancelOut:function(e){t.cancel(e),t.out(e),n.removePointer(e.pointerId),this.removePrimaryTouch(e)}},s={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],prepareEvent:function(e){var n=t.cloneEvent(e);return n.pointerId=this.POINTER_ID,n.isPrimary=!0,n.pointerType=this.POINTER_TYPE,n},mousedown:function(e){if(n.getPointerIndex(this.POINTER_ID)==-1){var r=this.prepareEvent(e),i=n.addPointer(this.POINTER_ID);i.button=e.button,t.down(r)}},mousemove:function(e){var n=this.prepareEvent(e);t.move(n)},mouseup:function(e){var r=n.getPointerById(this.POINTER_ID);if(r&&r.button===e.button){var i=this.prepareEvent(e);t.up(i),n.removePointer(this.POINTER_ID)}},mouseover:function(e){var n=this.prepareEvent(e);t.over(n)},mouseout:function(e){var n=this.prepareEvent(e);t.out(n)}},o={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel"],POINTER_TYPES:["NOT USED","unavailable","touch","pen","mouse"],prepareEvent:function(e){var n=t.cloneEvent(e);return n.pointerType=this.POINTER_TYPES[e.pointerType],n},MSPointerDown:function(e){var n=this.prepareEvent(e);t.down(n)},MSPointerMove:function(e){var n=this.prepareEvent(e);t.move(n)},MSPointerUp:function(e){var n=this.prepareEvent(e);t.up(n)},MSPointerOut:function(e){var n=this.prepareEvent(e);t.out(n)},MSPointerOver:function(e){var n=this.prepareEvent(e);t.over(n)},MSPointerCancel:function(e){var n=this.prepareEvent(e);t.cancel(n)}};window.navigator.pointerEnabled===undefined&&(window.navigator.msPointerEnabled?(t.registerSource("ms",o),window.navigator.msMaxTouchPoints!==undefined&&Object.defineProperty(window.navigator,"maxTouchPoints",{value:window.navigator.msMaxTouchPoints,enumerable:!0})):"ontouchstart"in window?t.registerSource("touch",i):t.registerSource("mouse",s),t.registerTarget(document),Object.defineProperty(window.navigator,"pointerEnabled",{value:!0,enumerable:!0}))}(window.__PointerEventShim__);<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var program = require('commander');
var shp = require('./lib/shp');

program
  .version('1.0.0')
	.option('-s, --shapefile <s>', 'Shapefile')
	.option('-h, --host <h>', 'ElasticSearch host')
	.option('-p ,--port <p>', 'ElasticSearch port', parseInt)
	.parse(process.argv);

	if (program.shapefile === undefined ||
      program.host === undefined ||
      program.port === undefined) {
		usage();
		return;
	} else {
		shp.read(program.shapefile, program.host, program.port);
		return;
	}

function usage() {
  console.log('usage: shp2es -s <shapefile> -h <ElasticSearch host> -p <ElasticSearch port>');
}
<commit_msg>slightly more robust error checking<commit_after>#!/usr/bin/env node

'use strict';

var program = require('commander');
var shp = require('./lib/shp');
var errorText = ''

program
  .version('1.0.0')
	.option('-s, --shapefile <s>', 'Shapefile')
	.option('-h, --host <h>', 'ElasticSearch host')
	.option('-p ,--port <p>', 'ElasticSearch port', parseInt)
  .parse(process.argv);

if(!program.shapefile || !program.shapefile.match(/\.shp$/i)){
  errorText += 'Invalid shapefile.\n';
}

if(!program.host){
  errorText += 'Must provide an elasticsearch host';
}

if(!program.port || program.port < -1 || program.port > 65536){
  errorText += 'Must provide a port number between 0 and 65535';
}

if (errorText) return usage(errorText);

return shp.read(program.shapefile, program.host, program.port);

function usage(error) {
  console.log(error);
  console.log('usage: ./shp2es -s <shapefile> -h <ElasticSearch host> -p <ElasticSearch port>');
}
<|endoftext|>


<commit_before>

var FlashType = {
	F: 'fixed',
	Fl: 'flashing',
	Q: 'quick flashing',
	VQ: 'very quick flashing',
	IQ: 'interrupted quick flashing',
	Iso: 'isophase',

};

var Light = function(opts) {
	opts = opts || {};

	// location of the light
	this.x = opts.x || 0;
	this.y = opts.y || 0;

	// if the light is currently lit
	this.isLit = opts.isLit || true;

	if(!opts.colour) {
		throw Error("colour required");
	}
	this.colour = opts.colour;

	// quick - very quick - solid...
	this.flashType = opts.flashType || FlashType.F;

	// how many flashes per frequency
	this.totalFlashes = opts.totalFlashes || 0;

	// radius of the light
	this.radius = opts.radius || 5;
};

Light.prototype.update = function(delta) {

};

// helpful for drawing complete circles
var TWOPI = Math.PI * 2;

Light.prototype.draw = function(g) {

	if(this.isLit) {

		g.save();

		g.beginPath();
			g.fillStyle = this.colour;
			g.arc(this.x, this.y, this.radius, 0, TWOPI);
			g.fill();

		g.restore();
	}
};

var FixedLight  = function(opts) {

	opts = opts || {};

	opts.flashType = FlashType.F;

	Light.call(this, opts);

};
FixedLight.prototype = Object.create(Light.prototype);

<commit_msg>Created the flashing light<commit_after>

var FlashType = {
	F: 'fixed',
	Fl: 'flashing',
	Q: 'quick flashing',
	VQ: 'very quick flashing',
	IQ: 'interrupted quick flashing',
	Iso: 'isophase',

};

var Light = function(opts) {
	opts = opts || {};

	// location of the light
	this.x = opts.x || 0;
	this.y = opts.y || 0;

	//last update for timing
	this.lastUpdate = new Date();

	// if the light is currently lit
	this.isLit = opts.isLit;

	// time to live - count down till the light state swaps
	this.ttl = 0;

	if(!opts.colour) {
		throw Error("colour required");
	}
	this.colour = opts.colour;

	// quick - very quick - solid...
	this.flashType = opts.flashType || FlashType.F;

	// how many flashes per period
	this.flashesPerPeriod = opts.flashesPerPeriod || 0;

	// how long to pause before the next light in the period is lit
	this.flashPauseLength = opts.flashPauseLength || 0;

	//keeps track of how many times this period has flashed
	this.currentFlashesPerPeriod = 0;

	this.period = opts.period || 0;

	//how long this period has left to go
	this.ttlPeriod = this.period;

	//how long the light is on for
	this.flashLength = opts.flashLength || 0;

	// radius of the light
	this.radius = opts.radius || 5;
};

// empty update method for other objects to implement
Light.prototype.update = function(delta) {
	this.lastUpdate = new Date();
};

// helpful for drawing complete circles
var TWOPI = Math.PI * 2;

Light.prototype.draw = function(g) {

	if(this.isLit) {

		g.save();

		g.beginPath();
			g.fillStyle = this.colour;
			g.arc(this.x, this.y, this.radius, 0, TWOPI);
			g.fill();

		g.restore();
	}
};

var FixedLight  = function(opts) {

	opts = opts || {};
	opts.flashType = FlashType.F;

	Light.call(this, opts);
};
FixedLight.prototype = Object.create(Light.prototype);

function FlashingLight(opts) {

	opts = opts || {};
	opts.flashType = FlashType.Fl;
	opts.flashLength = 500;
	opts.period = 5000;
	opts.flashesPerPeriod = 2;
	opts.flashPauseLength = 1000;
	opts.isLit = false;

	Light.call(this, opts);
};
FlashingLight.prototype = Object.create(Light.prototype);
FlashingLight.prototype.constructor = FlashingLight;

FlashingLight.prototype.update = function(delta) {

	this.ttl -= delta;
	this.ttlPeriod -= delta;

	if(this.currentFlashesPerPeriod < this.flashesPerPeriod) { //make sure the phase isn't over
		if(this.isLit && this.ttl <= 0) { //light is on and it's time to turn it off
			this.isLit = false;
			this.ttl = this.flashPauseLength;

			this.currentFlashesPerPeriod++;
		}
		else if (!this.isLit && this.ttl <= 0) { //light is off and it's time to turn it on
			this.isLit = true;
			this.ttl = this.flashLength;
		}
	}

	if(this.ttlPeriod <= 0) { //new period - so reset
		this.ttlPeriod = this.period;
		this.currentFlashesPerPeriod = 0;
	}

};
<|endoftext|>


<commit_before><commit_msg>Relayout needed on encoding change<commit_after><|endoftext|>


<commit_before>import mixin from 'reactjs-mixin';
import React, {PropTypes} from 'react';

import Page from '../../../../../../src/js/components/Page';
import ServiceBreadcrumbs from '../../components/ServiceBreadcrumbs';
import Service from '../../structs/Service';
import ServiceActionItem from '../../constants/ServiceActionItem';
import ServiceConfigurationContainer from '../service-configuration/ServiceConfigurationContainer';
import ServiceDebugContainer from '../service-debug/ServiceDebugContainer';
import ServiceTasksContainer from '../tasks/ServiceTasksContainer';
import TabsMixin from '../../../../../../src/js/mixins/TabsMixin';
import VolumeTable from '../../components/VolumeTable';

const METHODS_TO_BIND = [
  'onActionsItemSelection'
];

class ServiceDetail extends mixin(TabsMixin) {
  constructor() {
    super(...arguments);

    this.tabs_tabs = {
      tasks: 'Instances',
      configuration: 'Configuration',
      debug: 'Debug'
    };

    this.state = {
      currentTab: Object.keys(this.tabs_tabs).shift()
    };

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    super.componentDidMount(...arguments);
    this.checkForVolumes();
  }

  componentWillUpdate() {
    super.componentWillUpdate(...arguments);
    this.checkForVolumes();
  }

  onActionsItemSelection(actionItem) {
    const {modalHandlers} = this.context;
    const {service} = this.props;

    switch (actionItem.id) {
      case ServiceActionItem.EDIT:
        modalHandlers.editService({service});
        break;
      case ServiceActionItem.SCALE:
        modalHandlers.scaleService({service});
        break;
      case ServiceActionItem.RESTART:
        modalHandlers.restartService({service});
        break;
      case ServiceActionItem.SUSPEND:
        modalHandlers.suspendService({service});
        break;
      case ServiceActionItem.DESTROY:
        modalHandlers.deleteService({service});
        break;
    };
  }

  hasVolumes() {
    return !!this.props.service &&
        this.props.service.getVolumes().getItems().length > 0;
  }

  checkForVolumes() {
    // Add the Volumes tab if it isn't already there and the service has
    // at least one volume.
    if (this.tabs_tabs.volumes == null && this.hasVolumes()) {
      this.tabs_tabs.volumes = 'Volumes';
      this.forceUpdate();
    }
  }

  renderConfigurationTabView() {
    return (
      <ServiceConfigurationContainer
        actions={this.props.actions}
        service={this.props.service} />
    );
  }

  renderDebugTabView() {
    return (
      <ServiceDebugContainer service={this.props.service}/>
    );
  }

  renderVolumesTabView() {
    return (
      <VolumeTable
        params={this.props.params}
        routes={this.props.routes}
        service={this.props.service}
        volumes={this.props.service.getVolumes().getItems()} />
    );
  }

  renderInstancesTabView() {
    return (
      <ServiceTasksContainer
        params={this.props.params}
        service={this.props.service} />
    );
  }

  getActions() {
    const {service} = this.props;
    const {modalHandlers} = this.context;
    const instanceCount = service.getInstancesCount();

    const actions = [];

    actions.push({
      label: 'Edit',
      onItemSelect: modalHandlers.editService
    });

    if (instanceCount > 0) {
      actions.push({
        label: 'Restart',
        onItemSelect: modalHandlers.restartService
      });
    }

    actions.push({
      label: 'Scale',
      onItemSelect: modalHandlers.scaleService
    });

    if (instanceCount > 0) {
      actions.push({
        label: 'Suspend',
        onItemSelect: modalHandlers.suspendService
      });
    }

    actions.push({
      className: 'text-danger',
      label: 'Destroy',
      onItemSelect: modalHandlers.deleteService
    });

    return actions;
  }

  getTabs() {
    const {service:{id}} = this.props;
    const routePrefix = `/services/overview/${encodeURIComponent(id)}`;

    const tabs = [];

    tabs.push({
      label: 'Instances',
      callback: () => {
        this.setState({currentTab: 'tasks'});
      }
    });

    tabs.push({
      label: 'Configuration',
      callback: () => {
        this.setState({currentTab: 'configuration'});
      }
    });

    tabs.push({
      label: 'Debug',
      callback: () => {
        this.setState({currentTab: 'debug'});
      }
    });

    if (this.hasVolumes()) {
      tabs.push({
        label: 'Volumes', routePath: routePrefix + '/volumes',
        callback: this.tabs_handleTabClick.bind('volumes')
      });
    }

    return tabs;
  }

  render() {
    const {modals, service:{id}} = this.props;
    const breadcrumbs = <ServiceBreadcrumbs serviceID={id} />;

    return (
      <Page>
        <Page.Header actions={this.getActions()}
            tabs={this.getTabs()}
            breadcrumbs={breadcrumbs}
            iconID="services" />
        {this.tabs_getTabView()}
        {modals}
      </Page>
    );
  }
}

ServiceDetail.contextTypes = {
  modalHandlers: PropTypes.shape({
    editService: PropTypes.func,
    scaleService: PropTypes.func,
    restartService: PropTypes.func,
    suspendService: PropTypes.func,
    deleteService: PropTypes.func
  }).isRequired
};

ServiceDetail.propTypes = {
  actions: PropTypes.object.isRequired,
  params: PropTypes.object.isRequired,
  service: PropTypes.instanceOf(Service),
  modals: PropTypes.node
};

module.exports = ServiceDetail;
<commit_msg>Updating indentation<commit_after>import mixin from 'reactjs-mixin';
import React, {PropTypes} from 'react';

import Page from '../../../../../../src/js/components/Page';
import ServiceBreadcrumbs from '../../components/ServiceBreadcrumbs';
import Service from '../../structs/Service';
import ServiceActionItem from '../../constants/ServiceActionItem';
import ServiceConfigurationContainer from '../service-configuration/ServiceConfigurationContainer';
import ServiceDebugContainer from '../service-debug/ServiceDebugContainer';
import ServiceTasksContainer from '../tasks/ServiceTasksContainer';
import TabsMixin from '../../../../../../src/js/mixins/TabsMixin';
import VolumeTable from '../../components/VolumeTable';

const METHODS_TO_BIND = [
  'onActionsItemSelection'
];

class ServiceDetail extends mixin(TabsMixin) {
  constructor() {
    super(...arguments);

    this.tabs_tabs = {
      tasks: 'Instances',
      configuration: 'Configuration',
      debug: 'Debug'
    };

    this.state = {
      currentTab: Object.keys(this.tabs_tabs).shift()
    };

    METHODS_TO_BIND.forEach((method) => {
      this[method] = this[method].bind(this);
    });
  }

  componentDidMount() {
    super.componentDidMount(...arguments);
    this.checkForVolumes();
  }

  componentWillUpdate() {
    super.componentWillUpdate(...arguments);
    this.checkForVolumes();
  }

  onActionsItemSelection(actionItem) {
    const {modalHandlers} = this.context;
    const {service} = this.props;

    switch (actionItem.id) {
      case ServiceActionItem.EDIT:
        modalHandlers.editService({service});
        break;
      case ServiceActionItem.SCALE:
        modalHandlers.scaleService({service});
        break;
      case ServiceActionItem.RESTART:
        modalHandlers.restartService({service});
        break;
      case ServiceActionItem.SUSPEND:
        modalHandlers.suspendService({service});
        break;
      case ServiceActionItem.DESTROY:
        modalHandlers.deleteService({service});
        break;
    };
  }

  hasVolumes() {
    return !!this.props.service &&
      this.props.service.getVolumes().getItems().length > 0;
  }

  checkForVolumes() {
    // Add the Volumes tab if it isn't already there and the service has
    // at least one volume.
    if (this.tabs_tabs.volumes == null && this.hasVolumes()) {
      this.tabs_tabs.volumes = 'Volumes';
      this.forceUpdate();
    }
  }

  renderConfigurationTabView() {
    return (
      <ServiceConfigurationContainer
        actions={this.props.actions}
        service={this.props.service} />
    );
  }

  renderDebugTabView() {
    return (
      <ServiceDebugContainer service={this.props.service}/>
    );
  }

  renderVolumesTabView() {
    return (
      <VolumeTable
        params={this.props.params}
        routes={this.props.routes}
        service={this.props.service}
        volumes={this.props.service.getVolumes().getItems()} />
    );
  }

  renderInstancesTabView() {
    return (
      <ServiceTasksContainer
        params={this.props.params}
        service={this.props.service} />
    );
  }

  getActions() {
    const {service} = this.props;
    const {modalHandlers} = this.context;
    const instanceCount = service.getInstancesCount();

    const actions = [];

    actions.push({
      label: 'Edit',
      onItemSelect: modalHandlers.editService
    });

    if (instanceCount > 0) {
      actions.push({
        label: 'Restart',
        onItemSelect: modalHandlers.restartService
      });
    }

    actions.push({
      label: 'Scale',
      onItemSelect: modalHandlers.scaleService
    });

    if (instanceCount > 0) {
      actions.push({
        label: 'Suspend',
        onItemSelect: modalHandlers.suspendService
      });
    }

    actions.push({
      className: 'text-danger',
      label: 'Destroy',
      onItemSelect: modalHandlers.deleteService
    });

    return actions;
  }

  getTabs() {
    const {service:{id}} = this.props;
    const routePrefix = `/services/overview/${encodeURIComponent(id)}`;

    const tabs = [];

    tabs.push({
      label: 'Instances',
      callback: () => {
        this.setState({currentTab: 'tasks'});
      }
    });

    tabs.push({
      label: 'Configuration',
      callback: () => {
        this.setState({currentTab: 'configuration'});
      }
    });

    tabs.push({
      label: 'Debug',
      callback: () => {
        this.setState({currentTab: 'debug'});
      }
    });

    if (this.hasVolumes()) {
      tabs.push({
        label: 'Volumes', routePath: routePrefix + '/volumes',
        callback: this.tabs_handleTabClick.bind('volumes')
      });
    }

    return tabs;
  }

  render() {
    const {modals, service:{id}} = this.props;
    const breadcrumbs = <ServiceBreadcrumbs serviceID={id} />;

    return (
      <Page>
        <Page.Header actions={this.getActions()}
          tabs={this.getTabs()}
          breadcrumbs={breadcrumbs}
          iconID="services" />
        {this.tabs_getTabView()}
        {modals}
      </Page>
    );
  }
}

ServiceDetail.contextTypes = {
  modalHandlers: PropTypes.shape({
    editService: PropTypes.func,
    scaleService: PropTypes.func,
    restartService: PropTypes.func,
    suspendService: PropTypes.func,
    deleteService: PropTypes.func
  }).isRequired
};

ServiceDetail.propTypes = {
  actions: PropTypes.object.isRequired,
  params: PropTypes.object.isRequired,
  service: PropTypes.instanceOf(Service),
  modals: PropTypes.node
};

module.exports = ServiceDetail;
<|endoftext|>


<commit_before>/*!
 * jQCloud Plugin for jQuery
 *
 * Version 0.1.5
 *
 * Copyright 2011, Luca Ongaro
 * Licensed under the MIT license.
 *
 * Date: Tue Mar 1 11:09:37 +0100 2011
 */

(function( $ ){
  $.fn.jQCloud = function(word_array, callback_function) {
    // Reference to the container element
    var $this = this;
    // Reference to the ID of the container element
    var container_id = $this.attr('id');

    // Add the "jqcloud" class to the container for easy CSS styling
    $this.addClass("jqcloud");

    var drawWordCloud = function() {
      // Helper function to test if an element overlaps others
      var hitTest = function(elem, other_elems){
        // Pairwise overlap detection
        var overlapping = function(a, b){
          if (Math.abs(2.0*a.offsetLeft + a.offsetWidth - 2.0*b.offsetLeft - b.offsetWidth) < a.offsetWidth + b.offsetWidth) {
            if (Math.abs(2.0*a.offsetTop + a.offsetHeight - 2.0*b.offsetTop - b.offsetHeight) < a.offsetHeight + b.offsetHeight) {
              return true;
            }
          }
          return false;
        };
        var i = 0;
        // Check elements for overlap one by one, stop and return false as soon as an overlap is found
        for(i = 0; i < other_elems.length; i++) {
          if (overlapping(elem, other_elems[i])) {
            return true;
          }
        }
        return false;
      };

      // Sort word_array from the word with the highest weight to the one with the lowest
      word_array.sort(function(a, b) { if (a.weight  b.weight) {return -1;} else {return 0;} });

      var step = 2.0;
      var already_placed_words = [];
      var aspect_ratio = $this.width() / $this.height();
      var origin_x = $this.width() / 2.0;
      var origin_y = $this.height() / 2.0;

      // Move each word in spiral until it finds a suitable empty place
      $.each(word_array, function(index, word) {

        // Define the ID element of the span that will wrap the word, and the associated jquery selector string
        var word_id = container_id + "_word_" + index;
        var word_selector = "#" + word_id;

        var angle = 6.28 * Math.random();
        var radius = 0.0;
        // Linearly map the original weight to a discrete scale from 1 to 10
        var weight = Math.round((word.weight - word_array[word_array.length - 1].weight)/(word_array[0].weight - word_array[word_array.length - 1].weight) * 9.0) + 1;

        var inner_html = word.url !== undefined ? "" + word.text + "" : word.text;
        $this.append("" + inner_html + "");

        var width = $(word_selector).width();
        var height = $(word_selector).height();
        var left = origin_x - width / 2.0;
        var top = origin_y - height / 2.0;
        $(word_selector).css("position", "absolute");
        $(word_selector).css("left", left + "px");
        $(word_selector).css("top", top + "px");

        while(hitTest(document.getElementById(word_id), already_placed_words)) {
          radius += step;
          angle += (index % 2 === 0 ? 1 : -1)*step;

          left = origin_x + (radius*Math.cos(angle) - (width / 2.0)) * aspect_ratio;
          top = origin_y + radius*Math.sin(angle) - (height / 2.0);

          $(word_selector).css('left', left + "px");
          $(word_selector).css('top', top + "px");
        }
        already_placed_words.push(document.getElementById(word_id));
      });

      if (typeof callback_function === 'function') {
        callback_function.call(this);
      }
    };

    // Delay execution so that the browser can render the page before the computatively intensive word cloud drawing
    setTimeout(function(){drawWordCloud();}, 100);
    return this;
  };
})(jQuery);<commit_msg>bugfix: make sure typeof of word weight is a number to avoid sorting problems<commit_after>/*!
 * jQCloud Plugin for jQuery
 *
 * Version 0.1.5
 *
 * Copyright 2011, Luca Ongaro
 * Licensed under the MIT license.
 *
 * Date: Tue Mar 1 11:09:37 +0100 2011
 */

(function( $ ){
  $.fn.jQCloud = function(word_array, callback_function) {
    // Reference to the container element
    var $this = this;
    // Reference to the ID of the container element
    var container_id = $this.attr('id');

    // Add the "jqcloud" class to the container for easy CSS styling
    $this.addClass("jqcloud");

    var drawWordCloud = function() {
      // Helper function to test if an element overlaps others
      var hitTest = function(elem, other_elems){
        // Pairwise overlap detection
        var overlapping = function(a, b){
          if (Math.abs(2.0*a.offsetLeft + a.offsetWidth - 2.0*b.offsetLeft - b.offsetWidth) < a.offsetWidth + b.offsetWidth) {
            if (Math.abs(2.0*a.offsetTop + a.offsetHeight - 2.0*b.offsetTop - b.offsetHeight) < a.offsetHeight + b.offsetHeight) {
              return true;
            }
          }
          return false;
        };
        var i = 0;
        // Check elements for overlap one by one, stop and return false as soon as an overlap is found
        for(i = 0; i < other_elems.length; i++) {
          if (overlapping(elem, other_elems[i])) {
            return true;
          }
        }
        return false;
      };

      // Make sure every weight is a number before sorting
      for (i = 0; i < word_array.length; i++) {
        word_array[i].weight = parseFloat(word_array[i].weight, 10);
      }

      // Sort word_array from the word with the highest weight to the one with the lowest
      word_array.sort(function(a, b) { if (a.weight  b.weight) {return -1;} else {return 0;} });

      var step = 2.0;
      var already_placed_words = [];
      var aspect_ratio = $this.width() / $this.height();
      var origin_x = $this.width() / 2.0;
      var origin_y = $this.height() / 2.0;

      // Move each word in spiral until it finds a suitable empty place
      $.each(word_array, function(index, word) {

        // Define the ID element of the span that will wrap the word, and the associated jquery selector string
        var word_id = container_id + "_word_" + index;
        var word_selector = "#" + word_id;

        var angle = 6.28 * Math.random();
        var radius = 0.0;
        // Linearly map the original weight to a discrete scale from 1 to 10
        var weight = Math.round((word.weight - word_array[word_array.length - 1].weight)/(word_array[0].weight - word_array[word_array.length - 1].weight) * 9.0) + 1;

        var inner_html = word.url !== undefined ? "" + word.text + "" : word.text;
        $this.append("" + inner_html + "");

        var width = $(word_selector).width();
        var height = $(word_selector).height();
        var left = origin_x - width / 2.0;
        var top = origin_y - height / 2.0;
        $(word_selector).css("position", "absolute");
        $(word_selector).css("left", left + "px");
        $(word_selector).css("top", top + "px");

        while(hitTest(document.getElementById(word_id), already_placed_words)) {
          radius += step;
          angle += (index % 2 === 0 ? 1 : -1)*step;

          left = origin_x + (radius*Math.cos(angle) - (width / 2.0)) * aspect_ratio;
          top = origin_y + radius*Math.sin(angle) - (height / 2.0);

          $(word_selector).css('left', left + "px");
          $(word_selector).css('top', top + "px");
        }
        already_placed_words.push(document.getElementById(word_id));
      });

      if (typeof callback_function === 'function') {
        callback_function.call(this);
      }
    };

    // Delay execution so that the browser can render the page before the computatively intensive word cloud drawing
    setTimeout(function(){drawWordCloud();}, 100);
    return this;
  };
})(jQuery);<|endoftext|>


<commit_before>import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'
import shallowCompare from 'react-addons-shallow-compare'
import { withRouter } from 'next/router'

import { COLORS, EXPORT_SIZES } from '../lib/constants'
import Button from './Button'
import CopyButton from './CopyButton'
import WindowPointer from './WindowPointer'

const toIFrame = url =>
  `

`

class ExportMenu extends React.Component {
  state = {
    isVisible: false
  }

  shouldComponentUpdate(prevProps, prevState) {
    return (
      prevState.isVisible !== this.state.isVisible ||
      (prevState.isVisible && shallowCompare(this, prevProps, prevState))
    )
  }

  toggle = () => {
    this.setState({ isVisible: !this.state.isVisible })
  }

  handleClickOutside = () => {
    this.setState({ isVisible: false })
  }

  handleInputChange = e => {
    this.props.onChange(e.target.name, e.target.value)
  }

  handleExportSizeChange = selectedSize => () => {
    this.props.onChange('exportSize', selectedSize)
  }

  handleExport = format => () => {
    this.props.export(format)
  }

  render() {
    const { exportSize, filename, router } = this.props
    const { isVisible } = this.state

    return (

        <Button
          selected={isVisible}
          className="exportButton"
          onClick={this.toggle}
          title="Export"
          color={COLORS.PURPLE}
        />

          <WindowPointer fromRight="12px" color={COLORS.PURPLE} />

            <input
              title="filename"
              placeholder="File name..."
              value={filename}
              name="filename"
              onChange={this.handleInputChange}
            />

              Size

                {EXPORT_SIZES.map(({ name }) => (
                  <button
                    key={name}
                    onClick={this.handleExportSizeChange(name)}
                    className={`size-button ${exportSize === name ? 'selected' : ''}`}
                  >
                    {name}
                  </button>
                ))}

            <button className="open-button" onClick={this.handleExport('open')}>
              Open ↗
            </button>
            <CopyButton text={toIFrame(router.asPath)}>
              {({ copied }) => (
                <button className="copy-button">{copied ? 'Copied!' : 'Copy Embed'}</button>
              )}
            </CopyButton>

              Save as

                <button onClick={this.handleExport('png')} className="save-button">
                  PNG
                </button>
                <button onClick={this.handleExport('svg')} className="save-button">
                  SVG
                </button>

    )
  }
}

export default withRouter(enhanceWithClickOutside(ExportMenu))
<commit_msg>remove unneeded sCU<commit_after>import React from 'react'
import enhanceWithClickOutside from 'react-click-outside'
import { withRouter } from 'next/router'

import { COLORS, EXPORT_SIZES } from '../lib/constants'
import Button from './Button'
import CopyButton from './CopyButton'
import WindowPointer from './WindowPointer'

import { toggle } from '../lib/util'

const toIFrame = url =>
  `

`

class ExportMenu extends React.PureComponent {
  state = {
    isVisible: false
  }

  toggle = () => this.setState(toggle('isVisible'))

  handleClickOutside = () => this.setState({ isVisible: false })

  handleInputChange = e => this.props.onChange(e.target.name, e.target.value)

  handleExportSizeChange = selectedSize => () => this.props.onChange('exportSize', selectedSize)

  handleExport = format => () => this.props.export(format)

  render() {
    const { exportSize, filename, router } = this.props
    const { isVisible } = this.state

    return (

        <Button
          selected={isVisible}
          className="exportButton"
          onClick={this.toggle}
          title="Export"
          color={COLORS.PURPLE}
        />

          <WindowPointer fromRight="12px" color={COLORS.PURPLE} />

            <input
              title="filename"
              placeholder="File name..."
              value={filename}
              name="filename"
              onChange={this.handleInputChange}
            />

              Size

                {EXPORT_SIZES.map(({ name }) => (
                  <button
                    key={name}
                    onClick={this.handleExportSizeChange(name)}
                    className={`size-button ${exportSize === name ? 'selected' : ''}`}
                  >
                    {name}
                  </button>
                ))}

            <button className="open-button" onClick={this.handleExport('open')}>
              Open ↗
            </button>
            <CopyButton text={toIFrame(router.asPath)}>
              {({ copied }) => (
                <button className="copy-button">{copied ? 'Copied!' : 'Copy Embed'}</button>
              )}
            </CopyButton>

              Save as

                <button onClick={this.handleExport('png')} className="save-button">
                  PNG
                </button>
                <button onClick={this.handleExport('svg')} className="save-button">
                  SVG
                </button>

    )
  }
}

export default withRouter(enhanceWithClickOutside(ExportMenu))
<|endoftext|>


<commit_before>var childProcess = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
import createWaveform from './waveform-create.js';

function ffmpegPath() {
  if (os.type() === 'Darwin') {
    return path.join(__dirname, 'compiled', 'ffmpeg_mac');
  }
  if (os.type() === 'Windows_NT') {
    return path.join(__dirname, 'compiled', 'ffmpeg.exe');
  }
  if (os.type() === 'Linux') {
    return path.join(__dirname, 'compiled', 'ffmpeg_linux');
  }
  return false;
}

function ffprobePath() {
  if (os.type() === 'Darwin') {
    return path.join(__dirname, 'compiled', 'ffprobe_mac');
  }
  if (os.type() === 'Windows_NT') {
    return path.join(__dirname, 'compiled', 'ffprobe.exe');
  }
  if (os.type() === 'Linux') {
    return path.join(__dirname, 'compiled', 'ffprobe_linux');
  }
  return false;
}

function isAudioOrVideo(ffprobeResult) {
  for (var i = 0; i < ffprobeResult.streams.length; i++) {
    if (ffprobeResult.streams[i].hasOwnProperty('duration')) {
      return true;
    }
  }
  return false;
}

function durationFromFfprobe(ffprobeResult) {
  for (var i = 0; i < ffprobeResult.streams.length; i++) {
    if (ffprobeResult.streams[i].codec_type === 'audio') {
      return ffprobeResult.streams[i].duration;
    }
  }
  for (var j = 0; j < ffprobeResult.streams.length; j++) {
    if (ffprobeResult.streams[j].hasOwnProperty('duration')) {
      return ffprobeResult.streams[j].duration;
    }
  }
  return 0.0;
}

function handleUnknownFile(srcPath, destDir, handleChange,
    snackbar, loadWaveform) {
  var opts = [
    '-v',
    'quiet',
    '-print_format',
    'json',
    '-show_streams',
    srcPath
  ];
  var stdoutText = '';
  var ff = childProcess.spawn(ffprobePath(), opts);
  snackbar('investigating file...', null);
  ff.stdout.on('data', function(data) {
    stdoutText += data;
  });
  ff.on('exit', (code, signal) => {
    var ffprobeJson = {streams: []};
    var fileIsAudioVideo = false;
    var bestGuessDuration = 0.0;
    try {
      ffprobeJson = JSON.parse(stdoutText);
      fileIsAudioVideo = isAudioOrVideo(ffprobeJson);
      bestGuessDuration = durationFromFfprobe(ffprobeJson);
    } catch (ex) {
      snackbar(ex);
    }
    if (fileIsAudioVideo) {
      measureLoudness(srcPath, destDir, handleChange, snackbar, loadWaveform);
      handleChange('duration', bestGuessDuration);
    } else {
      snackbar('this does not appear to be an audio or video file.');
    }
  });
}

function measureLoudness(srcPath, destDir, handleChange,
    snackbar, loadWaveform) {
  var opts = [
    '-i',
    srcPath,
    '-af',
    'loudnorm=I=-18:TP=-1.0:LRA=9:print_format=json',
    '-f',
    'null',
    '-'
  ];
  var stderrText = '';
  var ff = childProcess.spawn(ffmpegPath(), opts);
  snackbar('measuring loudness...', null);
  ff.stderr.on('data', function(data) {
    stderrText += data;
  });
  ff.on('exit', (code, signal) => {
    console.log(stderrText);
    var jsonStartIndex = stderrText.lastIndexOf('{');
    var jsonString = stderrText.slice(jsonStartIndex);
    var measuredJson = JSON.parse(jsonString);
    secondPass(srcPath, destDir, measuredJson, handleChange,
      snackbar, loadWaveform);
  });
}

function secondPass(srcPath, destDir, loudnessInfo, handleChange,
    snackbar, loadWaveform) {
  if (!fs.existsSync(path.join(destDir, 'media'))) {
    fs.mkdirSync(path.join(destDir, 'media'));
  }
  var outPath = path.join(destDir, 'media', path.parse(srcPath).name + '.mp3');
  var afString = 'measured_I=' + loudnessInfo.input_i +
    ':measured_LRA=' + loudnessInfo.input_lra +
    ':measured_TP=' + loudnessInfo.input_tp +
    ':measured_thresh=' + loudnessInfo.input_thresh +
    ':offset=' + loudnessInfo.target_offset +
    ':linear=true:print_format=summary';
  var opts = [
    '-i',
    srcPath,
    '-af',
    'loudnorm=I=-18:TP=-1.0:LRA=9:' + afString,
    '-codec:a',
    'libmp3lame',
    '-b:a',
    '192k',
    outPath
  ];
  var stderrText = '';
  var ff = childProcess.spawn(ffmpegPath(), opts);
  snackbar('encoding to mp3...');
  ff.stderr.on('data', function(data) {
    stderrText += data;
  });
  ff.on('close', (code, signal) => {
    console.log(stderrText);
    var stats = fs.statSync(outPath);
    handleChange('fileurl', outPath);
    handleChange('filesize', stats.size);
    handleChange('filetype', 'audio/mpeg');
    createWaveform(outPath, loadWaveform);
  });
}

export default function encodeAudio(
    srcPath,
    destDir,
    handleChange,
    snackbar,
    loadWaveform) {
  handleUnknownFile(srcPath, destDir, handleChange, snackbar, loadWaveform);
}
<commit_msg>better feedback for waveform creation status<commit_after>var childProcess = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
import createWaveform from './waveform-create.js';

function ffmpegPath() {
  if (os.type() === 'Darwin') {
    return path.join(__dirname, 'compiled', 'ffmpeg_mac');
  }
  if (os.type() === 'Windows_NT') {
    return path.join(__dirname, 'compiled', 'ffmpeg.exe');
  }
  if (os.type() === 'Linux') {
    return path.join(__dirname, 'compiled', 'ffmpeg_linux');
  }
  return false;
}

function ffprobePath() {
  if (os.type() === 'Darwin') {
    return path.join(__dirname, 'compiled', 'ffprobe_mac');
  }
  if (os.type() === 'Windows_NT') {
    return path.join(__dirname, 'compiled', 'ffprobe.exe');
  }
  if (os.type() === 'Linux') {
    return path.join(__dirname, 'compiled', 'ffprobe_linux');
  }
  return false;
}

function isAudioOrVideo(ffprobeResult) {
  for (var i = 0; i < ffprobeResult.streams.length; i++) {
    if (ffprobeResult.streams[i].hasOwnProperty('duration')) {
      return true;
    }
  }
  return false;
}

function durationFromFfprobe(ffprobeResult) {
  for (var i = 0; i < ffprobeResult.streams.length; i++) {
    if (ffprobeResult.streams[i].codec_type === 'audio') {
      return ffprobeResult.streams[i].duration;
    }
  }
  for (var j = 0; j < ffprobeResult.streams.length; j++) {
    if (ffprobeResult.streams[j].hasOwnProperty('duration')) {
      return ffprobeResult.streams[j].duration;
    }
  }
  return 0.0;
}

function handleUnknownFile(srcPath, destDir, handleChange,
    snackbar, loadWaveform) {
  var opts = [
    '-v',
    'quiet',
    '-print_format',
    'json',
    '-show_streams',
    srcPath
  ];
  var stdoutText = '';
  var ff = childProcess.spawn(ffprobePath(), opts);
  snackbar('investigating file...', null);
  ff.stdout.on('data', function(data) {
    stdoutText += data;
  });
  ff.on('exit', (code, signal) => {
    var ffprobeJson = {streams: []};
    var fileIsAudioVideo = false;
    var bestGuessDuration = 0.0;
    try {
      ffprobeJson = JSON.parse(stdoutText);
      fileIsAudioVideo = isAudioOrVideo(ffprobeJson);
      bestGuessDuration = durationFromFfprobe(ffprobeJson);
    } catch (ex) {
      snackbar(ex);
    }
    if (fileIsAudioVideo) {
      measureLoudness(srcPath, destDir, handleChange, snackbar, loadWaveform);
      handleChange('duration', bestGuessDuration);
    } else {
      snackbar('this does not appear to be an audio or video file.');
    }
  });
}

function measureLoudness(srcPath, destDir, handleChange,
    snackbar, loadWaveform) {
  var opts = [
    '-i',
    srcPath,
    '-af',
    'loudnorm=I=-18:TP=-1.0:LRA=9:print_format=json',
    '-f',
    'null',
    '-'
  ];
  var stderrText = '';
  var ff = childProcess.spawn(ffmpegPath(), opts);
  snackbar('measuring loudness...', null);
  ff.stderr.on('data', function(data) {
    stderrText += data;
  });
  ff.on('exit', (code, signal) => {
    console.log(stderrText);
    var jsonStartIndex = stderrText.lastIndexOf('{');
    var jsonString = stderrText.slice(jsonStartIndex);
    var measuredJson = JSON.parse(jsonString);
    secondPass(srcPath, destDir, measuredJson, handleChange,
      snackbar, loadWaveform);
  });
}

function secondPass(srcPath, destDir, loudnessInfo, handleChange,
    snackbar, loadWaveform) {
  if (!fs.existsSync(path.join(destDir, 'media'))) {
    fs.mkdirSync(path.join(destDir, 'media'));
  }
  var outPath = path.join(destDir, 'media', path.parse(srcPath).name + '.mp3');
  var afString = 'measured_I=' + loudnessInfo.input_i +
    ':measured_LRA=' + loudnessInfo.input_lra +
    ':measured_TP=' + loudnessInfo.input_tp +
    ':measured_thresh=' + loudnessInfo.input_thresh +
    ':offset=' + loudnessInfo.target_offset +
    ':linear=true:print_format=summary';
  var opts = [
    '-i',
    srcPath,
    '-af',
    'loudnorm=I=-18:TP=-1.0:LRA=9:' + afString,
    '-codec:a',
    'libmp3lame',
    '-b:a',
    '192k',
    outPath
  ];
  var stderrText = '';
  var ff = childProcess.spawn(ffmpegPath(), opts);
  snackbar('encoding to mp3...');
  ff.stderr.on('data', function(data) {
    stderrText += data;
  });
  ff.on('close', (code, signal) => {
    console.log(stderrText);
    var stats = fs.statSync(outPath);
    handleChange('fileurl', outPath);
    handleChange('filesize', stats.size);
    handleChange('filetype', 'audio/mpeg');
    snackbar('creating waveform...');
    createWaveform(outPath, function() {
      snackbar('successfully encoded file.', 3000);
      loadWaveform();
    });
  });
}

export default function encodeAudio(
    srcPath,
    destDir,
    handleChange,
    snackbar,
    loadWaveform) {
  handleUnknownFile(srcPath, destDir, handleChange, snackbar, loadWaveform);
}
<|endoftext|>


<commit_before>/**@license
 *  sysend.js - send messages between browser windows/tabs
 *  Copyright (C) 2014 Jakub Jankiewicz <http://jcubic.pl>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  The idea for this implementation came from this StackOverflow question:
 *  http://stackoverflow.com/q/24182409/387194
 */
var sysend = (function() {
    // we use prefix so `foo' event don't collide with `foo' locaStorage value
    var uniq_prefix = '___sysend___';
    // we use id because storage event is not executed if message was not
    // changed, and we want it if user send same object twice (before it will
    // be removed)
    var id = 0;
    function get(key) {
        return localStorage.getItem(uniq_prefix + key);
    }
    function set(key, value) {
        localStorage.setItem(uniq_prefix + key, value);
    }
    function remove(key) {
        localStorage.removeItem(uniq_prefix + key);
    }
    function to_json(input) {
        var obj = [id++];
        // undefined in array get stringified as null
        if (typeof input != 'undefined') {
            obj.push(input);
        }
        return JSON.stringify(obj);
    }
    function from_json(json) {
        return JSON.parse(json);
    }
    // object with user events as keys and values arrays of callback functions
    var callbacks = {};
    window.addEventListener('storage', function(e) {
        // get user key
        var key = e.key.replace(new RegExp('^' + uniq_prefix), '');
        if (callbacks[key]) {
            var obj = JSON.parse(get(key));
            if (obj) {
                // don't call on remove
                callbacks[key].forEach(function(fn) {
                    fn(obj[1], key);
                });
            }
        }
    }, false);
    var timer;
    return {
        broadcast: function(event, message) {
            set(event, to_json(message));
            clearTimeout(timer);
            // clean up localstorage
            timer = setTimeout(function() {
                remove(event);
            }, 1000);
        },
        on: function(event, fn) {
            if (!callbacks[event]) {
                callbacks[event] = [];
            }
            callbacks[event].push(fn);
        },
        off: function(event, fn) {
            if (callbacks[event]) {
                if (fn) {
                    for (var i=callbacks[event].length; i--;) {
                        if (callbacks[event][i] == fn) {
                            callbacks[event].splice(i, 1);
                        }
                    }
                } else {
                    callbacks[event] = [];
                }
            }
        }
    };
})();
<commit_msg>remove remove from localstorage setTimeout - fix #1<commit_after>/**@license
 *  sysend.js - send messages between browser windows/tabs
 *  Copyright (C) 2014 Jakub Jankiewicz <http://jcubic.pl>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  The idea for this implementation came from this StackOverflow question:
 *  http://stackoverflow.com/q/24182409/387194
 */
var sysend = (function() {
    // we use prefix so `foo' event don't collide with `foo' locaStorage value
    var uniq_prefix = '___sysend___';
    // we use id because storage event is not executed if message was not
    // changed, and we want it if user send same object twice (before it will
    // be removed)
    var id = 0;
    function get(key) {
        return localStorage.getItem(uniq_prefix + key);
    }
    function set(key, value) {
        localStorage.setItem(uniq_prefix + key, value);
    }
    function remove(key) {
        localStorage.removeItem(uniq_prefix + key);
    }
    function to_json(input) {
        var obj = [id++];
        // undefined in array get stringified as null
        if (typeof input != 'undefined') {
            obj.push(input);
        }
        return JSON.stringify(obj);
    }
    function from_json(json) {
        return JSON.parse(json);
    }
    // object with user events as keys and values arrays of callback functions
    var callbacks = {};
    window.addEventListener('storage', function(e) {
        // get user key
        var key = e.key.replace(new RegExp('^' + uniq_prefix), '');
        if (callbacks[key]) {
            var obj = JSON.parse(get(key));
            if (obj) {
                // don't call on remove
                callbacks[key].forEach(function(fn) {
                    fn(obj[1], key);
                });
            }
        }
    }, false);
    return {
        broadcast: function(event, message) {
            set(event, to_json(message));
            // clean up localstorage
            remove(event);
        },
        on: function(event, fn) {
            if (!callbacks[event]) {
                callbacks[event] = [];
            }
            callbacks[event].push(fn);
        },
        off: function(event, fn) {
            if (callbacks[event]) {
                if (fn) {
                    for (var i=callbacks[event].length; i--;) {
                        if (callbacks[event][i] == fn) {
                            callbacks[event].splice(i, 1);
                        }
                    }
                } else {
                    callbacks[event] = [];
                }
            }
        }
    };
})();
<|endoftext|>


<commit_before>var h = 263,
		s = 60,
		b = 50,
		a = 10;

var h2,
		a2Start = 71,
		a2 = a2Start;

var h3 = 360,
		s3 = 10,
		b3 = 10,
		a3 = 2,
		a3Wipe = 40;

// vars for line
var eX, eY, // position
		eX2, eY2,
		eW = 2; // width

// for bounces on wall
var bounces = 0,
		bouncesMax,
		bouncesTotal = 0; // current total amount of bounces

// for conversion from polar to cartesian coordinates.
// basically getting x and y from an angle and a radius.
// angle: 0 to 360 ... duh
var angle,
		radius ; // sets the speed

var quadrant;

var wall;	// which wall? t,r,b,l?

// for Dot
var dot = [];

// for filling whole document
var w = window,
		wX = w.innerWidth,
		wY = w.innerHeight;

/*
* only executed once
*/
function setup(){
	createCanvas(wX, wY);
	// createCanvas(1600/2, 900/2);

	// change color mode to hsl
	colorMode(HSL, 360, 100, 100, 100);

	// start line at...
	eX = random(0,width);
	eY = 0;
	angle = radians(random(0,180));
	radius = 8;
	bouncesMax = 7;

	// rectangle/background
	background(h3, s3, b3);
}

/*
* this will be executed all the time
*/
function draw(){
	// translate from angle: polar to cartesian coordianates
	eX += cartesianX(radius,angle);
	eY += cartesianY(radius,angle);

	// DRAW LINE
	stroke(360,100,100,5);
	// stroke(h,s,b,a);
	strokeWeight(eW);
	line(eX,eY, eX2,eY2);

	// quadrants:
	// 1: 0° - 90°
	// 2: 90° - 180°
	// 3: 180° - 270°
	// 4: 270° - 360°
	if (angle >= radians(0) && angle < radians(90)) {
		quadrant = 1;
	}
	else if (angle >= radians(90) && angle < radians(180)) {
		quadrant = 2;
	}
	else if (angle >= radians(180) && angle < radians(270)) {
		quadrant = 3;
	}
	else if (angle >= radians(270) && angle < radians(360)) {
		quadrant = 4;
	}

	// wall sides
	if (eY < 0) {
		wall = 1;
	}
	else if (eX > width) {
		wall = 2;
	}
	else if (eY > height) {
		wall = 3;
	}
	else if (eX < 0) {
		wall = 4;
	}

	// if bounce from specific wall from specific angle
	// 0° - 90°
	if (quadrant === 1 && wall === 2) { // right
		angle += radians(90);
		bounces++;
		eX = width;
	}
	else if (quadrant === 1 && wall === 3) { // bottom
		angle -= radians(90);
		bounces++;
		eY = height;
	}
	// 90° - 180°
	else if (quadrant === 2 && wall === 3) { // bottom
		angle += radians(90);
		bounces++;
		eY = height;
	}
	else if (quadrant === 2 && wall === 4) { // left
		angle -= radians(90);
		bounces++;
		eX = 0;
	}
	// 180° - 270°
	else if (quadrant === 3 && wall === 4) { // left
		angle += radians(90);
		bounces++;
		eX = 0;
	}
	else if (quadrant === 3 && wall === 1) { // top
		angle -= radians(90);
		bounces++;
		eY = 0;
	}
	// 270° - 360°
	else if (quadrant === 4 && wall === 1) { // top
		angle += radians(90);
		bounces++;
		eY = 0;
	}
	else if (quadrant === 4 && wall === 2) { // right
		angle -= radians(90);
		bounces++;
		eX = width;
	}

	// stay in 360°
	if (angle >= radians(360)) {
		angle -= radians(360);
	}
	else if (angle < radians(0)) {
		angle += radians(360);
	}

	// if specific amount of bouncing, reset position
	if (bounces > bouncesMax) {
		noStroke();
		eX = random(0,width);
		eY = 0;
		angle = radians(random(0,180));
		bounces = 0; // reset bounces counter
	}
	// if at wall-bounce, add thing
	else if (eX === width || eY === height || eX === 0 || eY === 0) {
		h2 = random(0,360);

		// create new Dot at wall
		dot[bouncesTotal] = new Dot();

		a2 = a2Start;

		// draw triangle, start at third bounce
		if (bouncesTotal >= 2) {
			stroke(360,100,100,10);
			fill(360,100,100,5);
			triangle(
				dot[bouncesTotal].x,dot[bouncesTotal].y,
				dot[bouncesTotal-1].x,dot[bouncesTotal-1].y,
				dot[bouncesTotal-2].x,dot[bouncesTotal-2].y
			);
		}

		dot[bouncesTotal].show();

		bouncesTotal++;
	}
	// fadeOut effect
	// fill(h3,s3,b3,a3);
	// rect(0,0, width, height);

	// get last coordinate for drawing a line
	eX2 = eX;
	eY2 = eY;

	// console.log(bouncesTotal);
}

/*
* custom functions
*/
// create cartesian coordinates
function cartesianX(radius,angle) {
	var x = radius*cos(angle);

	return x;
}

function cartesianY(radius,angle) {
	var y = radius*sin(angle);

	return y;
}

/*
* Class Dot
*/
// Dot constructor
var Dot = function() {
	this.x = eX;
	this.y = eY;
	this.width = eW;
	this.color = color(12,4,23,100);
	// this.color = color(h2,50,50,50);
};

// show method
Dot.prototype.show = function() {
	noStroke();
	fill(this.color);
	ellipse(this.x,this.y, this.width*10,this.width*10);
};<commit_msg>new colors<commit_after>var h = 263,
		s = 60,
		b = 50,
		a = 10;

var h2 = 12,
		s2 = 4,
		b2 = 23,
		a2 = 100;

var h3 = 360,
		s3 = 10,
		b3 = 90,
		a3 = 2,
		a3Wipe = 40;

// vars for line
var eX, eY, // position
		eX2, eY2,
		eW = 2; // width

// for bounces on wall
var bounces = 0,
		bouncesMax,
		bouncesTotal = 0; // current total amount of bounces

// for conversion from polar to cartesian coordinates.
// basically getting x and y from an angle and a radius.
// angle: 0 to 360 ... duh
var angle,
		radius ; // sets the speed

var quadrant;

var wall;	// which wall? t,r,b,l?

// for Dot
var dot = [];

// for filling whole document
var w = window,
		wX = w.innerWidth,
		wY = w.innerHeight;

/*
* only executed once
*/
function setup(){
	createCanvas(wX, wY);
	// createCanvas(1600/2, 900/2);

	// change color mode to hsl
	colorMode(HSL, 360, 100, 100, 100);

	// start line at...
	eX = random(0,width);
	eY = 0;
	angle = radians(random(0,180));
	radius = 8;
	bouncesMax = 7;

	// rectangle/background
	background(h3, s3, b3);
}

/*
* this will be executed all the time
*/
function draw(){
	// translate from angle: polar to cartesian coordianates
	eX += cartesianX(radius,angle);
	eY += cartesianY(radius,angle);

	// DRAW LINE
	stroke(h2,s2,b2,5);
	// stroke(h,s,b,a);
	strokeWeight(eW);
	line(eX,eY, eX2,eY2);

	// quadrants:
	// 1: 0° - 90°
	// 2: 90° - 180°
	// 3: 180° - 270°
	// 4: 270° - 360°
	if (angle >= radians(0) && angle < radians(90)) {
		quadrant = 1;
	}
	else if (angle >= radians(90) && angle < radians(180)) {
		quadrant = 2;
	}
	else if (angle >= radians(180) && angle < radians(270)) {
		quadrant = 3;
	}
	else if (angle >= radians(270) && angle < radians(360)) {
		quadrant = 4;
	}

	// wall sides
	if (eY < 0) {
		wall = 1;
	}
	else if (eX > width) {
		wall = 2;
	}
	else if (eY > height) {
		wall = 3;
	}
	else if (eX < 0) {
		wall = 4;
	}

	// if bounce from specific wall from specific angle
	// 0° - 90°
	if (quadrant === 1 && wall === 2) { // right
		angle += radians(90);
		bounces++;
		eX = width;
	}
	else if (quadrant === 1 && wall === 3) { // bottom
		angle -= radians(90);
		bounces++;
		eY = height;
	}
	// 90° - 180°
	else if (quadrant === 2 && wall === 3) { // bottom
		angle += radians(90);
		bounces++;
		eY = height;
	}
	else if (quadrant === 2 && wall === 4) { // left
		angle -= radians(90);
		bounces++;
		eX = 0;
	}
	// 180° - 270°
	else if (quadrant === 3 && wall === 4) { // left
		angle += radians(90);
		bounces++;
		eX = 0;
	}
	else if (quadrant === 3 && wall === 1) { // top
		angle -= radians(90);
		bounces++;
		eY = 0;
	}
	// 270° - 360°
	else if (quadrant === 4 && wall === 1) { // top
		angle += radians(90);
		bounces++;
		eY = 0;
	}
	else if (quadrant === 4 && wall === 2) { // right
		angle -= radians(90);
		bounces++;
		eX = width;
	}

	// stay in 360°
	if (angle >= radians(360)) {
		angle -= radians(360);
	}
	else if (angle < radians(0)) {
		angle += radians(360);
	}

	// if specific amount of bouncing, reset position
	if (bounces > bouncesMax) {
		noStroke();
		eX = random(0,width);
		eY = 0;
		angle = radians(random(0,180));
		bounces = 0; // reset bounces counter
	}
	// if at wall-bounce, add thing
	else if (eX === width || eY === height || eX === 0 || eY === 0) {

		// create new Dot at wall
		dot[bouncesTotal] = new Dot();

		// draw triangle, start at third bounce
		if (bouncesTotal >= 2) {
			stroke(360,100,100,10);
			// noStroke();
			fill(h2,s2,b2,10);
			triangle(
				dot[bouncesTotal].x,dot[bouncesTotal].y,
				dot[bouncesTotal-1].x,dot[bouncesTotal-1].y,
				dot[bouncesTotal-2].x,dot[bouncesTotal-2].y
			);

		// dot[bouncesTotal].show();
		// dot[bouncesTotal-1].show();
		// dot[bouncesTotal-2].show();

		}

		bouncesTotal++;
	}
	// fadeOut effect
	// fill(h3,s3,b3,1);
	// rect(0,0, width, height);

	// get last coordinate for drawing a line
	eX2 = eX;
	eY2 = eY;

	// console.log(bouncesTotal);
}

/*
* custom functions
*/
// create cartesian coordinates
function cartesianX(radius,angle) {
	var x = radius*cos(angle);

	return x;
}

function cartesianY(radius,angle) {
	var y = radius*sin(angle);

	return y;
}

/*
* Class Dot
*/
// Dot constructor
var Dot = function() {
	this.x = eX;
	this.y = eY;
	this.width = eW;
	this.color = color(h2,s2,b2,a2);
	// this.color = color(h2,50,50,50);
};

// show method
Dot.prototype.show = function() {
	noStroke();
	fill(this.color);
	ellipse(this.x,this.y, this.width*10,this.width*10);
};<|endoftext|>