<commit_before>#!/usr/bin/env node
require('babel-register');

/**
* NPM dependencies
**/
import options from 'eslint/lib/options';

/**
* Local dependencies
**/
import Linter from './linter';
import { formatTotal } from './formatter';

function translateOptions(cliOptions) {
  return {
    envs: cliOptions.env,
    extensions: cliOptions.ext,
    rules: cliOptions.rule,
    plugins: cliOptions.plugin,
    globals: cliOptions.global,
    ignore: cliOptions.ignore,
    ignorePath: cliOptions.ignorePath,
    ignorePattern: cliOptions.ignorePattern,
    configFile: cliOptions.config,
    rulePaths: cliOptions.rulesdir,
    useEslintrc: cliOptions.eslintrc,
    parser: cliOptions.parser,
    parserOptions: cliOptions.parserOptions,
    cache: cliOptions.cache,
    cacheFile: cliOptions.cacheFile,
    cacheLocation: cliOptions.cacheLocation,
    fix: cliOptions.fix,
    allowInlineConfig: cliOptions.inlineConfig
  };
}

const cliOptions = options.parse(process.argv);

if (cliOptions.version) {
  console.log(`v${require("../package.json").version}`);
} else if (cliOptions.help) {
  console.log(options.generateHelp());
} else {
  new Linter(translateOptions(cliOptions)).execute(cliOptions._).then(
    (result) => {
      const failed = result.errorCount > 1 || result.warningCount > 1;

      if (failed) {
        console.log(formatTotal(result));
        process.exit(1);
      } else {
        process.exit(0);
      }
    },
    (err) => {
      console.log(err);
      process.exit(1);
    }
  );
}
<commit_msg>testing<commit_after>#!/usr/bin/env node
require('babel-register');

/**
* NPM dependencies
**/
import options from 'eslint/lib/options';

/**
* Local dependencies
**/
import Linter from './linter';
import { formatTotal } from './formatte

function translateOptions(cliOptions) {
  return {
    envs: cliOptions.env,
    extensions: cliOptions.ext,
    rules: cliOptions.rule,
    plugins: cliOptions.plugin,
    globals: cliOptions.global,
    ignore: cliOptions.ignore,
    ignorePath: cliOptions.ignorePath,
    ignorePattern: cliOptions.ignorePattern,
    configFile: cliOptions.config,
    rulePaths: cliOptions.rulesdir,
    useEslintrc: cliOptions.eslintrc,
    parser: cliOptions.parser,
    parserOptions: cliOptions.parserOptions,
    cache: cliOptions.cache,
    cacheFile: cliOptions.cacheFile,
    cacheLocation: cliOptions.cacheLocation,
    fix: cliOptions.fix,
    allowInlineConfig: cliOptions.inlineConfig
  };
}

const cliOptions = options.parse(process.argv);

if (cliOptions.version) {
  console.log(`v${require("../package.json").version}`);
} else if (cliOptions.help) {
  console.log(options.generateHelp());
} else {
  new Linter(translateOptions(cliOptions)).execute(cliOptions._).then(
    (result) => {
      const failed = result.errorCount > 1 || result.warningCount > 1;

      if (failed) {
        console.log(formatTotal(result));
        process.exit(1);
      } else {
        process.exit(0);
      }
    },
    (err) => {
      console.log(err);
      process.exit(1);
    }
  );
}
<|endoftext|>


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

'use strict';

var exporter = require('./index');
var program = require('commander');
var pkgInfo = require('../package.json');

program
    .version(pkgInfo.version)
    .option('-i, --input <file>', 'Input file')
    .option('-o, --output [file]', 'Output file', 'lib.js')
    .option('-e, --exports <path>', 'Exported path from GWT')
    .option('-p, --package [file]', 'Take information from a package.json file')
    .parse(process.argv);

exporter(program).catch(function (e) {
    console.error(e.message);
    process.exit(1);
});
<commit_msg>cli : log path of output file if success<commit_after>#!/usr/bin/env node

'use strict';

var exporter = require('./index');
var program = require('commander');
var pkgInfo = require('../package.json');

program
    .version(pkgInfo.version)
    .option('-i, --input <file>', 'Input file')
    .option('-o, --output [file]', 'Output file', 'lib.js')
    .option('-e, --exports <path>', 'Exported path from GWT')
    .option('-p, --package [file]', 'Take information from a package.json file')
    .parse(process.argv);

exporter(program).then(function () {
    console.log(require('path').resolve(program.output) + ' written');
}, function (e) {
    console.error(e.message);
    process.exit(1);
});
<|endoftext|>


<commit_before>import canvasModule from 'canvas';
import measureBlur from './measureBlur.js';

if (process.argv.length < 3) {
  console.info('Usage: node measureBlur.js path/to/image/file.jpg');
  process.exit(0);
}

const { createCanvas, loadImage } = canvasModule;
const image = await loadImage(process.argv[2]);
const canvas = createCanvas(image.width, image.height);
const context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
const stats = measureBlur(
  context.getImageData(0, 0, canvas.width, canvas.height)
);

console.log('Blur score:', Number(stats.avg_edge_width_perc.toFixed(2)));
console.log(stats);
<commit_msg>fix filename cli.js<commit_after>import canvasModule from 'canvas';
import measureBlur from './measureBlur.js';

if (process.argv.length < 3) {
  console.info('Usage: node cli.js path/to/image/file.jpg');
  process.exit(0);
}

const { createCanvas, loadImage } = canvasModule;
const image = await loadImage(process.argv[2]);
const canvas = createCanvas(image.width, image.height);
const context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
const stats = measureBlur(
  context.getImageData(0, 0, canvas.width, canvas.height)
);

console.log('Blur score:', Number(stats.avg_edge_width_perc.toFixed(2)));
console.log(stats);
<|endoftext|>


<commit_before>#!/usr/bin/env node
var path = require('path')
var express = require('express')
var app = express()
var dafuq = require('./')

var argv = require('yargs')
    .usage('$0 Leverages command-based api')
    .describe('commands', 'the path to commands directory')
    .alias('commands', 'c')
    .alias('commands', 'path')
    .alias('commands', 'directory')
    .demand('commands')
    .describe('shebang', 'the interpreter to use when running the command files')
    .default('shebang', '')
    .describe('port', 'the port where to listen for api call')
    .alias('port', 'p')
    .default('port', 3000)
    .help('help')
    .alias('help', 'h')
    .argv;

// Resolve full path when executing via CLI
if (require.main === module)
    argv.commands = path.resolve(process.pwd(), argv.commands)

app.use(dafuq({
    path: argv.commands,
    shebang: argv.shebang
}))
app.listen(argv.port)
<commit_msg>Add debug flag to cli dafuq<commit_after>#!/usr/bin/env node
var path = require('path')
var express = require('express')
var app = express()
var dafuq = require('./')

var argv = require('yargs')
    .usage('$0 Leverages a command-based api')
    .describe('commands', 'the path to commands directory')
    // commands
    .alias('commands', 'c')
    .alias('commands', 'path')
    .alias('commands', 'directory')
    .demand('commands')
    // shebang
    .describe('shebang', 'the interpreter to use when running the command files')
    .default('shebang', '')
    // port
    .describe('port', 'the port where to listen for api call')
    .alias('port', 'p')
    .default('port', 3000)
    // debug
    .describe('debug', 'show debug and trace output when running')
    .boolean('debug')
    .alias('debug', 'd')
    .default('debug', false)
    // help
    .help('help')
    .alias('help', 'h')
    .argv;

// Resolve full path when executing via CLI
if (require.main === module)
    argv.commands = path.resolve(process.pwd(), argv.commands)

app.use(dafuq({
    path: argv.commands,
    shebang: argv.shebang
}))
app.listen(argv.port)
<|endoftext|>


<commit_before>import optimist from 'optimist';
import checkDirectory from './index';
import fs from 'fs';
import path from 'path';

function run(absolutePath, argv, log, exit) {
  checkDirectory(absolutePath, {
    'withoutDev': !argv.dev,
    'ignoreMatches': (argv.ignores || '').split(','),
  }, unused => {
    if (argv.json) {
      log(JSON.stringify(unused));
      return exit(0);
    }

    if (unused.dependencies.length === 0 && unused.devDependencies.length === 0) {
      log('No unused dependencies');
      exit(0);
    } else {
      if (unused.dependencies.length !== 0) {
        log('Unused Dependencies');
        unused.dependencies.forEach(u => {
          log('* ' + u);
        });
      }
      if (unused.devDependencies.length !== 0) {
        log();
        log('Unused devDependencies');
        unused.devDependencies.forEach(u => {
          log('* ' + u);
        });
      }
      exit(-1);
    }
  });
}

export default function cli(args, log, error, exit) {
  const opt = optimist(args)
    .usage('Usage: $0 [DIRECTORY]')
    .boolean('dev')
    .default('dev', true)
    .describe('no-dev', 'Don\'t look at devDependecies')
    .describe('json', 'Output results to JSON')
    .describe('ignores', 'Comma separated package list to ignore')
    .describe('help', 'Show this help message');

  const argv = opt.argv;

  if (argv.help) {
    log(opt.help());
    exit(0);
  }

  const dir = argv._[0] || '.';
  const absolutePath = path.resolve(dir);

  fs.exists(absolutePath, pathExists => {
    if (pathExists) {
      fs.exists(absolutePath + path.sep + 'package.json', exists => {
        if (exists) {
          run(absolutePath, argv, log, exit);
        } else {
          error('Path ' + dir + ' does not contain a package.json file');
          log(opt.help());
          exit(-1);
        }
      });
    } else {
      error('Path ' + dir + ' does not exist');
      exit(-1);
    }
  });
}
<commit_msg>Quick fix to a code flaw in unit test.<commit_after>import optimist from 'optimist';
import checkDirectory from './index';
import fs from 'fs';
import path from 'path';

function run(absolutePath, argv, log, exit) {
  checkDirectory(absolutePath, {
    'withoutDev': !argv.dev,
    'ignoreMatches': (argv.ignores || '').split(','),
  }, unused => {
    if (argv.json) {
      log(JSON.stringify(unused));
      return exit(0);
    }

    if (unused.dependencies.length === 0 && unused.devDependencies.length === 0) {
      log('No unused dependencies');
      exit(0);
    } else {
      if (unused.dependencies.length !== 0) {
        log('Unused Dependencies');
        unused.dependencies.forEach(u => {
          log('* ' + u);
        });
      }
      if (unused.devDependencies.length !== 0) {
        log();
        log('Unused devDependencies');
        unused.devDependencies.forEach(u => {
          log('* ' + u);
        });
      }
      exit(-1);
    }
  });
}

export default function cli(args, log, error, exit) {
  const opt = optimist(args)
    .usage('Usage: $0 [DIRECTORY]')
    .boolean('dev')
    .default('dev', true)
    .describe('no-dev', 'Don\'t look at devDependecies')
    .describe('json', 'Output results to JSON')
    .describe('ignores', 'Comma separated package list to ignore')
    .describe('help', 'Show this help message');

  const argv = opt.argv;

  if (argv.help) {
    log(opt.help());
    exit(0);
    return; // HACK to not execute the following code in test
  }

  const dir = argv._[0] || '.';
  const absolutePath = path.resolve(dir);

  fs.exists(absolutePath, pathExists => {
    if (pathExists) {
      fs.exists(absolutePath + path.sep + 'package.json', exists => {
        if (exists) {
          run(absolutePath, argv, log, exit);
        } else {
          error('Path ' + dir + ' does not contain a package.json file');
          log(opt.help());
          exit(-1);
        }
      });
    } else {
      error('Path ' + dir + ' does not exist');
      exit(-1);
    }
  });
}
<|endoftext|>


<commit_before>
/*
determines if eventInstanceGroup is allowed,
in relation to other EVENTS and business hours.
*/
Calendar.prototype.isEventInstanceGroupAllowed = function(eventInstanceGroup) {
	var eventDef = eventInstanceGroup.getEventDef();
	var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
	var i;

	var peerEventInstances = this.getPeerEventInstances(eventDef);
	var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
	var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);

	var constraintVal = eventDef.getConstraint();
	var overlapVal = eventDef.getOverlap();

	var eventAllowFunc = this.opt('eventAllow');

	for (i = 0; i < eventFootprints.length; i++) {
		if (
			!this.isFootprintAllowed(
				eventFootprints[i].componentFootprint,
				peerEventFootprints,
				constraintVal,
				overlapVal,
				eventFootprints[i].eventInstance
			)
		) {
			return false;
		}
	}

	if (eventAllowFunc) {
		for (i = 0; i < eventFootprints.length; i++) {
			if (
				eventAllowFunc(
					eventFootprints[i].componentFootprint.toLegacy(this),
					eventFootprints[i].getEventLegacy()
				) === false
			) {
				return false;
			}
		}
	}

	return true;
};

Calendar.prototype.getPeerEventInstances = function(eventDef) {
	return this.eventManager.getEventInstancesWithoutId(eventDef.id);
};

Calendar.prototype.isSelectionFootprintAllowed = function(componentFootprint) {
	var peerEventInstances = this.eventManager.getEventInstances();
	var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
	var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);

	var selectAllowFunc;

	if (
		this.isFootprintAllowed(
			componentFootprint,
			peerEventFootprints,
			this.opt('selectConstraint'),
			this.opt('selectOverlap')
		)
	) {
		selectAllowFunc = this.opt('selectAllow');

		if (selectAllowFunc) {
			return selectAllowFunc(componentFootprint.toLegacy(this)) !== false;
		}
		else {
			return true;
		}
	}

	return false;
};

Calendar.prototype.isFootprintAllowed = function(
	componentFootprint,
	peerEventFootprints,
	constraintVal,
	overlapVal,
	subjectEventInstance // optional
) {
	var constraintFootprints; // ComponentFootprint[]
	var overlapEventFootprints; // EventFootprint[]

	if (constraintVal != null) {
		constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay);

		if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) {
			return false;
		}
	}

	overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint);

	if (overlapVal === false) {
		if (overlapEventFootprints.length) {
			return false;
		}
	}
	else if (typeof overlapVal === 'function') {
		if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) {
			return false;
		}
	}

	if (subjectEventInstance) {
		if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) {
			return false;
		}
	}

	return true;
};

// Constraint
// ------------------------------------------------------------------------------------------------

Calendar.prototype.isFootprintWithinConstraints = function(componentFootprint, constraintFootprints) {
	var i;

	for (i = 0; i < constraintFootprints.length; i++) {
		if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) {
			return true;
		}
	}

	return false;
};

Calendar.prototype.constraintValToFootprints = function(constraintVal, isAllDay) {
	var eventInstances;

	if (constraintVal === 'businessHours') {
		return this.buildCurrentBusinessFootprints(isAllDay);
	}
	else if (typeof constraintVal === 'object') {
		eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events

		if (!eventInstances) { // invalid input. fallback to parsing footprint directly
			return this.parseFootprints(constraintVal);
		}
		else {
			return this.eventInstancesToFootprints(eventInstances);
		}
	}
	else if (constraintVal != null) { // an ID
		eventInstances = this.eventManager.getEventInstancesWithId(constraintVal);

		return this.eventInstancesToFootprints(eventInstances);
	}
};

// returns ComponentFootprint[]
// uses current view's range
Calendar.prototype.buildCurrentBusinessFootprints = function(isAllDay) {
	var view = this.view;
	var businessHourGenerator = view.get('businessHourGenerator');
	var unzonedRange = view.dateProfile.activeUnzonedRange;
	var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange);

	if (eventInstanceGroup) {
		return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances);
	}
	else {
		return [];
	}
};

// conversion util
Calendar.prototype.eventInstancesToFootprints = function(eventInstances) {
	var eventRanges = eventInstances.map(eventInstanceToEventRange);
	var eventFootprints = this.eventRangesToEventFootprints(eventRanges);

	return eventFootprints.map(eventFootprintToComponentFootprint);
};

// Overlap
// ------------------------------------------------------------------------------------------------

Calendar.prototype.collectOverlapEventFootprints = function(peerEventFootprints, targetFootprint) {
	var overlapEventFootprints = [];
	var i;

	for (i = 0; i < peerEventFootprints.length; i++) {
		if (
			this.footprintsIntersect(
				targetFootprint,
				peerEventFootprints[i].componentFootprint
			)
		) {
			overlapEventFootprints.push(peerEventFootprints[i]);
		}
	}

	return overlapEventFootprints;
};

// optional subjectEventInstance
function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) {
	var i;

	for (i = 0; i < overlapEventFootprints.length; i++) {
		if (
			!overlapFunc(
				overlapEventFootprints[i].eventInstance.toLegacy(),
				subjectEventInstance ? subjectEventInstance.toLegacy() : null
			)
		) {
			return false;
		}
	}

	return true;
}

function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) {
	var subjectLegacyInstance = subjectEventInstance.toLegacy();
	var i;
	var overlapEventInstance;
	var overlapEventDef;
	var overlapVal;

	for (i = 0; i < overlapEventFootprints.length; i++) {
		overlapEventInstance = overlapEventFootprints[i].eventInstance;
		overlapEventDef = overlapEventInstance.def;

		// don't need to pass in calendar, because don't want to consider global eventOverlap property,
		// because we already considered that earlier in the process.
		overlapVal = overlapEventDef.getOverlap();

		if (overlapVal === false) {
			return false;
		}
		else if (typeof overlapVal === 'function') {
			if (
				!overlapVal(
					overlapEventInstance.toLegacy(),
					subjectLegacyInstance
				)
			) {
				return false;
			}
		}
	}

	return true;
}

// Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints
// ------------------------------------------------------------------------------------------------
// NOTE: this might seem like repetitive code with the Grid class, however, this code is related to
// constraints whereas the Grid code is related to rendering. Each approach might want to convert
// eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make
// this more DRY.

/*
Returns false on invalid input.
*/
Calendar.prototype.parseEventDefToInstances = function(eventInput) {
	var eventPeriod = this.eventManager.currentPeriod;
	var eventDef = EventDefParser.parse(eventInput, new EventSource(this));

	if (!eventDef) { // invalid
		return false;
	}

	if (eventPeriod) {
		return eventDef.buildInstances(eventPeriod.unzonedRange);
	}
	else {
		return [];
	}
};

Calendar.prototype.eventRangesToEventFootprints = function(eventRanges) {
	var i;
	var eventFootprints = [];

	for (i = 0; i < eventRanges.length; i++) {
		eventFootprints.push(
			eventRangeToEventFootprint(eventRanges[i])
		);
	}

	return eventFootprints;
};

/*
Parses footprints directly.
Very similar to EventDateProfile::parse :(
*/
Calendar.prototype.parseFootprints = function(rawInput) {
	var start, end;

	if (rawInput.start) {
		start = this.moment(rawInput.start);

		if (!start.isValid()) {
			start = null;
		}
	}

	if (rawInput.end) {
		end = this.moment(rawInput.end);

		if (!end.isValid()) {
			end = null;
		}
	}

	return [
		new ComponentFootprint(
			new UnzonedRange(start, end),
			(start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay
		)
	];
};

// Footprint Utils
// ----------------------------------------------------------------------------------------

Calendar.prototype.footprintContainsFootprint = function(outerFootprint, innerFootprint) {
	return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange);
};

Calendar.prototype.footprintsIntersect = function(footprint0, footprint1) {
	return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange);
};
<commit_msg>revive Calendar::eventRangeToEventFootprints for constraint testing<commit_after>
/*
determines if eventInstanceGroup is allowed,
in relation to other EVENTS and business hours.
*/
Calendar.prototype.isEventInstanceGroupAllowed = function(eventInstanceGroup) {
	var eventDef = eventInstanceGroup.getEventDef();
	var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
	var i;

	var peerEventInstances = this.getPeerEventInstances(eventDef);
	var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
	var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);

	var constraintVal = eventDef.getConstraint();
	var overlapVal = eventDef.getOverlap();

	var eventAllowFunc = this.opt('eventAllow');

	for (i = 0; i < eventFootprints.length; i++) {
		if (
			!this.isFootprintAllowed(
				eventFootprints[i].componentFootprint,
				peerEventFootprints,
				constraintVal,
				overlapVal,
				eventFootprints[i].eventInstance
			)
		) {
			return false;
		}
	}

	if (eventAllowFunc) {
		for (i = 0; i < eventFootprints.length; i++) {
			if (
				eventAllowFunc(
					eventFootprints[i].componentFootprint.toLegacy(this),
					eventFootprints[i].getEventLegacy()
				) === false
			) {
				return false;
			}
		}
	}

	return true;
};

Calendar.prototype.getPeerEventInstances = function(eventDef) {
	return this.eventManager.getEventInstancesWithoutId(eventDef.id);
};

Calendar.prototype.isSelectionFootprintAllowed = function(componentFootprint) {
	var peerEventInstances = this.eventManager.getEventInstances();
	var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
	var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);

	var selectAllowFunc;

	if (
		this.isFootprintAllowed(
			componentFootprint,
			peerEventFootprints,
			this.opt('selectConstraint'),
			this.opt('selectOverlap')
		)
	) {
		selectAllowFunc = this.opt('selectAllow');

		if (selectAllowFunc) {
			return selectAllowFunc(componentFootprint.toLegacy(this)) !== false;
		}
		else {
			return true;
		}
	}

	return false;
};

Calendar.prototype.isFootprintAllowed = function(
	componentFootprint,
	peerEventFootprints,
	constraintVal,
	overlapVal,
	subjectEventInstance // optional
) {
	var constraintFootprints; // ComponentFootprint[]
	var overlapEventFootprints; // EventFootprint[]

	if (constraintVal != null) {
		constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay);

		if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) {
			return false;
		}
	}

	overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint);

	if (overlapVal === false) {
		if (overlapEventFootprints.length) {
			return false;
		}
	}
	else if (typeof overlapVal === 'function') {
		if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) {
			return false;
		}
	}

	if (subjectEventInstance) {
		if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) {
			return false;
		}
	}

	return true;
};

// Constraint
// ------------------------------------------------------------------------------------------------

Calendar.prototype.isFootprintWithinConstraints = function(componentFootprint, constraintFootprints) {
	var i;

	for (i = 0; i < constraintFootprints.length; i++) {
		if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) {
			return true;
		}
	}

	return false;
};

Calendar.prototype.constraintValToFootprints = function(constraintVal, isAllDay) {
	var eventInstances;

	if (constraintVal === 'businessHours') {
		return this.buildCurrentBusinessFootprints(isAllDay);
	}
	else if (typeof constraintVal === 'object') {
		eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events

		if (!eventInstances) { // invalid input. fallback to parsing footprint directly
			return this.parseFootprints(constraintVal);
		}
		else {
			return this.eventInstancesToFootprints(eventInstances);
		}
	}
	else if (constraintVal != null) { // an ID
		eventInstances = this.eventManager.getEventInstancesWithId(constraintVal);

		return this.eventInstancesToFootprints(eventInstances);
	}
};

// returns ComponentFootprint[]
// uses current view's range
Calendar.prototype.buildCurrentBusinessFootprints = function(isAllDay) {
	var view = this.view;
	var businessHourGenerator = view.get('businessHourGenerator');
	var unzonedRange = view.dateProfile.activeUnzonedRange;
	var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange);

	if (eventInstanceGroup) {
		return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances);
	}
	else {
		return [];
	}
};

// conversion util
Calendar.prototype.eventInstancesToFootprints = function(eventInstances) {
	var eventRanges = eventInstances.map(eventInstanceToEventRange);
	var eventFootprints = this.eventRangesToEventFootprints(eventRanges);

	return eventFootprints.map(eventFootprintToComponentFootprint);
};

// Overlap
// ------------------------------------------------------------------------------------------------

Calendar.prototype.collectOverlapEventFootprints = function(peerEventFootprints, targetFootprint) {
	var overlapEventFootprints = [];
	var i;

	for (i = 0; i < peerEventFootprints.length; i++) {
		if (
			this.footprintsIntersect(
				targetFootprint,
				peerEventFootprints[i].componentFootprint
			)
		) {
			overlapEventFootprints.push(peerEventFootprints[i]);
		}
	}

	return overlapEventFootprints;
};

// optional subjectEventInstance
function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) {
	var i;

	for (i = 0; i < overlapEventFootprints.length; i++) {
		if (
			!overlapFunc(
				overlapEventFootprints[i].eventInstance.toLegacy(),
				subjectEventInstance ? subjectEventInstance.toLegacy() : null
			)
		) {
			return false;
		}
	}

	return true;
}

function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) {
	var subjectLegacyInstance = subjectEventInstance.toLegacy();
	var i;
	var overlapEventInstance;
	var overlapEventDef;
	var overlapVal;

	for (i = 0; i < overlapEventFootprints.length; i++) {
		overlapEventInstance = overlapEventFootprints[i].eventInstance;
		overlapEventDef = overlapEventInstance.def;

		// don't need to pass in calendar, because don't want to consider global eventOverlap property,
		// because we already considered that earlier in the process.
		overlapVal = overlapEventDef.getOverlap();

		if (overlapVal === false) {
			return false;
		}
		else if (typeof overlapVal === 'function') {
			if (
				!overlapVal(
					overlapEventInstance.toLegacy(),
					subjectLegacyInstance
				)
			) {
				return false;
			}
		}
	}

	return true;
}

// Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints
// ------------------------------------------------------------------------------------------------
// NOTE: this might seem like repetitive code with the Grid class, however, this code is related to
// constraints whereas the Grid code is related to rendering. Each approach might want to convert
// eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make
// this more DRY.

/*
Returns false on invalid input.
*/
Calendar.prototype.parseEventDefToInstances = function(eventInput) {
	var eventPeriod = this.eventManager.currentPeriod;
	var eventDef = EventDefParser.parse(eventInput, new EventSource(this));

	if (!eventDef) { // invalid
		return false;
	}

	if (eventPeriod) {
		return eventDef.buildInstances(eventPeriod.unzonedRange);
	}
	else {
		return [];
	}
};

Calendar.prototype.eventRangesToEventFootprints = function(eventRanges) {
	var i;
	var eventFootprints = [];

	for (i = 0; i < eventRanges.length; i++) {
		eventFootprints.push.apply( // footprints
			eventFootprints,
			this.eventRangeToEventFootprints(eventRanges[i])
		);
	}

	return eventFootprints;
};

Calendar.prototype.eventRangeToEventFootprints = function(eventRange) {
	return [ eventRangeToEventFootprint(eventRange) ];
};

/*
Parses footprints directly.
Very similar to EventDateProfile::parse :(
*/
Calendar.prototype.parseFootprints = function(rawInput) {
	var start, end;

	if (rawInput.start) {
		start = this.moment(rawInput.start);

		if (!start.isValid()) {
			start = null;
		}
	}

	if (rawInput.end) {
		end = this.moment(rawInput.end);

		if (!end.isValid()) {
			end = null;
		}
	}

	return [
		new ComponentFootprint(
			new UnzonedRange(start, end),
			(start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay
		)
	];
};

// Footprint Utils
// ----------------------------------------------------------------------------------------

Calendar.prototype.footprintContainsFootprint = function(outerFootprint, innerFootprint) {
	return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange);
};

Calendar.prototype.footprintsIntersect = function(footprint0, footprint1) {
	return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange);
};
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.buying");

cur_frm.cscript.tax_table = "Purchase Taxes and Charges";

{% include 'erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js' %}

cur_frm.email_field = "contact_email";

erpnext.buying.BuyingController = erpnext.TransactionController.extend({
	setup: function() {
		this._super();
	},

	onload: function() {
		this.setup_queries();
		this._super();

		this.frm.set_query('shipping_rule', function() {
			return {
				filters: {
					"shipping_rule_type": "Buying"
				}
			};
		});

		if (this.frm.doc.__islocal) {
			this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
		}

		/* eslint-disable */
		// no idea where me is coming from
		if(this.frm.get_field('shipping_address')) {
			this.frm.set_query("shipping_address", function() {
				if(me.frm.doc.customer) {
					return {
						query: 'frappe.contacts.doctype.address.address.address_query',
						filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
					};
				} else
					return erpnext.queries.company_address_query(me.frm.doc)
			});
		}
		/* eslint-enable */
	},

	setup_queries: function() {
		var me = this;

		if(this.frm.fields_dict.buying_price_list) {
			this.frm.set_query("buying_price_list", function() {
				return{
					filters: { 'buying': 1 }
				}
			});
		}

		me.frm.set_query('supplier', erpnext.queries.supplier);
		me.frm.set_query('contact_person', erpnext.queries.contact_query);
		me.frm.set_query('supplier_address', erpnext.queries.address_query);

		if(this.frm.fields_dict.supplier) {
			this.frm.set_query("supplier", function() {
				return{	query: "erpnext.controllers.queries.supplier_query" }});
		}

		this.frm.set_query("item_code", "items", function() {
			if(me.frm.doc.is_subcontracted == "Yes") {
				return{
					query: "erpnext.controllers.queries.item_query",
					filters:{ 'is_sub_contracted_item': 1 }
				}
			} else {
				return{
					query: "erpnext.controllers.queries.item_query",
					filters: {'is_purchase_item': 1}
				}
			}
		});
	},

	refresh: function(doc) {
		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};

		this.frm.toggle_display("supplier_name",
			(this.frm.doc.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier));

		if(this.frm.doc.docstatus==0 &&
			(this.frm.doctype==="Purchase Order" || this.frm.doctype==="Material Request")) {
			this.set_from_product_bundle();
		}

		this._super();
	},

	supplier: function() {
		var me = this;
		erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
	},

	supplier_address: function() {
		erpnext.utils.get_address_display(this.frm);
	},

	buying_price_list: function() {
		this.apply_price_list();
	},

	price_list_rate: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]);

		item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0),
			precision("rate", item));

		this.calculate_taxes_and_totals();
	},

	discount_percentage: function(doc, cdt, cdn) {
		this.price_list_rate(doc, cdt, cdn);
	},

	qty: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && (doc.update_stock || doc.is_return))) {
			frappe.model.round_floats_in(item, ["qty", "received_qty"]);

			if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["qty", "received_qty"])){ return }

			if(!item.rejected_qty && item.qty) {
				item.received_qty = item.qty;
			}

			frappe.model.round_floats_in(item, ["qty", "received_qty"]);
			item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
		}

		this._super(doc, cdt, cdn);
	},

	received_qty: function(doc, cdt, cdn) {
		this.calculate_accepted_qty(doc, cdt, cdn)
	},

	rejected_qty: function(doc, cdt, cdn) {
		this.calculate_accepted_qty(doc, cdt, cdn)
	},

	calculate_accepted_qty: function(doc, cdt, cdn){
		var item = frappe.get_doc(cdt, cdn);
		frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);

		if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["received_qty", "rejected_qty"])){ return }

		item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
		this.qty(doc, cdt, cdn);
	},

	validate_negative_quantity: function(cdt, cdn, item, fieldnames){
		if(!item || !fieldnames) { return }

		var is_negative_qty = false;
		for(var i = 0; i<fieldnames.length; i++) {
			if(item[fieldnames[i]] < 0){
				frappe.msgprint(__("Row #{0}: {1} can not be negative for item {2}",
					[item.idx,__(frappe.meta.get_label(cdt, fieldnames[i], cdn)), item.item_code]));
				is_negative_qty = true;
				break;
			}
		}

		return is_negative_qty
	},

	warehouse: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if(item.item_code && item.warehouse) {
			return this.frm.call({
				method: "erpnext.stock.get_item_details.get_bin_details",
				child: item,
				args: {
					item_code: item.item_code,
					warehouse: item.warehouse
				}
			});
		}
	},

	project: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if(item.project) {
			$.each(this.frm.doc["items"] || [],
				function(i, other_item) {
					if(!other_item.project) {
						other_item.project = item.project;
						refresh_field("project", other_item.name, other_item.parentfield);
					}
				});
		}
	},

	category: function(doc, cdt, cdn) {
		// should be the category field of tax table
		if(cdt != doc.doctype) {
			this.calculate_taxes_and_totals();
		}
	},
	add_deduct_tax: function(doc, cdt, cdn) {
		this.calculate_taxes_and_totals();
	},

	set_from_product_bundle: function() {
		var me = this;
		this.frm.add_custom_button(__("Product Bundle"), function() {
			erpnext.buying.get_items_from_product_bundle(me.frm);
		}, __("Get items from"));
	},

	shipping_address: function(){
		var me = this;
		erpnext.utils.get_address_display(this.frm, "shipping_address",
			"shipping_address_display", true);
	},

	tc_name: function() {
		this.get_terms();
	}
});

cur_frm.add_fetch('project', 'cost_center', 'cost_center');

erpnext.buying.get_default_bom = function(frm) {
	$.each(frm.doc["items"] || [], function(i, d) {
		if (d.item_code && d.bom === "") {
			return frappe.call({
				type: "GET",
				method: "erpnext.stock.get_item_details.get_default_bom",
				args: {
					"item_code": d.item_code,
				},
				callback: function(r) {
					if(r) {
						frappe.model.set_value(d.doctype, d.name, "bom", r.message);
					}
				}
			})
		}
	});
}

erpnext.buying.get_items_from_product_bundle = function(frm) {
	var dialog = new frappe.ui.Dialog({
		title: __("Get Items from Product Bundle"),
		fields: [
			{
				"fieldtype": "Link",
				"label": __("Product Bundle"),
				"fieldname": "product_bundle",
				"options":"Product Bundle",
				"reqd": 1
			},
			{
				"fieldtype": "Currency",
				"label": __("Quantity"),
				"fieldname": "quantity",
				"reqd": 1,
				"default": 1
			},
			{
				"fieldtype": "Button",
				"label": __("Get Items"),
				"fieldname": "get_items",
				"cssClass": "btn-primary"
			}
		]
	});

	dialog.fields_dict.get_items.$input.click(function() {
		var args = dialog.get_values();
		if(!args) return;
		dialog.hide();
		return frappe.call({
			type: "GET",
			method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
			args: {
				args: {
					item_code: args.product_bundle,
					quantity: args.quantity,
					parenttype: frm.doc.doctype,
					parent: frm.doc.name,
					supplier: frm.doc.supplier,
					currency: frm.doc.currency,
					conversion_rate: frm.doc.conversion_rate,
					price_list: frm.doc.buying_price_list,
					price_list_currency: frm.doc.price_list_currency,
					plc_conversion_rate: frm.doc.plc_conversion_rate,
					company: frm.doc.company,
					is_subcontracted: frm.doc.is_subcontracted,
					transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
					ignore_pricing_rule: frm.doc.ignore_pricing_rule
				}
			},
			freeze: true,
			callback: function(r) {
				const first_row_is_empty = function(child_table){
					if($.isArray(child_table) && child_table.length > 0) {
						return !child_table[0].item_code;
					}
					return false;
				};

				const remove_empty_first_row = function(frm){
				if (first_row_is_empty(frm.doc.items)){
					frm.doc.items = frm.doc.items.splice(1);
					}
				};

				if(!r.exc && r.message) {
					remove_empty_first_row(frm);
					for ( var i=0; i< r.message.length; i++ ) {
						var d = frm.add_child("items");
						var item = r.message[i];
						for ( var key in  item) {
							if ( !is_null(item[key]) ) {
								d[key] = item[key];
							}
						}
						if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
							frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
						}
					}
					frm.refresh_field("items");
				}
			}
		})
	});
	dialog.show();
}

<commit_msg>[Fix] disable_rounded_total not found error (#15113)<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

frappe.provide("erpnext.buying");

cur_frm.cscript.tax_table = "Purchase Taxes and Charges";

{% include 'erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.js' %}

cur_frm.email_field = "contact_email";

erpnext.buying.BuyingController = erpnext.TransactionController.extend({
	setup: function() {
		this._super();
	},

	onload: function() {
		this.setup_queries();
		this._super();

		this.frm.set_query('shipping_rule', function() {
			return {
				filters: {
					"shipping_rule_type": "Buying"
				}
			};
		});

		if (this.frm.doc.__islocal
			&& frappe.meta.has_field(this.frm.doc.doctype, "disable_rounded_total")) {
			this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
		}

		/* eslint-disable */
		// no idea where me is coming from
		if(this.frm.get_field('shipping_address')) {
			this.frm.set_query("shipping_address", function() {
				if(me.frm.doc.customer) {
					return {
						query: 'frappe.contacts.doctype.address.address.address_query',
						filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
					};
				} else
					return erpnext.queries.company_address_query(me.frm.doc)
			});
		}
		/* eslint-enable */
	},

	setup_queries: function() {
		var me = this;

		if(this.frm.fields_dict.buying_price_list) {
			this.frm.set_query("buying_price_list", function() {
				return{
					filters: { 'buying': 1 }
				}
			});
		}

		me.frm.set_query('supplier', erpnext.queries.supplier);
		me.frm.set_query('contact_person', erpnext.queries.contact_query);
		me.frm.set_query('supplier_address', erpnext.queries.address_query);

		if(this.frm.fields_dict.supplier) {
			this.frm.set_query("supplier", function() {
				return{	query: "erpnext.controllers.queries.supplier_query" }});
		}

		this.frm.set_query("item_code", "items", function() {
			if(me.frm.doc.is_subcontracted == "Yes") {
				return{
					query: "erpnext.controllers.queries.item_query",
					filters:{ 'is_sub_contracted_item': 1 }
				}
			} else {
				return{
					query: "erpnext.controllers.queries.item_query",
					filters: {'is_purchase_item': 1}
				}
			}
		});
	},

	refresh: function(doc) {
		frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};

		this.frm.toggle_display("supplier_name",
			(this.frm.doc.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier));

		if(this.frm.doc.docstatus==0 &&
			(this.frm.doctype==="Purchase Order" || this.frm.doctype==="Material Request")) {
			this.set_from_product_bundle();
		}

		this._super();
	},

	supplier: function() {
		var me = this;
		erpnext.utils.get_party_details(this.frm, null, null, function(){me.apply_pricing_rule()});
	},

	supplier_address: function() {
		erpnext.utils.get_address_display(this.frm);
	},

	buying_price_list: function() {
		this.apply_price_list();
	},

	price_list_rate: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		frappe.model.round_floats_in(item, ["price_list_rate", "discount_percentage"]);

		item.rate = flt(item.price_list_rate * (1 - item.discount_percentage / 100.0),
			precision("rate", item));

		this.calculate_taxes_and_totals();
	},

	discount_percentage: function(doc, cdt, cdn) {
		this.price_list_rate(doc, cdt, cdn);
	},

	qty: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && (doc.update_stock || doc.is_return))) {
			frappe.model.round_floats_in(item, ["qty", "received_qty"]);

			if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["qty", "received_qty"])){ return }

			if(!item.rejected_qty && item.qty) {
				item.received_qty = item.qty;
			}

			frappe.model.round_floats_in(item, ["qty", "received_qty"]);
			item.rejected_qty = flt(item.received_qty - item.qty, precision("rejected_qty", item));
		}

		this._super(doc, cdt, cdn);
	},

	received_qty: function(doc, cdt, cdn) {
		this.calculate_accepted_qty(doc, cdt, cdn)
	},

	rejected_qty: function(doc, cdt, cdn) {
		this.calculate_accepted_qty(doc, cdt, cdn)
	},

	calculate_accepted_qty: function(doc, cdt, cdn){
		var item = frappe.get_doc(cdt, cdn);
		frappe.model.round_floats_in(item, ["received_qty", "rejected_qty"]);

		if(!doc.is_return && this.validate_negative_quantity(cdt, cdn, item, ["received_qty", "rejected_qty"])){ return }

		item.qty = flt(item.received_qty - item.rejected_qty, precision("qty", item));
		this.qty(doc, cdt, cdn);
	},

	validate_negative_quantity: function(cdt, cdn, item, fieldnames){
		if(!item || !fieldnames) { return }

		var is_negative_qty = false;
		for(var i = 0; i<fieldnames.length; i++) {
			if(item[fieldnames[i]] < 0){
				frappe.msgprint(__("Row #{0}: {1} can not be negative for item {2}",
					[item.idx,__(frappe.meta.get_label(cdt, fieldnames[i], cdn)), item.item_code]));
				is_negative_qty = true;
				break;
			}
		}

		return is_negative_qty
	},

	warehouse: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if(item.item_code && item.warehouse) {
			return this.frm.call({
				method: "erpnext.stock.get_item_details.get_bin_details",
				child: item,
				args: {
					item_code: item.item_code,
					warehouse: item.warehouse
				}
			});
		}
	},

	project: function(doc, cdt, cdn) {
		var item = frappe.get_doc(cdt, cdn);
		if(item.project) {
			$.each(this.frm.doc["items"] || [],
				function(i, other_item) {
					if(!other_item.project) {
						other_item.project = item.project;
						refresh_field("project", other_item.name, other_item.parentfield);
					}
				});
		}
	},

	category: function(doc, cdt, cdn) {
		// should be the category field of tax table
		if(cdt != doc.doctype) {
			this.calculate_taxes_and_totals();
		}
	},
	add_deduct_tax: function(doc, cdt, cdn) {
		this.calculate_taxes_and_totals();
	},

	set_from_product_bundle: function() {
		var me = this;
		this.frm.add_custom_button(__("Product Bundle"), function() {
			erpnext.buying.get_items_from_product_bundle(me.frm);
		}, __("Get items from"));
	},

	shipping_address: function(){
		var me = this;
		erpnext.utils.get_address_display(this.frm, "shipping_address",
			"shipping_address_display", true);
	},

	tc_name: function() {
		this.get_terms();
	}
});

cur_frm.add_fetch('project', 'cost_center', 'cost_center');

erpnext.buying.get_default_bom = function(frm) {
	$.each(frm.doc["items"] || [], function(i, d) {
		if (d.item_code && d.bom === "") {
			return frappe.call({
				type: "GET",
				method: "erpnext.stock.get_item_details.get_default_bom",
				args: {
					"item_code": d.item_code,
				},
				callback: function(r) {
					if(r) {
						frappe.model.set_value(d.doctype, d.name, "bom", r.message);
					}
				}
			})
		}
	});
}

erpnext.buying.get_items_from_product_bundle = function(frm) {
	var dialog = new frappe.ui.Dialog({
		title: __("Get Items from Product Bundle"),
		fields: [
			{
				"fieldtype": "Link",
				"label": __("Product Bundle"),
				"fieldname": "product_bundle",
				"options":"Product Bundle",
				"reqd": 1
			},
			{
				"fieldtype": "Currency",
				"label": __("Quantity"),
				"fieldname": "quantity",
				"reqd": 1,
				"default": 1
			},
			{
				"fieldtype": "Button",
				"label": __("Get Items"),
				"fieldname": "get_items",
				"cssClass": "btn-primary"
			}
		]
	});

	dialog.fields_dict.get_items.$input.click(function() {
		var args = dialog.get_values();
		if(!args) return;
		dialog.hide();
		return frappe.call({
			type: "GET",
			method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
			args: {
				args: {
					item_code: args.product_bundle,
					quantity: args.quantity,
					parenttype: frm.doc.doctype,
					parent: frm.doc.name,
					supplier: frm.doc.supplier,
					currency: frm.doc.currency,
					conversion_rate: frm.doc.conversion_rate,
					price_list: frm.doc.buying_price_list,
					price_list_currency: frm.doc.price_list_currency,
					plc_conversion_rate: frm.doc.plc_conversion_rate,
					company: frm.doc.company,
					is_subcontracted: frm.doc.is_subcontracted,
					transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
					ignore_pricing_rule: frm.doc.ignore_pricing_rule
				}
			},
			freeze: true,
			callback: function(r) {
				const first_row_is_empty = function(child_table){
					if($.isArray(child_table) && child_table.length > 0) {
						return !child_table[0].item_code;
					}
					return false;
				};

				const remove_empty_first_row = function(frm){
				if (first_row_is_empty(frm.doc.items)){
					frm.doc.items = frm.doc.items.splice(1);
					}
				};

				if(!r.exc && r.message) {
					remove_empty_first_row(frm);
					for ( var i=0; i< r.message.length; i++ ) {
						var d = frm.add_child("items");
						var item = r.message[i];
						for ( var key in  item) {
							if ( !is_null(item[key]) ) {
								d[key] = item[key];
							}
						}
						if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
							frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
						}
					}
					frm.refresh_field("items");
				}
			}
		})
	});
	dialog.show();
}

<|endoftext|>


<commit_before>import { determineColorByGenotypeType } from "../util/urlHelpers";
import { numericToCalendar, currentNumDate, currentCalDate } from "../util/dateHelpers";
import { flattenTree } from "../components/tree/treeHelpers";
import { defaultGeoResolution,
  defaultColorBy,
  defaultDateRange,
  defaultDistanceMeasure,
  defaultLayout,
  mutType,
  twoColumnBreakpoint,
  reallySmallNumber } from "../util/globals";
import * as types from "../actions/types";
import { calcBrowserDimensionsInitialState } from "./browserDimensions";

const checkColorByConfidence = (attrs, colorBy) => {
  return colorBy !== "num_date" && attrs.indexOf(colorBy + "_confidence") > -1;
};

const getMinCalDateViaTree = (root) => {
  const minNumDate = root.attr.num_date - 0.01; /* slider should be earlier than actual day */
  return numericToCalendar(minNumDate);
};

const getMaxCalDateViaTree = (tree) => {
  let maxNumDate = reallySmallNumber;
  const nodesArray = flattenTree(tree);
  nodesArray.forEach((node) => {
    if (node.attr) {
      if (node.attr.num_date) {
        if (node.attr.num_date > maxNumDate) {
          maxNumDate = node.attr.num_date;
        }
      }
    }
  });
  maxNumDate += 0.01; /* slider should be later than actual day */
  return numericToCalendar(maxNumDate);
};

/* defaultState is a fn so that we can re-create it
at any time, e.g. if we want to revert things (e.g. on dataset change)
*/
const getDefaultState = () => {
  return {
    showBranchLabels: false,
    selectedLegendItem: null,
    selectedBranch: null,
    selectedNode: null,
    region: null,
    search: null,
    strain: null,
    mutType: mutType,
    temporalConfidence: {exists: false, display: false, on: false},
    layout: defaultLayout,
    distanceMeasure: defaultDistanceMeasure,
    dateMin: numericToCalendar(currentNumDate() - defaultDateRange),
    dateMax: currentCalDate(),
    absoluteDateMin: numericToCalendar(currentNumDate() - defaultDateRange),
    absoluteDateMax: currentCalDate(),
    colorBy: defaultColorBy,
    defaultColorBy: defaultColorBy,
    colorByConfidence: {display: false, on: false},
    colorScale: undefined,
    analysisSlider: false,
    geoResolution: defaultGeoResolution,
    datasetPathName: "",
    filters: {},
    showDownload: false,
    quickdraw: false, // if true, components may skip expensive computes.
    mapAnimationDurationInMilliseconds: 30000, // in milliseconds
    mapAnimationStartDate: null, // Null so it can pull the absoluteDateMin as the default
    mapAnimationCumulative: false,
    mapAnimationPlayPauseButton: "Play",
    panelLayout: calcBrowserDimensionsInitialState().width > twoColumnBreakpoint ? "grid" : "full"
  };
};

const Controls = (state = getDefaultState(), action) => {
  switch (action.type) {
    case types.DATA_INVALID:
      return Object.assign({}, state, {
        datasetPathName: undefined
      });
    case types.NEW_DATASET: {
      const base = getDefaultState();
      base["datasetPathName"] = action.datasetPathName;
      base["dateMin"] = getMinCalDateViaTree(action.tree);
      base["absoluteDateMin"] = getMinCalDateViaTree(action.tree);
      base["dateMax"] = getMaxCalDateViaTree(action.tree);
      base["absoluteDateMax"] = getMaxCalDateViaTree(action.tree);
      /* overwrite base state with data from the metadata JSON */
      if (action.meta.date_range) {
        /* this may be useful if, e.g., one were to want to display an outbreak
        from 2000-2005 (the default is the present day) */
        if (action.meta.date_range.date_min) {
          base["dateMin"] = action.meta.date_range.date_min;
          base["absoluteDateMin"] = action.meta.date_range.date_min;
          base["mapAnimationStartDate"] = action.meta.date_range.date_min;
        }
        if (action.meta.date_range.date_max) {
          base["dateMax"] = action.meta.date_range.date_max;
          base["absoluteDateMax"] = action.meta.date_range.date_max;
        }
      }
      if (action.meta.analysisSlider) {
        base["analysisSlider"] = {key: action.meta.analysisSlider, valid: false};
      }
      if (action.meta.author_info) {
        base.filters.authors = [];
      } else {
        console.error("update meta.json to include author_info.");
      }
      if (action.meta.filters) {
        action.meta.filters.forEach((v) => {base.filters[v] = [];});
      } else {
        console.warn("the meta.json did not include any filters");
      }
      if (action.meta.defaults) {
        const keysToCheckFor = ["geoResolution", "colorBy", "distanceMeasure", "layout"];
        const expectedTypes = ["string", "string", "string", "string"];

        for (let i = 0; i < keysToCheckFor.length; i += 1) {
          if (action.meta.defaults[keysToCheckFor[i]]) {
            if (typeof action.meta.defaults[keysToCheckFor[i]] === expectedTypes[i]) { // eslint-disable-line valid-typeof
              base[keysToCheckFor[i]] = action.meta.defaults[keysToCheckFor[i]];
            } else {
              console.error("Skipping (meta.json) default for ", keysToCheckFor[i], "as it is not of type ", expectedTypes[i]);
            }
          }
        }
        // TODO: why are these false / False
        if (action.meta.defaults.mapTriplicate) {
          // convert string to boolean; default is true; turned off with either false (js) or False (python)
          base["mapTriplicate"] = (action.meta.defaults.mapTriplicate === 'false' || action.meta.defaults.mapTriplicate === 'False') ? false : true;
        }
      }
      /* now overwrite state with data from the URL */
      if (action.query.l) {
        base["layout"] = action.query.l;
      }
      if (action.query.m) {
        base["distanceMeasure"] = action.query.m;
      }
      if (action.query.c) {
        base["colorBy"] = action.query.c;
      }
      if (action.query.r) {
        base["geoResolution"] = action.query.r;
      }
      if (action.query.dmin) {
        base["dateMin"] = action.query.dmin;
      }
      if (action.query.dmax) {
        base["dateMax"] = action.query.dmax;
      }
      base["temporalConfidence"] = Object.keys(action.tree.attr).indexOf("num_date_confidence") > -1 ?
        {exists: true, display: true, on: false} : {exists: false, display: false, on: false};
      if (base.temporalConfidence.exists && base.layout !== "rect") {
        base.temporalConfidence.display = false;
      }

      /* if only map or only tree, then panelLayout must be full */
      if (action.meta.panels.indexOf("map") === -1 || action.meta.panels.indexOf("tree") === -1) {
        base["panelLayout"] = "full";
      }

      /* we now check that the set values (meta.json defaults, hardcoded defaults, URL queries) are "valid" */
      /* colorBy */
      const colorByValid = Object.keys(action.meta.color_options).indexOf(base["colorBy"]) !== -1;
      const availableNonGenotypeColorBys = Object.keys(action.meta.color_options);
      if (availableNonGenotypeColorBys.indexOf("gt") > -1) {
        availableNonGenotypeColorBys.splice(availableNonGenotypeColorBys.indexOf("gt"), 1);
      }
      if (!colorByValid || base["colorBy"].startsWith("gt-")) {
        base["defaultColorBy"] = availableNonGenotypeColorBys[0];
        base["colorBy"] = base["defaultColorBy"];
        console.error("Error detected. Setting colorBy to ", base["colorBy"]);
      } else {
        base["defaultColorBy"] = base["colorBy"]; // set this so that we can always go back to the initial value
      }

      /* geoResolution */
      const availableGeoResultions = Object.keys(action.meta.geo);
      if (availableGeoResultions.indexOf(base["geoResolution"]) === -1) {
        base["geoResolution"] = availableGeoResultions[0];
        console.error("Error detected. Setting geoResolution to ", base["geoResolution"]);
      }

      /* distanceMeasure */
      if (["div", "num_date"].indexOf(base["distanceMeasure"]) === -1) {
        base["distanceMeasure"] = "num_date";
        console.error("Error detected. Setting distanceMeasure to ", base["distanceMeasure"]);
      }

      /* available tree attrs - based upon the root node */
      base["attrs"] = Object.keys(action.tree.attr);
      base["colorByConfidence"] = checkColorByConfidence(base["attrs"], base["colorBy"]);
      return base;
    }
    case types.TOGGLE_BRANCH_LABELS:
      return Object.assign({}, state, {
        showBranchLabels: !state.showBranchLabels
      });
    case types.LEGEND_ITEM_MOUSEENTER:
      return Object.assign({}, state, {
        selectedLegendItem: action.data
      });
    case types.LEGEND_ITEM_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedLegendItem: null
      });
    case types.BRANCH_MOUSEENTER:
      return Object.assign({}, state, {
        selectedBranch: action.data
      });
    case types.BRANCH_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedBranch: null
      });
    case types.NODE_MOUSEENTER:
      return Object.assign({}, state, {
        selectedNode: action.data
      });
    case types.NODE_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedNode: null
      });
    case types.CHANGE_LAYOUT: {
      const layout = action.data;
      /* if temporalConfidence and layout !== rect then disable confidence toggle */
      const temporalConfidence = Object.assign({}, state.temporalConfidence);
      if (temporalConfidence.exists) {
        temporalConfidence.display = layout === "rect";
      }
      return Object.assign({}, state, {
        layout,
        temporalConfidence
      });
    }
    case types.CHANGE_DISTANCE_MEASURE:
      /* while this may change, div currently doesn't have CIs,
      so they shouldn't be displayed. The SVG el's still exist, they're just of
      width zero */
      if (state.temporalConfidence.exists) {
        if (state.temporalConfidence.display && action.data === "div") {
          return Object.assign({}, state, {
            distanceMeasure: action.data,
            temporalConfidence: Object.assign({}, state.temporalConfidence, {display: false})
          });
        } else if (state.layout === "rect" && action.data === "num_date") {
          return Object.assign({}, state, {
            distanceMeasure: action.data,
            temporalConfidence: Object.assign({}, state.temporalConfidence, {display: true})
          });
        }
      }
      return Object.assign({}, state, {
        distanceMeasure: action.data
      });
    case types.CHANGE_DATES_VISIBILITY_THICKNESS:
      return Object.assign({}, state, {
        quickdraw: action.quickdraw,
        dateMin: action.dateMin ? action.dateMin : state.dateMin,
        dateMax: action.dateMax ? action.dateMax : state.dateMax
      });
    case types.CHANGE_ABSOLUTE_DATE_MIN:
      return Object.assign({}, state, {
        absoluteDateMin: action.data
      });
    case types.CHANGE_ABSOLUTE_DATE_MAX:
      return Object.assign({}, state, {
        absoluteDateMax: action.data
      });
    case types.CHANGE_ANIMATION_TIME:
      return Object.assign({}, state, {
        mapAnimationDurationInMilliseconds: action.data
      });
    case types.CHANGE_ANIMATION_CUMULATIVE:
      return Object.assign({}, state, {
        mapAnimationCumulative: action.data
      });
    case types.MAP_ANIMATION_PLAY_PAUSE_BUTTON:
      return Object.assign({}, state, {
        quickdraw: action.data === "Play" ? false : true,
        mapAnimationPlayPauseButton: action.data
      });
    case types.CHANGE_ANIMATION_START:
      return Object.assign({}, state, {
        mapAnimationStartDate: action.data
      });
    case types.CHANGE_PANEL_LAYOUT:
      return Object.assign({}, state, {
        panelLayout: action.data
      });
    case types.NEW_COLORS: {
      const newState = Object.assign({}, state, {
        colorBy: action.colorBy,
        colorScale: action.colorScale,
        colorByConfidence: checkColorByConfidence(state.attrs, action.colorBy)
      });
      /* may need to toggle the entropy selector AA <-> NUC */
      if (determineColorByGenotypeType(action.colorBy)) {
        newState.mutType = determineColorByGenotypeType(action.colorBy);
      }
      return newState;
    }
    case types.CHANGE_GEO_RESOLUTION:
      return Object.assign({}, state, {
        geoResolution: action.data
      });
    case types.APPLY_FILTER_QUERY: {
      // values arrive as array
      const filters = Object.assign({}, state.filters, {});
      filters[action.fields] = action.values;
      // console.log(filters)
      return Object.assign({}, state, {
        filters
      });
    }
    case types.TOGGLE_MUT_TYPE:
      return Object.assign({}, state, {
        mutType: action.data
      });
    case types.TOGGLE_TEMPORAL_CONF:
      return Object.assign({}, state, {
        temporalConfidence: Object.assign({}, state.temporalConfidence, {
          on: !state.temporalConfidence.on
        })
      });
    case types.ANALYSIS_SLIDER:
      if (action.destroy) {
        return Object.assign({}, state, {
          analysisSlider: false
        });
      }
      return Object.assign({}, state, {
        analysisSlider: {
          key: state.analysisSlider.key,
          // valid: true, // TESTING ONLY
          valid: false, // FIXME --- This is a temporary hack to disable the analysis slider, while keeping color options
          value: action.maxVal,
          absoluteMinVal: action.minVal,
          absoluteMaxVal: action.maxVal
        }
      });
    case types.CHANGE_ANALYSIS_VALUE:
      return Object.assign({}, state, {
        analysisSlider: Object.assign({}, state.analysisSlider, {
          value: action.value
        })
      });
    case types.TRIGGER_DOWNLOAD_MODAL:
      return Object.assign({}, state, {
        showDownload: true
      });
    case types.DISMISS_DOWNLOAD_MODAL:
      return Object.assign({}, state, {
        showDownload: false
      });
    default:
      return state;
  }
};

export default Controls;
<commit_msg>break apart controls reducer into functions<commit_after>import { determineColorByGenotypeType } from "../util/urlHelpers";
import { numericToCalendar, currentNumDate, currentCalDate } from "../util/dateHelpers";
import { flattenTree } from "../components/tree/treeHelpers";
import { defaultGeoResolution,
  defaultColorBy,
  defaultDateRange,
  defaultDistanceMeasure,
  defaultLayout,
  mutType,
  twoColumnBreakpoint,
  reallySmallNumber } from "../util/globals";
import * as types from "../actions/types";
import { calcBrowserDimensionsInitialState } from "./browserDimensions";

const checkColorByConfidence = (attrs, colorBy) => {
  return colorBy !== "num_date" && attrs.indexOf(colorBy + "_confidence") > -1;
};

const getMinCalDateViaTree = (root) => {
  const minNumDate = root.attr.num_date - 0.01; /* slider should be earlier than actual day */
  return numericToCalendar(minNumDate);
};

const getMaxCalDateViaTree = (tree) => {
  let maxNumDate = reallySmallNumber;
  const nodesArray = flattenTree(tree);
  nodesArray.forEach((node) => {
    if (node.attr) {
      if (node.attr.num_date) {
        if (node.attr.num_date > maxNumDate) {
          maxNumDate = node.attr.num_date;
        }
      }
    }
  });
  maxNumDate += 0.01; /* slider should be later than actual day */
  return numericToCalendar(maxNumDate);
};

const modifyStateViaURLQuery = (state, query) => {
  if (query.l) {
    state["layout"] = query.l;
  }
  if (query.m) {
    state["distanceMeasure"] = query.m;
  }
  if (query.c) {
    state["colorBy"] = query.c;
  }
  if (query.r) {
    state["geoResolution"] = query.r;
  }
  if (query.dmin) {
    state["dateMin"] = query.dmin;
  }
  if (query.dmax) {
    state["dateMax"] = query.dmax;
  }
  return state;
};

const modifyStateViaMetadata = (state, metadata) => {
  if (metadata.date_range) {
    /* this may be useful if, e.g., one were to want to display an outbreak
    from 2000-2005 (the default is the present day) */
    if (metadata.date_range.date_min) {
      state["dateMin"] = metadata.date_range.date_min;
      state["absoluteDateMin"] = metadata.date_range.date_min;
      state["mapAnimationStartDate"] = metadata.date_range.date_min;
    }
    if (metadata.date_range.date_max) {
      state["dateMax"] = metadata.date_range.date_max;
      state["absoluteDateMax"] = metadata.date_range.date_max;
    }
  }
  if (metadata.analysisSlider) {
    state["analysisSlider"] = {key: metadata.analysisSlider, valid: false};
  }
  if (metadata.author_info) {
    state.filters.authors = [];
  } else {
    console.error("update meta.json to include author_info.");
  }
  if (metadata.filters) {
    metadata.filters.forEach((v) => {state.filters[v] = [];});
  } else {
    console.warn("the meta.json did not include any filters");
  }
  if (metadata.defaults) {
    const keysToCheckFor = ["geoResolution", "colorBy", "distanceMeasure", "layout"];
    const expectedTypes = ["string", "string", "string", "string"];

    for (let i = 0; i < keysToCheckFor.length; i += 1) {
      if (metadata.defaults[keysToCheckFor[i]]) {
        if (typeof metadata.defaults[keysToCheckFor[i]] === expectedTypes[i]) { // eslint-disable-line valid-typeof
          state[keysToCheckFor[i]] = metadata.defaults[keysToCheckFor[i]];
        } else {
          console.error("Skipping (meta.json) default for ", keysToCheckFor[i], "as it is not of type ", expectedTypes[i]);
        }
      }
    }
    // TODO: why are these false / False
    if (metadata.defaults.mapTriplicate) {
      // convert string to boolean; default is true; turned off with either false (js) or False (python)
      state["mapTriplicate"] = (metadata.defaults.mapTriplicate === 'false' || metadata.defaults.mapTriplicate === 'False') ? false : true;
    }
  }

  /* if only map or only tree, then panelLayout must be full */
  if (metadata.panels.indexOf("map") === -1 || metadata.panels.indexOf("tree") === -1) {
    state["panelLayout"] = "full";
  }
  return state;
};

const modifyStateViaTree = (state, tree) => {
  state["dateMin"] = getMinCalDateViaTree(tree);
  state["absoluteDateMin"] = getMinCalDateViaTree(tree);
  state["dateMax"] = getMaxCalDateViaTree(tree);
  state["absoluteDateMax"] = getMaxCalDateViaTree(tree);
  /* available tree attrs - based upon the root node */
  state["attrs"] = Object.keys(tree.attr);
  state["temporalConfidence"] = Object.keys(tree.attr).indexOf("num_date_confidence") > -1 ?
    {exists: true, display: true, on: false} : {exists: false, display: false, on: false};
  return state;
};

const checkAndCorrectErrorsInState = (state, metadata) => {

  /* colorBy */
  const availableNonGenotypeColorBys = Object.keys(metadata.color_options);
  if (availableNonGenotypeColorBys.indexOf("gt") > -1) {
    availableNonGenotypeColorBys.splice(availableNonGenotypeColorBys.indexOf("gt"), 1);
  }
  const colorByValid = Object.keys(metadata.color_options).indexOf(state["colorBy"]) !== -1;
  if (!colorByValid || state["colorBy"].startsWith("gt-")) {
    state["defaultColorBy"] = availableNonGenotypeColorBys[0];
    state["colorBy"] = state["defaultColorBy"];
    console.error("Error detected. Setting colorBy to ", state["colorBy"]);
  } else {
    state["defaultColorBy"] = state["colorBy"]; // set this so that we can always go back to the initial value
  }

  /* colorBy confidence */
  state["colorByConfidence"] = checkColorByConfidence(state["attrs"], state["colorBy"]);

  /* distanceMeasure */
  if (["div", "num_date"].indexOf(state["distanceMeasure"]) === -1) {
    state["distanceMeasure"] = "num_date";
    console.error("Error detected. Setting distanceMeasure to ", state["distanceMeasure"]);
  }

  /* geoResolution */
  const availableGeoResultions = Object.keys(metadata.geo);
  if (availableGeoResultions.indexOf(state["geoResolution"]) === -1) {
    state["geoResolution"] = availableGeoResultions[0];
    console.error("Error detected. Setting geoResolution to ", state["geoResolution"]);
  }

  /* temporalConfidence */
  if (state.temporalConfidence.exists && state.layout !== "rect") {
    state.temporalConfidence.display = false;
  }

  return state;
};

/* defaultState is a fn so that we can re-create it
at any time, e.g. if we want to revert things (e.g. on dataset change)
*/
const getDefaultState = () => {
  return {
    showBranchLabels: false,
    selectedLegendItem: null,
    selectedBranch: null,
    selectedNode: null,
    region: null,
    search: null,
    strain: null,
    mutType: mutType,
    temporalConfidence: {exists: false, display: false, on: false},
    layout: defaultLayout,
    distanceMeasure: defaultDistanceMeasure,
    dateMin: numericToCalendar(currentNumDate() - defaultDateRange),
    dateMax: currentCalDate(),
    absoluteDateMin: numericToCalendar(currentNumDate() - defaultDateRange),
    absoluteDateMax: currentCalDate(),
    colorBy: defaultColorBy,
    defaultColorBy: defaultColorBy,
    colorByConfidence: {display: false, on: false},
    colorScale: undefined,
    analysisSlider: false,
    geoResolution: defaultGeoResolution,
    datasetPathName: "",
    filters: {},
    showDownload: false,
    quickdraw: false, // if true, components may skip expensive computes.
    mapAnimationDurationInMilliseconds: 30000, // in milliseconds
    mapAnimationStartDate: null, // Null so it can pull the absoluteDateMin as the default
    mapAnimationCumulative: false,
    mapAnimationPlayPauseButton: "Play",
    panelLayout: calcBrowserDimensionsInitialState().width > twoColumnBreakpoint ? "grid" : "full"
  };
};

const Controls = (state = getDefaultState(), action) => {
  switch (action.type) {
    case types.DATA_INVALID:
      return Object.assign({}, state, {
        datasetPathName: undefined
      });
    case types.NEW_DATASET: {
      let base = getDefaultState();
      base["datasetPathName"] = action.datasetPathName;
      base = modifyStateViaTree(base, action.tree);
      base = modifyStateViaMetadata(base, action.meta);
      base = modifyStateViaURLQuery(base, action.query);
      base = checkAndCorrectErrorsInState(base, action.meta); /* must run last */
      return base;
    }
    case types.TOGGLE_BRANCH_LABELS:
      return Object.assign({}, state, {
        showBranchLabels: !state.showBranchLabels
      });
    case types.LEGEND_ITEM_MOUSEENTER:
      return Object.assign({}, state, {
        selectedLegendItem: action.data
      });
    case types.LEGEND_ITEM_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedLegendItem: null
      });
    case types.BRANCH_MOUSEENTER:
      return Object.assign({}, state, {
        selectedBranch: action.data
      });
    case types.BRANCH_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedBranch: null
      });
    case types.NODE_MOUSEENTER:
      return Object.assign({}, state, {
        selectedNode: action.data
      });
    case types.NODE_MOUSELEAVE:
      return Object.assign({}, state, {
        selectedNode: null
      });
    case types.CHANGE_LAYOUT: {
      const layout = action.data;
      /* if temporalConfidence and layout !== rect then disable confidence toggle */
      const temporalConfidence = Object.assign({}, state.temporalConfidence);
      if (temporalConfidence.exists) {
        temporalConfidence.display = layout === "rect";
      }
      return Object.assign({}, state, {
        layout,
        temporalConfidence
      });
    }
    case types.CHANGE_DISTANCE_MEASURE:
      /* while this may change, div currently doesn't have CIs,
      so they shouldn't be displayed. The SVG el's still exist, they're just of
      width zero */
      if (state.temporalConfidence.exists) {
        if (state.temporalConfidence.display && action.data === "div") {
          return Object.assign({}, state, {
            distanceMeasure: action.data,
            temporalConfidence: Object.assign({}, state.temporalConfidence, {display: false})
          });
        } else if (state.layout === "rect" && action.data === "num_date") {
          return Object.assign({}, state, {
            distanceMeasure: action.data,
            temporalConfidence: Object.assign({}, state.temporalConfidence, {display: true})
          });
        }
      }
      return Object.assign({}, state, {
        distanceMeasure: action.data
      });
    case types.CHANGE_DATES_VISIBILITY_THICKNESS:
      return Object.assign({}, state, {
        quickdraw: action.quickdraw,
        dateMin: action.dateMin ? action.dateMin : state.dateMin,
        dateMax: action.dateMax ? action.dateMax : state.dateMax
      });
    case types.CHANGE_ABSOLUTE_DATE_MIN:
      return Object.assign({}, state, {
        absoluteDateMin: action.data
      });
    case types.CHANGE_ABSOLUTE_DATE_MAX:
      return Object.assign({}, state, {
        absoluteDateMax: action.data
      });
    case types.CHANGE_ANIMATION_TIME:
      return Object.assign({}, state, {
        mapAnimationDurationInMilliseconds: action.data
      });
    case types.CHANGE_ANIMATION_CUMULATIVE:
      return Object.assign({}, state, {
        mapAnimationCumulative: action.data
      });
    case types.MAP_ANIMATION_PLAY_PAUSE_BUTTON:
      return Object.assign({}, state, {
        quickdraw: action.data === "Play" ? false : true,
        mapAnimationPlayPauseButton: action.data
      });
    case types.CHANGE_ANIMATION_START:
      return Object.assign({}, state, {
        mapAnimationStartDate: action.data
      });
    case types.CHANGE_PANEL_LAYOUT:
      return Object.assign({}, state, {
        panelLayout: action.data
      });
    case types.NEW_COLORS: {
      const newState = Object.assign({}, state, {
        colorBy: action.colorBy,
        colorScale: action.colorScale,
        colorByConfidence: checkColorByConfidence(state.attrs, action.colorBy)
      });
      /* may need to toggle the entropy selector AA <-> NUC */
      if (determineColorByGenotypeType(action.colorBy)) {
        newState.mutType = determineColorByGenotypeType(action.colorBy);
      }
      return newState;
    }
    case types.CHANGE_GEO_RESOLUTION:
      return Object.assign({}, state, {
        geoResolution: action.data
      });
    case types.APPLY_FILTER_QUERY: {
      // values arrive as array
      const filters = Object.assign({}, state.filters, {});
      filters[action.fields] = action.values;
      // console.log(filters)
      return Object.assign({}, state, {
        filters
      });
    }
    case types.TOGGLE_MUT_TYPE:
      return Object.assign({}, state, {
        mutType: action.data
      });
    case types.TOGGLE_TEMPORAL_CONF:
      return Object.assign({}, state, {
        temporalConfidence: Object.assign({}, state.temporalConfidence, {
          on: !state.temporalConfidence.on
        })
      });
    case types.ANALYSIS_SLIDER:
      if (action.destroy) {
        return Object.assign({}, state, {
          analysisSlider: false
        });
      }
      return Object.assign({}, state, {
        analysisSlider: {
          key: state.analysisSlider.key,
          // valid: true, // TESTING ONLY
          valid: false, // FIXME --- This is a temporary hack to disable the analysis slider, while keeping color options
          value: action.maxVal,
          absoluteMinVal: action.minVal,
          absoluteMaxVal: action.maxVal
        }
      });
    case types.CHANGE_ANALYSIS_VALUE:
      return Object.assign({}, state, {
        analysisSlider: Object.assign({}, state.analysisSlider, {
          value: action.value
        })
      });
    case types.TRIGGER_DOWNLOAD_MODAL:
      return Object.assign({}, state, {
        showDownload: true
      });
    case types.DISMISS_DOWNLOAD_MODAL:
      return Object.assign({}, state, {
        showDownload: false
      });
    default:
      return state;
  }
};

export default Controls;
<|endoftext|>


<commit_before>import compileFun from '../lib/compile-fun'
import { Readable } from 'readable-stream'
import http from 'stream-http'
import { processInputStream, concatStream } from '../lib/stream'
import stringToStream from 'string-to-stream'
import concat from './concat'

let stdin = Uint8Array.of()

const window = { localStorage: { debug: '*' } }
const debug = require('debug')('ramda-cli:web:worker')
debug.enabled = true
debug('worker initialized')

const stdinHttpReq = http.get('/stdin', (res) => {
  res.on('data', (chunk) => {
    debug('got stdin chunk')
    stdin = concat(Uint8Array, [ stdin, chunk ])
  })
})

const onEvalInputError = (err) => {
  self.postMessage({
    event: 'EVAL_ERROR',
    err: err.stack || err.message || err
  })
}

const onEvalInput = ({ opts }) => {
  let fun
  try {
    fun = compileFun(opts)
  } catch (err) {
    onEvalInputError(err)
    return
  }

  const inputStream = new Readable()
  inputStream.push(stdin)
  inputStream.push(null)
  const stream = processInputStream(
    onEvalInputError,
    opts,
    fun,
    inputStream
  )
  stream.pipe(concatStream()).on('data', (chunk) => {
    self.postMessage({
      event: 'EVAL_OUTPUT',
      output: chunk,
      opts
    })
  })
}

self.onmessage = ({ data }) => {
  debug('message', data)
  const { event } = data
  if (event === 'EVAL_INPUT') onEvalInput(data)
}
<commit_msg>worker: don't evaluate on new chunk before app has sent opts<commit_after>import compileFun from '../lib/compile-fun'
import { Readable } from 'readable-stream'
import http from 'stream-http'
import { processInputStream, concatStream } from '../lib/stream'
import stringToStream from 'string-to-stream'
import concat from './concat'

let stdin = Uint8Array.of()
let curOpts = null

const window = { localStorage: { debug: '*' } }
const debug = require('debug')('ramda-cli:web:worker')
debug.enabled = true
debug('worker initialized')

const stdinHttpReq = http.get('/stdin', (res) => {
  res.on('data', (chunk) => {
    debug('got stdin chunk')
    stdin = concat(Uint8Array, [stdin, chunk])
    onEvalInput({ opts: curOpts })
  })
})

const onEvalInputError = (err) => {
  self.postMessage({
    event: 'EVAL_ERROR',
    err: err.stack || err.message || err
  })
}

const onEvalInput = ({ opts }) => {
  if (opts === null) return
  curOpts = opts
  let fun
  try {
    fun = compileFun(opts)
  } catch (err) {
    onEvalInputError(err)
    return
  }

  const inputStream = new Readable()
  inputStream.push(stdin)
  inputStream.push(null)
  const stream = processInputStream(onEvalInputError, opts, fun, inputStream)
  stream
    .pipe(concatStream())
    .on('data', (chunk) => {
      self.postMessage({
        event: 'EVAL_OUTPUT',
        output: chunk,
        opts
      })
  })
}

self.onmessage = ({ data }) => {
  debug('message', data)
  const { event } = data
  if (event === 'EVAL_INPUT') onEvalInput(data)
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';

class ErrorPage extends Component {
  render() {
    const errors = this.props.errors;
    console.log(errors);

    return (

There's been an error

          {errors && errors.map((error, index) =>
{error}
)}

    );
  }
}

const mapStateToProps = state => {
  return {
    errors: state.payment.errors
  };
};

export default connect(mapStateToProps)(ErrorPage);
<commit_msg>Escape ' character<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';

class ErrorPage extends Component {
  render() {
    const errors = this.props.errors;
    console.log(errors);

    return (

{"There's been an error"}

          {errors && errors.map((error, index) =>
{error}
)}

    );
  }
}

const mapStateToProps = state => {
  return {
    errors: state.payment.errors
  };
};

export default connect(mapStateToProps)(ErrorPage);
<|endoftext|>


<commit_before>import {both, equals, find, propEq, reject} from 'ramda'
import {
  ACTIVE_PATTERN_CELL_CLICK,
  UPDATE_ACTIVE_PATTERN_ACTIVE_POSITION,
  UPDATE_ACTIVE_PATTERN_INSTRUMENT,
  UPDATE_ACTIVE_PATTERN_OCTAVE,
  UPDATE_ACTIVE_PATTERN_X_LENGTH,
  UPDATE_ACTIVE_PATTERN_VOLUME
} from '../actions'
import store from '../store'

export const initialState = [{
  activePosition: null,
  instrument: 'Prometheus',
  notes: [],
  octave: 0,
  xLength: 8,
  yLength: 8,
  volume: 1 / 3
}]

export const noteExists = (notes, x, y) => Boolean(find(both(propEq('x', x), propEq('y', y)), notes))

export default (state = initialState, {type, payload}) => {
  switch (type) {
    case ACTIVE_PATTERN_CELL_CLICK: {
      const {x, y} = payload
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      const {notes} = activePattern
      return noteExists(notes, x, y)
        ? [...state.slice(0, activePatternIndex),
         {...activePattern, notes: reject(equals(payload), notes)},
         ...state.slice(activePatternIndex + 1)]
        : [...state.slice(0, activePatternIndex),
         {...activePattern, notes: [...notes, payload]},
         ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_ACTIVE_POSITION: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, activePosition: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_INSTRUMENT: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, instrument: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_OCTAVE: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, octave: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_X_LENGTH: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, xLength: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_VOLUME: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, volume: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    default:
      return state
  }
}
<commit_msg>refactor(patterns) more elegant reducer code<commit_after>import {adjust, both, equals, find, propEq, reject} from 'ramda'
import {
  ACTIVE_PATTERN_CELL_CLICK,
  UPDATE_ACTIVE_PATTERN_ACTIVE_POSITION,
  UPDATE_ACTIVE_PATTERN_INSTRUMENT,
  UPDATE_ACTIVE_PATTERN_OCTAVE,
  UPDATE_ACTIVE_PATTERN_X_LENGTH,
  UPDATE_ACTIVE_PATTERN_VOLUME
} from '../actions'
import store from '../store'

export const initialState = [{
  activePosition: null,
  instrument: 'Prometheus',
  notes: [],
  octave: 0,
  xLength: 8,
  yLength: 8,
  volume: 1 / 3
}]

export const noteExists = (notes, x, y) => Boolean(find(both(propEq('x', x), propEq('y', y)), notes))

export default (state = initialState, {type, payload}) => {
  switch (type) {
    case ACTIVE_PATTERN_CELL_CLICK: {
      const {x, y} = payload
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      const {notes} = activePattern
      return noteExists(notes, x, y)
        ? [...state.slice(0, activePatternIndex),
         {...activePattern, notes: reject(equals(payload), notes)},
         ...state.slice(activePatternIndex + 1)]
        : [...state.slice(0, activePatternIndex),
         {...activePattern, notes: [...notes, payload]},
         ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_ACTIVE_POSITION:
      return adjust(
        activePattern => ({...activePattern, activePosition: payload}),
        store.getState().activePatternIndex,
        state
      )
    case UPDATE_ACTIVE_PATTERN_INSTRUMENT: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, instrument: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_OCTAVE: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, octave: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_X_LENGTH: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, xLength: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    case UPDATE_ACTIVE_PATTERN_VOLUME: {
      const {activePatternIndex} = store.getState()
      const activePattern = state[activePatternIndex]
      return [...state.slice(0, activePatternIndex),
              {...activePattern, volume: payload},
              ...state.slice(activePatternIndex + 1)]
    }
    default:
      return state
  }
}
<|endoftext|>


<commit_before>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**
 * @ngdoc directive
 * @name pnc.record:pncLogCanvas
 * @restrict EA
 * @interface
 * @description
 * @example
 * @author Alex Creasy
 */
angular.module('pnc.record')
  .directive('pncLogCanvas', function() {

    return {
      restrict: 'EA',
      template: '

',
      link: function(scope, element) {
        var autoscroll = true;

        // Find the child div specified in `template`
        var div = element.find('div');
        var parent = element[0];

        function addToLog(event, payload) {
          div.append(payload + '
');
          if (autoscroll) {
            parent.scrollTop = parent.scrollHeight;
          }
        }

        function toggleAutoscroll() {
          autoscroll = !autoscroll;
        }

        scope.$on('pnc-log-canvas::add_line', addToLog);
        scope.$on('pnc-log-canvas::toggle_autoscroll', toggleAutoscroll);
      }
    };

});
<commit_msg>[NCL-1809] Add auto-toggle of autoscroll based on the user's scroll position in the log canvas.<commit_after>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

/**
 * @ngdoc directive
 * @name pnc.record:pncLogCanvas
 * @restrict EA
 * @interface
 * @description
 * @example
 * @author Alex Creasy
 */
angular.module('pnc.record')
  .directive('pncLogCanvas', function() {

    return {
      restrict: 'EA',
      template: '

',
      link: function(scope, element) {
        // Find the child div specified in `template`
        var div = element.find('div');
        var parent = element[0];

        var autoscroll = true;
        var startPosition = parent.scrollTop;

        // Catch scroll events so we can enable / disable scrolling based
        // on whether the user is scrolled to the bottom.
        parent.onscroll = function () {
          var endPosition = parent.scrollTop;
          var height = element.innerHeight();
          var bottom = parent.scrollHeight;

          if (endPosition >= startPosition) {
            // User is scrolling downwards, if they scroll to the bottom
            // enable autoscroll.
            if (endPosition + height >= bottom) {
              autoscroll = true;
            }
          } else {
            // User is scrolling up so disable autoscroll
            autoscroll = false;
          }
          // Reset the start position so we can detect which direction the user
          // has scrolled in next time.
          startPosition = parent.scrollTop;
        };

        function addToLog(event, payload) {
          div.append(payload + '
');
          if (autoscroll) {
            parent.scrollTop = parent.scrollHeight;
            // Reset the start position so we can detect which direction the user
            // has scrolled in next time.
            startPosition = parent.scrollTop;
          }
        }

        scope.$on('pnc-log-canvas::add_line', addToLog);
      }
    };

});
<|endoftext|>


<commit_before>import { CardModel } from 'redux/modules/card';

const cards = [
  {
    name: 'Anima Golem',
    mana: 6,
    attack: 9,
    defense: 9,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/5/54/Anima_Golem_full.jpg/459px-Anima_Golem_full.jpg?version=1624263f4c524b56f97dd80fdd3d9bf2',
  }, {
    name: 'Abusive Sergeant',
    mana: 1,
    attack: 2,
    defense: 1,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/1/18/Abusive_Sergeant_full.jpg/587px-Abusive_Sergeant_full.jpg?version=80b05953c8897d68d12706490c8ab68d',
  }, {
    name: 'Acolyte of Pain',
    mana: 3,
    attack: 1,
    defense: 3,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/e/e0/Acolyte_of_Pain_full.jpg/350px-Acolyte_of_Pain_full.jpg?version=ea71ea7aef056d51f01800584e74c1bb',
  }, {
    name: 'Azure Drake',
    mana: 5,
    attack: 4,
    defense: 4,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/6/64/Azure_Drake_full.jpg/782px-Azure_Drake_full.jpg?version=6104b0c3caf640057fb10ca860778635',
  },
];

const cardsByName = {};
for (const card of cards) {
  cardsByName[card.name.toLowerCase()] = card;
}

export default function newCardByName(name = '') {
  const card = cardsByName[name.toLowerCase()];
  if (!card) throw new Error('There is no card with that name');
  return new CardModel(card);
}

export function newRandomCard() {
  const randomCard = cards[Math.floor(Math.random() * cards.length)];
  return newCardByName(randomCard.name);
}
<commit_msg>Add RareParrot and James Kappa cards<commit_after>import { CardModel } from 'redux/modules/card';

const cards = [
  {
    name: 'Anima Golem',
    mana: 6,
    attack: 9,
    defense: 9,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/5/54/Anima_Golem_full.jpg/459px-Anima_Golem_full.jpg?version=1624263f4c524b56f97dd80fdd3d9bf2',
  }, {
    name: 'Abusive Sergeant',
    mana: 1,
    attack: 2,
    defense: 1,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/1/18/Abusive_Sergeant_full.jpg/587px-Abusive_Sergeant_full.jpg?version=80b05953c8897d68d12706490c8ab68d',
  }, {
    name: 'Acolyte of Pain',
    mana: 3,
    attack: 1,
    defense: 3,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/e/e0/Acolyte_of_Pain_full.jpg/350px-Acolyte_of_Pain_full.jpg?version=ea71ea7aef056d51f01800584e74c1bb',
  }, {
    name: 'Azure Drake',
    mana: 5,
    attack: 4,
    defense: 4,
    portrait: 'http://hydra-media.cursecdn.com/hearthstone.gamepedia.com/thumb/6/64/Azure_Drake_full.jpg/782px-Azure_Drake_full.jpg?version=6104b0c3caf640057fb10ca860778635',
  }, {
    name: 'Rare Parrot',
    mana: 10,
    attack: 0,
    defense: 10,
    portrait: 'http://i.imgur.com/PYe4A3T.gif',
  }, {
    name: 'James Kappa',
    mana: 3,
    attack: 16,
    defense: 5,
    portrait: 'http://media.steampowered.com/steamcommunity/public/images/avatars/0c/0c32e686f6c202e65de64bacb32eaea0c6b517f0_full.jpg',
  },
];

const cardsByName = {};
for (const card of cards) {
  cardsByName[card.name.toLowerCase()] = card;
}

export default function newCardByName(name = '') {
  const card = cardsByName[name.toLowerCase()];
  if (!card) throw new Error('There is no card with that name');
  return new CardModel(card);
}

export function newRandomCard() {
  const randomCard = cards[Math.floor(Math.random() * cards.length)];
  return newCardByName(randomCard.name);
}
<|endoftext|>


<commit_before>import React from 'react'
import ReactDOM from 'react-dom'
import Root from './components/root'
import TweetList from './components/tweet-list'

export default class Renderer {
    render(stores) {
        ReactDOM.render(
            <Root stores={stores}/>, document.getElementById("postLoad")
        );
    }
}
<commit_msg>add render-preload method.<commit_after>import React from 'react'
import ReactDOM from 'react-dom'
import Root from './components/root'
import TweetList from './components/tweet-list'
import PreLoad from './components/pre-load'

export default class Renderer {
    render(stores) {
        ReactDOM.render(
            <Root stores={stores}/>, document.getElementById("postLoad")
        );
    }

    renderPreload() {
        ReactDOM.render(
            <PreLoad/>, document.getElementById("preLoad")
        );
    }
}
<|endoftext|>


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

  require('shared/fend/progressbar-loading/tests/unit/require.load');
  require('shared/fend/input-utils/tests/unit/require.load');
  require('shared/fend/navbar/tests/unit/require.load');
  require('shared/fend/pagination/tests/unit/require.load');

  require('app/main/tests/unit/require.load');
  require('app/home/tests/unit/require.load');
  require('app/about/tests/unit/require.load');
  require('app/help/tests/unit/require.load');
  require('app/bookmarks/tests/unit/require.load');

});
<commit_msg>src/require.unit.load.js #18 #19<commit_after>define(function(require) {
  'use strict';

  require('shared/fend/progressbar-loading/tests/unit/require.load');
  require('shared/fend/input-utils/tests/unit/require.load');
  require('shared/fend/navbar/tests/unit/require.load');
  require('shared/fend/pagination/tests/unit/require.load');

  require('app/main/tests/unit/require.load');
  require('app/home/tests/unit/require.load');
  require('app/about/tests/unit/require.load');
  require('app/help/tests/unit/require.load');
  require('app/bookmarks/tests/unit/require.load');

  // TODO: add here tests unit module to load

});
<|endoftext|>


<commit_before>exports.unloadAll = function () {
  // Consider clearing path cache as well. This can be reached with:
  // require.cache[cache].constructor._pathCache.
  for (var cache in require.cache) {
    delete require.cache[cache];
  }
};

var _lastUnloadPrefix = "";
exports.unload = function (files) {
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    if (_lastUnloadPrefix && ((_lastUnloadPrefix + file) in require.cache)) {
      delete require.cache[_lastUnloadPrefix + file];
    } else {
      for (var cache in require.cache) {
        var parts = cache.split(file);
        if (parts.length == 2 && parts[1] == "") {
          _lastUnloadPrefix = parts[0];
          delete require.cache[cache];
        }
      }
    }
  }
};

exports.getCacheList = function () {
  var result = [];
  for (var cache in require.cache) {
    result.push(cache);
  }
  return result;
};
<commit_msg>Support revolver.unload(fileName), without Array<commit_after>exports.unloadAll = function () {
  // Consider clearing path cache as well. This can be reached with:
  // require.cache[cache].constructor._pathCache.
  for (var cache in require.cache) {
    delete require.cache[cache];
  }
};

var _lastUnloadPrefix = "";
exports.unload = function (files) {
  if (!(files instanceof Array)) {
    files = [files];
  }
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    if (_lastUnloadPrefix && ((_lastUnloadPrefix + file) in require.cache)) {
      delete require.cache[_lastUnloadPrefix + file];
    } else {
      for (var cache in require.cache) {
        var parts = cache.split(file);
        if (parts.length == 2 && parts[1] == "") {
          _lastUnloadPrefix = parts[0];
          delete require.cache[cache];
          break;
        }
      }
    }
  }
};

exports.getCacheList = function () {
  var result = [];
  for (var cache in require.cache) {
    result.push(cache);
  }
  return result;
};
<|endoftext|>