<commit_before>/** @type {import('eslint').Linter.Config} */
module.exports = {
  'env': {
    'jest': true,
    'node': true
  },
  'extends': [
    'airbnb-base',
    'plugin:security/recommended',
    'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
  ],
  parser: '@typescript-eslint/parser', // Specifies the ESLint parser
  parserOptions:  {
    ecmaVersion:  2018,  // Allows for the parsing of modern ECMAScript features
    sourceType:  'module',  // Allows for the use of imports
  },
  'plugins': [
    'import',
    'security',
    'jest'
  ],
  'rules': {
    'jest/no-disabled-tests': [2],
    'jest/no-focused-tests': [2],
    'jest/no-identical-title': [2],
    'jest/prefer-to-have-length': [2],
    'jest/valid-expect': [2],

    '@typescript-eslint/no-empty-interface': [2],
    '@typescript-eslint/no-explicit-any': [2],
    '@typescript-eslint/no-var-requires': [2],
    'import/prefer-default-export': [0],
    'import/extensions': ['error', 'ignorePackages', {
      js: 'never',
      ts: 'never',
    }],
    // TODO: Enable these lint rules:
    // They were disabled to facilitate the transition to TypeScript
    '@typescript-eslint/explicit-function-return-type': [0],
    // These rules disabled during the dependency upgrade on 2020-07-06
    // Check these and re-enable
    '@typescript-eslint/class-name-casing': [0],
    '@typescript-eslint/ban-ts-ignore': [0],
    '@typescript-eslint/ban-types': [0],
    'comma-dangle': [0],
    'quote-props': [0],
    'no-multi-spaces': [0],
    'key-spacing': [0],
  },
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx']
    },
    'import/resolver': {
      node: {
        extensions: ['.js', '.ts']
      }
    }
  }
};
<commit_msg>Enable lint rule "key-spacing"<commit_after>/** @type {import('eslint').Linter.Config} */
module.exports = {
  'env': {
    'jest': true,
    'node': true
  },
  'extends': [
    'airbnb-base',
    'plugin:security/recommended',
    'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
  ],
  parser: '@typescript-eslint/parser', // Specifies the ESLint parser
  parserOptions: {
    ecmaVersion: 2018,  // Allows for the parsing of modern ECMAScript features
    sourceType: 'module',  // Allows for the use of imports
  },
  'plugins': [
    'import',
    'security',
    'jest'
  ],
  'rules': {
    'jest/no-disabled-tests': [2],
    'jest/no-focused-tests': [2],
    'jest/no-identical-title': [2],
    'jest/prefer-to-have-length': [2],
    'jest/valid-expect': [2],

    '@typescript-eslint/no-empty-interface': [2],
    '@typescript-eslint/no-explicit-any': [2],
    '@typescript-eslint/no-var-requires': [2],
    'import/prefer-default-export': [0],
    'import/extensions': ['error', 'ignorePackages', {
      js: 'never',
      ts: 'never',
    }],
    // TODO: Enable these lint rules:
    // They were disabled to facilitate the transition to TypeScript
    '@typescript-eslint/explicit-function-return-type': [0],
    // These rules disabled during the dependency upgrade on 2020-07-06
    // Check these and re-enable
    '@typescript-eslint/class-name-casing': [0],
    '@typescript-eslint/ban-ts-ignore': [0],
    '@typescript-eslint/ban-types': [0],
    'comma-dangle': [0],
    'quote-props': [0],
    'no-multi-spaces': [0],
  },
  settings: {
    'import/parsers': {
      '@typescript-eslint/parser': ['.ts', '.tsx']
    },
    'import/resolver': {
      node: {
        extensions: ['.js', '.ts']
      }
    }
  }
};
<|endoftext|>


<commit_before>var SteamCommunity = require('../index.js');

SteamCommunity.prototype.getWebApiOauthToken = function(callback) {
	var self = this;

	// Pull an oauth token from the webchat UI
	this.request("https://steamcommunity.com/chat", function(err, response, body) {
		if(self._checkHttpError(err, response, callback)) {
			return;
		}

		var match = body.match(/"([0-9a-f]{32})"/);
		if (!match) {
			callback(new Error("Malformed response"));
			return;
		}

		callback(null, match[1]);
	});
};
<commit_msg>Added check for community error when getting webapi oauth token<commit_after>var SteamCommunity = require('../index.js');

SteamCommunity.prototype.getWebApiOauthToken = function(callback) {
	var self = this;

	// Pull an oauth token from the webchat UI
	this.request("https://steamcommunity.com/chat", function(err, response, body) {
		if(self._checkHttpError(err, response, callback)) {
			return;
		}

		if(self._checkCommunityError(body, callback)) {
			return;
		}

		var match = body.match(/"([0-9a-f]{32})"/);
		if (!match) {
			callback(new Error("Malformed response"));
			return;
		}

		callback(null, match[1]);
	});
};
<|endoftext|>


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

// Native
const http = require('http');
const path = require('path');
const fs = require('fs');
const {promisify} = require('util');
const {parse} = require('url');
const os = require('os');

// Packages
const Ajv = require('ajv');
const checkForUpdate = require('update-check');
const chalk = require('chalk');
const arg = require('arg');
const {write: copy} = require('clipboardy');
const handler = require('serve-handler');
const schema = require('@zeit/schemas/deployment/config-static');
const boxen = require('boxen');
const compression = require('compression');

// Utilities
const pkg = require('../package');

const readFile = promisify(fs.readFile);
const compressionHandler = promisify(compression());

const interfaces = os.networkInterfaces();

const warning = (message) => chalk`{yellow WARNING:} ${message}`;
const info = (message) => chalk`{magenta INFO:} ${message}`;
const error = (message) => chalk`{red ERROR:} ${message}`;

const updateCheck = async (isDebugging) => {
	let update = null;

	try {
		update = await checkForUpdate(pkg);
	} catch (err) {
		const suffix = isDebugging ? ':' : ' (use `--debug` to see full error)';
		console.error(warning(`Checking for updates failed${suffix}`));

		if (isDebugging) {
			console.error(err);
		}
	}

	if (!update) {
		return;
	}

	console.log(`${chalk.bgRed('UPDATE AVAILABLE')} The latest version of \`serve\` is ${update.latest}`);
};

const getHelp = () => chalk`
  {bold.cyan serve} - Static file serving and directory listing

  {bold USAGE}

      {bold $} {cyan serve} --help
      {bold $} {cyan serve} --version
      {bold $} {cyan serve} [-l {underline listen_uri} [-l ...]] [{underline directory}]

      By default, {cyan serve} will listen on {bold 0.0.0.0:5000} and serve the
      current working directory on that address.

      Specifying a single {bold --listen} argument will overwrite the default, not supplement it.

  {bold OPTIONS}

      --help                              Shows this help message

      -v, --version                       Displays the current version of serve

      -l, --listen {underline listen_uri}             Specify a URI endpoint on which to listen (see below) -
                                          more than one may be specified to listen in multiple places

      -d, --debug                         Show debugging information

      -s, --single                        Rewrite all not-found requests to \`index.html\`

      -c, --config                        Specify custom path to \`serve.json\`

      -n, --no-clipboard                  Do not copy the local address to the clipboard

      -u, --no-compression                Do not compress files

      --no-etag                           Send \`Last-Modified\` header instead of \`ETag\`

      -S, --symlinks                      Resolve symlinks instead of showing 404 errors

  {bold ENDPOINTS}

      Listen endpoints (specified by the {bold --listen} or {bold -l} options above) instruct {cyan serve}
      to listen on one or more interfaces/ports, UNIX domain sockets, or Windows named pipes.

      For TCP ports on hostname "localhost":

          {bold $} {cyan serve} -l {underline 1234}

      For TCP (traditional host/port) endpoints:

          {bold $} {cyan serve} -l tcp://{underline hostname}:{underline 1234}

      For UNIX domain socket endpoints:

          {bold $} {cyan serve} -l unix:{underline /path/to/socket.sock}

      For Windows named pipe endpoints:

          {bold $} {cyan serve} -l pipe:\\\\.\\pipe\\{underline PipeName}
`;

const parseEndpoint = (str) => {
	if (!isNaN(str)) {
		return [str];
	}

	// We cannot use `new URL` here, otherwise it will not
	// parse the host properly and it would drop support for IPv6.
	const url = parse(str);

	switch (url.protocol) {
	case 'pipe:': {
		// some special handling
		const cutStr = str.replace(/^pipe:/, '');

		if (cutStr.slice(0, 4) !== '\\\\.\\') {
			throw new Error(`Invalid Windows named pipe endpoint: ${str}`);
		}

		return [cutStr];
	}
	case 'unix:':
		if (!url.pathname) {
			throw new Error(`Invalid UNIX domain socket endpoint: ${str}`);
		}

		return [url.pathname];
	case 'tcp:':
		url.port = url.port || '5000';
		return [parseInt(url.port, 10), url.hostname];
	default:
		throw new Error(`Unknown --listen endpoint scheme (protocol): ${url.protocol}`);
	}
};

const registerShutdown = (fn) => {
	let run = false;

	const wrapper = () => {
		if (!run) {
			run = true;
			fn();
		}
	};

	process.on('SIGINT', wrapper);
	process.on('SIGTERM', wrapper);
	process.on('exit', wrapper);
};

const getNetworkAddress = () => {
	for (const name of Object.keys(interfaces)) {
		for (const interface of interfaces[name]) {
			const {address, family, internal} = interface;
			if (family === 'IPv4' && !internal) {
				return address;
			}
		}
	}
};

const startEndpoint = (endpoint, config, args, previous) => {
	const {isTTY} = process.stdout;
	const clipboard = args['--no-clipboard'] !== true;
	const compress = args['--no-compression'] !== true;

	const server = http.createServer(async (request, response) => {
		if (compress) {
			await compressionHandler(request, response);
		}

		return handler(request, response, config);
	});

	server.on('error', (err) => {
		if (err.code === 'EADDRINUSE' && endpoint.length === 1 && !isNaN(endpoint[0])) {
			startEndpoint([0], config, args, endpoint[0]);
			return;
		}

		console.error(error(`Failed to serve: ${err.stack}`));
		process.exit(1);
	});

	server.listen(...endpoint, async () => {
		const details = server.address();
		registerShutdown(() => server.close());

		let localAddress = null;
		let networkAddress = null;

		if (typeof details === 'string') {
			localAddress = details;
		} else if (typeof details === 'object' && details.port) {
			const address = details.address === '::' ? 'localhost' : details.address;
			const ip = getNetworkAddress();

			localAddress = `http://${address}:${details.port}`;
			networkAddress = `http://${ip}:${details.port}`;
		}

		if (isTTY && process.env.NODE_ENV !== 'production') {
			let message = chalk.green('Serving!');

			if (localAddress) {
				const prefix = networkAddress ? '- ' : '';
				const space = networkAddress ? '            ' : '  ';

				message += `\n\n${chalk.bold(`${prefix}Local:`)}${space}${localAddress}`;
			}

			if (networkAddress) {
				message += `\n${chalk.bold('- On Your Network:')}  ${networkAddress}`;
			}

			if (previous) {
				message += chalk.red(`\n\nThis port was picked because ${chalk.underline(previous)} is in use.`);
			}

			if (clipboard) {
				try {
					await copy(localAddress);
					message += `\n\n${chalk.grey('Copied local address to clipboard!')}`;
				} catch (err) {
					console.error(error(`Cannot copy to clipboard: ${err.message}`));
				}
			}

			console.log(boxen(message, {
				padding: 1,
				borderColor: 'green',
				margin: 1
			}));
		} else {
			const suffix = localAddress ? ` at ${localAddress}` : '';
			console.log(info(`Accepting connections${suffix}`));
		}
	});
};

const loadConfig = async (cwd, entry, args) => {
	const files = [
		'serve.json',
		'now.json',
		'package.json'
	];

	if (args['--config']) {
		files.unshift(args['--config']);
	}

	const config = {};

	for (const file of files) {
		const location = path.resolve(entry, file);
		let content = null;

		try {
			content = await readFile(location, 'utf8');
		} catch (err) {
			if (err.code === 'ENOENT') {
				continue;
			}

			console.error(error(`Not able to read ${location}: ${err.message}`));
			process.exit(1);
		}

		try {
			content = JSON.parse(content);
		} catch (err) {
			console.error(error(`Could not parse ${location} as JSON: ${err.message}`));
			process.exit(1);
		}

		if (typeof content !== 'object') {
			console.error(warning(`Didn't find a valid object in ${location}. Skipping...`));
			continue;
		}

		try {
			switch (file) {
			case 'now.json':
				content = content.static;
				break;
			case 'package.json':
				content = content.now.static;
				break;
			}
		} catch (err) {
			continue;
		}

		Object.assign(config, content);
		console.log(info(`Discovered configuration in \`${file}\``));

		if (file === 'now.json' || file === 'package.json') {
			console.error(warning('The config files `now.json` and `package.json` are deprecated. Please use `serve.json`.'));
		}

		break;
	}

	if (entry) {
		const {public} = config;
		config.public = path.relative(cwd, (public ? path.resolve(entry, public) : entry));
	}

	if (Object.keys(config).length !== 0) {
		const ajv = new Ajv();
		const validateSchema = ajv.compile(schema);

		if (!validateSchema(config)) {
			const defaultMessage = error('The configuration you provided is wrong:');
			const {message, params} = validateSchema.errors[0];

			console.error(`${defaultMessage}\n${message}\n${JSON.stringify(params)}`);
			process.exit(1);
		}
	}

	// "ETag" headers are enabled by default unless `--no-etag` is provided
	config.etag = !args['--no-etag'];

	return config;
};

(async () => {
	let args = null;

	try {
		args = arg({
			'--help': Boolean,
			'--version': Boolean,
			'--listen': [parseEndpoint],
			'--single': Boolean,
			'--debug': Boolean,
			'--config': String,
			'--no-clipboard': Boolean,
			'--no-compression': Boolean,
			'--no-etag': Boolean,
			'--symlinks': Boolean,
			'-h': '--help',
			'-v': '--version',
			'-l': '--listen',
			'-s': '--single',
			'-d': '--debug',
			'-c': '--config',
			'-n': '--no-clipboard',
			'-u': '--no-compression',
			'-S': '--symlinks',
			// This is deprecated and only for backwards-compatibility.
			'-p': '--listen'
		});
	} catch (err) {
		console.error(error(err.message));
		process.exit(1);
	}

	if (process.env.NO_UPDATE_CHECK !== '1') {
		await updateCheck(args['--debug']);
	}

	if (args['--version']) {
		console.log(pkg.version);
		return;
	}

	if (args['--help']) {
		console.log(getHelp());
		return;
	}

	if (!args['--listen']) {
		// Default endpoint
		args['--listen'] = [[process.env.PORT || 5000]];
	}

	if (args._.length > 1) {
		console.error(error('Please provide one path argument at maximum'));
		process.exit(1);
	}

	const cwd = process.cwd();
	const entry = args._.length > 0 ? path.resolve(args._[0]) : cwd;

	const config = await loadConfig(cwd, entry, args);

	if (args['--single']) {
		const {rewrites} = config;
		const existingRewrites = Array.isArray(rewrites) ? rewrites : [];

		// As the first rewrite rule, make `--single` work
		config.rewrites = [{
			source: '**',
			destination: '/index.html'
		}, ...existingRewrites];
	}

	if (args['--symlinks']) {
		config.symlinks = true;
	}

	for (const endpoint of args['--listen']) {
		startEndpoint(endpoint, config, args);
	}

	registerShutdown(() => {
		console.log(`\n${info('Gracefully shutting down. Please wait...')}`);

		process.on('SIGINT', () => {
			console.log(`\n${warning('Force-closing all open sockets...')}`);
			process.exit(0);
		});
	});
})();
<commit_msg>Add support for manual SSL certs/keys (#520)<commit_after>#!/usr/bin/env node

// Native
const http = require('http');
const https = require('https');
const path = require('path');
const fs = require('fs');
const {promisify} = require('util');
const {parse} = require('url');
const os = require('os');

// Packages
const Ajv = require('ajv');
const checkForUpdate = require('update-check');
const chalk = require('chalk');
const arg = require('arg');
const {write: copy} = require('clipboardy');
const handler = require('serve-handler');
const schema = require('@zeit/schemas/deployment/config-static');
const boxen = require('boxen');
const compression = require('compression');

// Utilities
const pkg = require('../package');

const readFile = promisify(fs.readFile);
const compressionHandler = promisify(compression());

const interfaces = os.networkInterfaces();

const warning = (message) => chalk`{yellow WARNING:} ${message}`;
const info = (message) => chalk`{magenta INFO:} ${message}`;
const error = (message) => chalk`{red ERROR:} ${message}`;

const updateCheck = async (isDebugging) => {
	let update = null;

	try {
		update = await checkForUpdate(pkg);
	} catch (err) {
		const suffix = isDebugging ? ':' : ' (use `--debug` to see full error)';
		console.error(warning(`Checking for updates failed${suffix}`));

		if (isDebugging) {
			console.error(err);
		}
	}

	if (!update) {
		return;
	}

	console.log(`${chalk.bgRed('UPDATE AVAILABLE')} The latest version of \`serve\` is ${update.latest}`);
};

const getHelp = () => chalk`
  {bold.cyan serve} - Static file serving and directory listing

  {bold USAGE}

      {bold $} {cyan serve} --help
      {bold $} {cyan serve} --version
      {bold $} {cyan serve} [-l {underline listen_uri} [-l ...]] [{underline directory}]

      By default, {cyan serve} will listen on {bold 0.0.0.0:5000} and serve the
      current working directory on that address.

      Specifying a single {bold --listen} argument will overwrite the default, not supplement it.

  {bold OPTIONS}

      --help                              Shows this help message

      -v, --version                       Displays the current version of serve

      -l, --listen {underline listen_uri}             Specify a URI endpoint on which to listen (see below) -
                                          more than one may be specified to listen in multiple places

      -d, --debug                         Show debugging information

      -s, --single                        Rewrite all not-found requests to \`index.html\`

      -c, --config                        Specify custom path to \`serve.json\`

      -n, --no-clipboard                  Do not copy the local address to the clipboard

      -u, --no-compression                Do not compress files

      --no-etag                           Send \`Last-Modified\` header instead of \`ETag\`

      -S, --symlinks                      Resolve symlinks instead of showing 404 errors

      --ssl-cert                          Optional path to an SSL/TLS certificate to serve with HTTPS

      --ssl-key                           Optional path to the SSL/TLS certificate\'s private key

  {bold ENDPOINTS}

      Listen endpoints (specified by the {bold --listen} or {bold -l} options above) instruct {cyan serve}
      to listen on one or more interfaces/ports, UNIX domain sockets, or Windows named pipes.

      For TCP ports on hostname "localhost":

          {bold $} {cyan serve} -l {underline 1234}

      For TCP (traditional host/port) endpoints:

          {bold $} {cyan serve} -l tcp://{underline hostname}:{underline 1234}

      For UNIX domain socket endpoints:

          {bold $} {cyan serve} -l unix:{underline /path/to/socket.sock}

      For Windows named pipe endpoints:

          {bold $} {cyan serve} -l pipe:\\\\.\\pipe\\{underline PipeName}
`;

const parseEndpoint = (str) => {
	if (!isNaN(str)) {
		return [str];
	}

	// We cannot use `new URL` here, otherwise it will not
	// parse the host properly and it would drop support for IPv6.
	const url = parse(str);

	switch (url.protocol) {
	case 'pipe:': {
		// some special handling
		const cutStr = str.replace(/^pipe:/, '');

		if (cutStr.slice(0, 4) !== '\\\\.\\') {
			throw new Error(`Invalid Windows named pipe endpoint: ${str}`);
		}

		return [cutStr];
	}
	case 'unix:':
		if (!url.pathname) {
			throw new Error(`Invalid UNIX domain socket endpoint: ${str}`);
		}

		return [url.pathname];
	case 'tcp:':
		url.port = url.port || '5000';
		return [parseInt(url.port, 10), url.hostname];
	default:
		throw new Error(`Unknown --listen endpoint scheme (protocol): ${url.protocol}`);
	}
};

const registerShutdown = (fn) => {
	let run = false;

	const wrapper = () => {
		if (!run) {
			run = true;
			fn();
		}
	};

	process.on('SIGINT', wrapper);
	process.on('SIGTERM', wrapper);
	process.on('exit', wrapper);
};

const getNetworkAddress = () => {
	for (const name of Object.keys(interfaces)) {
		for (const interface of interfaces[name]) {
			const {address, family, internal} = interface;
			if (family === 'IPv4' && !internal) {
				return address;
			}
		}
	}
};

const startEndpoint = (endpoint, config, args, previous) => {
	const {isTTY} = process.stdout;
	const clipboard = args['--no-clipboard'] !== true;
	const compress = args['--no-compression'] !== true;
	const httpMode = args['--ssl-cert'] && args['--ssl-key'] ? 'https' : 'http';

	const serverHandler = async (request, response) => {
		if (compress) {
			await compressionHandler(request, response);
		}

		return handler(request, response, config);
	};

	const server = httpMode === 'https'
		? https.createServer({
			key: fs.readFileSync(args['--ssl-key']),
			cert: fs.readFileSync(args['--ssl-cert'])
		}, serverHandler)
		: http.createServer(serverHandler);

	server.on('error', (err) => {
		if (err.code === 'EADDRINUSE' && endpoint.length === 1 && !isNaN(endpoint[0])) {
			startEndpoint([0], config, args, endpoint[0]);
			return;
		}

		console.error(error(`Failed to serve: ${err.stack}`));
		process.exit(1);
	});

	server.listen(...endpoint, async () => {
		const details = server.address();
		registerShutdown(() => server.close());

		let localAddress = null;
		let networkAddress = null;

		if (typeof details === 'string') {
			localAddress = details;
		} else if (typeof details === 'object' && details.port) {
			const address = details.address === '::' ? 'localhost' : details.address;
			const ip = getNetworkAddress();

			localAddress = `${httpMode}://${address}:${details.port}`;
			networkAddress = `${httpMode}://${ip}:${details.port}`;
		}

		if (isTTY && process.env.NODE_ENV !== 'production') {
			let message = chalk.green('Serving!');

			if (localAddress) {
				const prefix = networkAddress ? '- ' : '';
				const space = networkAddress ? '            ' : '  ';

				message += `\n\n${chalk.bold(`${prefix}Local:`)}${space}${localAddress}`;
			}

			if (networkAddress) {
				message += `\n${chalk.bold('- On Your Network:')}  ${networkAddress}`;
			}

			if (previous) {
				message += chalk.red(`\n\nThis port was picked because ${chalk.underline(previous)} is in use.`);
			}

			if (clipboard) {
				try {
					await copy(localAddress);
					message += `\n\n${chalk.grey('Copied local address to clipboard!')}`;
				} catch (err) {
					console.error(error(`Cannot copy to clipboard: ${err.message}`));
				}
			}

			console.log(boxen(message, {
				padding: 1,
				borderColor: 'green',
				margin: 1
			}));
		} else {
			const suffix = localAddress ? ` at ${localAddress}` : '';
			console.log(info(`Accepting connections${suffix}`));
		}
	});
};

const loadConfig = async (cwd, entry, args) => {
	const files = [
		'serve.json',
		'now.json',
		'package.json'
	];

	if (args['--config']) {
		files.unshift(args['--config']);
	}

	const config = {};

	for (const file of files) {
		const location = path.resolve(entry, file);
		let content = null;

		try {
			content = await readFile(location, 'utf8');
		} catch (err) {
			if (err.code === 'ENOENT') {
				continue;
			}

			console.error(error(`Not able to read ${location}: ${err.message}`));
			process.exit(1);
		}

		try {
			content = JSON.parse(content);
		} catch (err) {
			console.error(error(`Could not parse ${location} as JSON: ${err.message}`));
			process.exit(1);
		}

		if (typeof content !== 'object') {
			console.error(warning(`Didn't find a valid object in ${location}. Skipping...`));
			continue;
		}

		try {
			switch (file) {
			case 'now.json':
				content = content.static;
				break;
			case 'package.json':
				content = content.now.static;
				break;
			}
		} catch (err) {
			continue;
		}

		Object.assign(config, content);
		console.log(info(`Discovered configuration in \`${file}\``));

		if (file === 'now.json' || file === 'package.json') {
			console.error(warning('The config files `now.json` and `package.json` are deprecated. Please use `serve.json`.'));
		}

		break;
	}

	if (entry) {
		const {public} = config;
		config.public = path.relative(cwd, (public ? path.resolve(entry, public) : entry));
	}

	if (Object.keys(config).length !== 0) {
		const ajv = new Ajv();
		const validateSchema = ajv.compile(schema);

		if (!validateSchema(config)) {
			const defaultMessage = error('The configuration you provided is wrong:');
			const {message, params} = validateSchema.errors[0];

			console.error(`${defaultMessage}\n${message}\n${JSON.stringify(params)}`);
			process.exit(1);
		}
	}

	// "ETag" headers are enabled by default unless `--no-etag` is provided
	config.etag = !args['--no-etag'];

	return config;
};

(async () => {
	let args = null;

	try {
		args = arg({
			'--help': Boolean,
			'--version': Boolean,
			'--listen': [parseEndpoint],
			'--single': Boolean,
			'--debug': Boolean,
			'--config': String,
			'--no-clipboard': Boolean,
			'--no-compression': Boolean,
			'--no-etag': Boolean,
			'--symlinks': Boolean,
			'--ssl-cert': String,
			'--ssl-key': String,
			'-h': '--help',
			'-v': '--version',
			'-l': '--listen',
			'-s': '--single',
			'-d': '--debug',
			'-c': '--config',
			'-n': '--no-clipboard',
			'-u': '--no-compression',
			'-S': '--symlinks',
			// This is deprecated and only for backwards-compatibility.
			'-p': '--listen'
		});
	} catch (err) {
		console.error(error(err.message));
		process.exit(1);
	}

	if (process.env.NO_UPDATE_CHECK !== '1') {
		await updateCheck(args['--debug']);
	}

	if (args['--version']) {
		console.log(pkg.version);
		return;
	}

	if (args['--help']) {
		console.log(getHelp());
		return;
	}

	if (!args['--listen']) {
		// Default endpoint
		args['--listen'] = [[process.env.PORT || 5000]];
	}

	if (args._.length > 1) {
		console.error(error('Please provide one path argument at maximum'));
		process.exit(1);
	}

	const cwd = process.cwd();
	const entry = args._.length > 0 ? path.resolve(args._[0]) : cwd;

	const config = await loadConfig(cwd, entry, args);

	if (args['--single']) {
		const {rewrites} = config;
		const existingRewrites = Array.isArray(rewrites) ? rewrites : [];

		// As the first rewrite rule, make `--single` work
		config.rewrites = [{
			source: '**',
			destination: '/index.html'
		}, ...existingRewrites];
	}

	if (args['--symlinks']) {
		config.symlinks = true;
	}

	for (const endpoint of args['--listen']) {
		startEndpoint(endpoint, config, args);
	}

	registerShutdown(() => {
		console.log(`\n${info('Gracefully shutting down. Please wait...')}`);

		process.on('SIGINT', () => {
			console.log(`\n${warning('Force-closing all open sockets...')}`);
			process.exit(0);
		});
	});
})();
<|endoftext|>


<commit_before>/**
 * Created by Muthu on 28/11/16.
 */

var prompt_lib		                = require('prompt');
var manager_builder                 = require('./manager');
var async                           = require('async');
var lib 			= require('./lib');

function baseAdapter () {
    this.adapterContext = {};

    this.doTask = function(taskName,context,resourceName,subResourceName, params, cb) {

        /*
        var rName                           = config.configName;
        if (!this.adapterContext[rName]) {
            this.adapterContext[rName]      = {};
        }

        if (!this.adapterContext[rName].initialized) {
            this.prompt(context,config);
            this.adapterContext[rName].initialized = true;
        }
        */

        //TODO: check the taskName and call appropriate function

        switch (taskName.toUpperCase()) {
            case 'CLEAN' : this.clean (context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'BUILD' : this.build (context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'DEPLOY': this.deploy(context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'PROMPT': this.prompt(context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
        }

    },

    //do the same activity for all subresources/resources; don't override
    this.gotoSubResources = function(taskName, context, resourceName, subResourceName, params, cb) {
        var manager                         = manager_builder.getManager();

        console.log('climbing down the tree ... ')

        var config                          = context.getConfig(resourceName);

        var resourceType                    = config.type;

        if (!config) return;

        var subResources;

        if(taskName.toUpperCase() != 'CLEAN'){
            subResources                        = config.properties.subResources;
        } else {
            subResources                        = config.properties.subResources;
            subResources.reverse();
        }

        if (subResources && subResources.length > 0) {
            console.log('deploying all subresources')
            // TODO async or promise

            async.eachSeries(subResources,
                function (subResource, callback) {
                    var subResourceType         = subResource.type;
                    var subResourceName         = subResource.name;

                    var adapter                 = manager.getAdapter(resourceType, subResourceType);

                    adapter.doTask(taskName, context, resourceName, subResourceName, params, function (err, result) {
                        if(!err) {
                           callback()
                       } else {
                           callback(err)
                       }
                    });
                },

                function (err) {
                    if(taskName.toUpperCase() == 'CLEAN'){
                        subResources.reverse();
                    }

                    if(!err) {
                        cb()
                    } else {
                        lib.print('ERROR',err);
                        cb(err)
                    }

                }
            );

            //use promise - synchronous invocation
            //loop through subresources
            //for each sub-resource get its adapter based on the resource & subResource type
            //config.configName = getName(resourceName, subResourceName);
            //call doTask on the subresource adapter with the subresource config. (set resourceType and resourceName attributes for the subresource config before passing, when getConfig() is not used
            //if there is an error then log the error (getLog().logErrorStatus(config, error))

        }
    },

    this.clean = function(context, resourceName, subResourceName, params, cb) {
        console.log('base clean');
        this.gotoSubResources();
    },

    this.build = function(context, resourceName, subResourceName, params, cb) {
        console.log('base build');
        this.gotoSubResources();
    },

    this.deploy = function(context, resourceName, subResourceName, params, cb) {
        console.log('base deploy');
        this.gotoSubResources();
    },

    this.isAsynchable = function() {
        return false;
    }

    this.prompt = function(context, resourceName, subResourceName, params, cb) {
        var config = context.getConfig(resourceName);
        if (config.properties.inputs && config.properties.inputs.length > 0) {
            var inputs = config.properties.inputs;

            var required_values = [];

            for(var i=0; i<inputs.length; i++){
                if(!context.getVariable(inputs[i].name) && !context.getVariable(inputs[i].ifNotPresent)) {
                    required_values.push({name: inputs[i].name, description: inputs[i].prompt, type: 'string'});
                }
            }

            prompt_lib.start();

            prompt_lib.get(required_values, function(err, results) {
                var keys = Object.keys(results)
                for(var i=0; i<keys.length; i++){
                    context.setVariable(keys[i], results[keys[i]])
                }
                cb(err, results);
            });
        }

        //check is there inputParams for the specific config
        //check whether all inputParams are found in context.getVariable(); if not prompt and store the input value in the variables (setVariable())

    }
}

exports.baseAdapter 			= new baseAdapter();<commit_msg>password invisible<commit_after>/**
 * Created by Muthu on 28/11/16.
 */

var prompt_lib		                = require('prompt');
var manager_builder                 = require('./manager');
var async                           = require('async');
var lib 			= require('./lib');

function baseAdapter () {
    this.adapterContext = {};

    this.doTask = function(taskName,context,resourceName,subResourceName, params, cb) {

        /*
        var rName                           = config.configName;
        if (!this.adapterContext[rName]) {
            this.adapterContext[rName]      = {};
        }

        if (!this.adapterContext[rName].initialized) {
            this.prompt(context,config);
            this.adapterContext[rName].initialized = true;
        }
        */

        //TODO: check the taskName and call appropriate function

        switch (taskName.toUpperCase()) {
            case 'CLEAN' : this.clean (context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'BUILD' : this.build (context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'DEPLOY': this.deploy(context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
            case 'PROMPT': this.prompt(context, resourceName, subResourceName, params, function (err, result) {
                cb(err, result)
            }); break;
        }

    },

    //do the same activity for all subresources/resources; don't override
    this.gotoSubResources = function(taskName, context, resourceName, subResourceName, params, cb) {
        var manager                         = manager_builder.getManager();

        console.log('climbing down the tree ... ')

        var config                          = context.getConfig(resourceName);

        var resourceType                    = config.type;

        if (!config) return;

        var subResources;

        if(taskName.toUpperCase() != 'CLEAN'){
            subResources                        = config.properties.subResources;
        } else {
            subResources                        = config.properties.subResources;
            subResources.reverse();
        }

        if (subResources && subResources.length > 0) {
            console.log('deploying all subresources')
            // TODO async or promise

            async.eachSeries(subResources,
                function (subResource, callback) {
                    var subResourceType         = subResource.type;
                    var subResourceName         = subResource.name;

                    var adapter                 = manager.getAdapter(resourceType, subResourceType);

                    adapter.doTask(taskName, context, resourceName, subResourceName, params, function (err, result) {
                        if(!err) {
                           callback()
                       } else {
                           callback(err)
                       }
                    });
                },

                function (err) {
                    if(taskName.toUpperCase() == 'CLEAN'){
                        subResources.reverse();
                    }

                    if(!err) {
                        cb()
                    } else {
                        lib.print('ERROR',err);
                        cb(err)
                    }

                }
            );

            //use promise - synchronous invocation
            //loop through subresources
            //for each sub-resource get its adapter based on the resource & subResource type
            //config.configName = getName(resourceName, subResourceName);
            //call doTask on the subresource adapter with the subresource config. (set resourceType and resourceName attributes for the subresource config before passing, when getConfig() is not used
            //if there is an error then log the error (getLog().logErrorStatus(config, error))

        }
    },

    this.clean = function(context, resourceName, subResourceName, params, cb) {
        console.log('base clean');
        this.gotoSubResources();
    },

    this.build = function(context, resourceName, subResourceName, params, cb) {
        console.log('base build');
        this.gotoSubResources();
    },

    this.deploy = function(context, resourceName, subResourceName, params, cb) {
        console.log('base deploy');
        this.gotoSubResources();
    },

    this.isAsynchable = function() {
        return false;
    }

    this.prompt = function(context, resourceName, subResourceName, params, cb) {
        var config = context.getConfig(resourceName);
        if (config.properties.inputs && config.properties.inputs.length > 0) {
            var inputs = config.properties.inputs;

            var required_values = [];

            for(var i=0; i<inputs.length; i++){
                if(!context.getVariable(inputs[i].name) && !context.getVariable(inputs[i].ifNotPresent)) {
                    if(inputs[i].name != 'password') {
                        required_values.push({name: inputs[i].name, description: inputs[i].prompt, type: 'string'});
                    } else {
                        required_values.push({name: inputs[i].name, description: inputs[i].prompt, type: 'string', hidden: true});
                    }
                }
            }

            prompt_lib.start();

            prompt_lib.get(required_values, function(err, results) {
                var keys = Object.keys(results)
                for(var i=0; i<keys.length; i++){
                    context.setVariable(keys[i], results[keys[i]])
                }
                cb(err, results);
            });
        }

        //check is there inputParams for the specific config
        //check whether all inputParams are found in context.getVariable(); if not prompt and store the input value in the variables (setVariable())

    }
}

exports.baseAdapter 			= new baseAdapter();<|endoftext|>


<commit_before>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Dashboard Chart', {
	refresh: function(frm) {

	}
});
<commit_msg>feat(dashboard): Provide modal to update filters<commit_after>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.provide("frappe.dashboard_chart_sources");

frappe.ui.form.on('Dashboard Chart', {
	refresh: function(frm) {
		frm.trigger("show_filters");
	},

	source: function(frm) {
		frm.trigger("show_filters");
	},

	show_filters: function(frm) {
		if (frm.doc.source) {
			if (frappe.dashboard_chart_sources && frappe.dashboard_chart_sources[frm.doc.source]) {
				frm.trigger('render_filters_table');
			} else {
				frappe.call({
					method: 'frappe.core.page.dashboard.dashboard.get_script',
					args: {
						source_name: frm.doc.source
					},
					callback: result => {
						frappe.dom.eval(result.message.script || '');
						frm.trigger('render_filters_table');
					}
				});
			}
		}
	},

	render_filters_table: function(frm) {
		let fields = frappe.dashboard_chart_sources[frm.doc.source].filters;

		let wrapper = $(frm.get_field('filters_json').wrapper).empty();
		let table = $(`

					${__('Filter')}
					${__('Value')}

`).appendTo(wrapper);
		$(`<p class="text-muted small">${__("Click table to edit")}</p>`).appendTo(wrapper);

		let filters = JSON.parse(frm.doc.filters_json || '{}');
		fields.map( f => {
			const filter_row = $(`<tr><td>${f.label}</td><td>${filters[f.fieldname]}</td></tr>`);
			table.find('tbody').append(filter_row);
		});

		table.on('click', () => {
			let dialog = new frappe.ui.Dialog({
				title: __('Set Filters'),
				fields: fields,
				primary_action: function() {
					let values = this.get_values();
					if(values) {
						this.hide();
						frm.set_value('filters_json', JSON.stringify(values));
						frm.trigger('show_filters');
					}
				}
			});
			dialog.show();
			dialog.set_values(filters);
		});
	}
});

<|endoftext|>


<commit_before>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import NumberInput from 'grommet/components/NumberInput';
import Form from 'grommet/components/Form';
import FormField from 'grommet/components/FormField';
import DocsArticle from '../../components/DocsArticle';
import Example from '../Example';

NumberInput.displayName = 'NumberInput';

const USAGE =
`import NumberInput from 'grommet/components/NumberInput';
<NumberInput value={} onChange={} />`;

export default class NumberInputDoc extends Component {

  constructor () {
    super();
    this._onChange = this._onChange.bind(this);
    this.state = { value: 10 };
  }

  _onChange (event) {
    this.setState({value: parseInt(event.target.value)});
  }

  render () {
    return (
      <DocsArticle title="NumberInput" colorIndex="neutral-3">

A number input in a web form. We have a separate component from the
            browser base so we can style it.

          <Form>
            <FormField>
              <NumberInput id="item1" name="item1" label="Item 1"
                value={this.state.value} onChange={this._onChange} />
            </FormField>
          </Form>

Usage

{USAGE}

Properties

ariaDescribedby {"{string}"}

Optional attribute to enhance accessibility in case the
              this is used inside a context.

defaultValue  {"{number}"}

Same as React {"<input defaultValue= >"}.

disabled        true|false

Same as React {"<input disabled= >"}.
              Also adds a hidden input element with the same name so
              form submissions work.

id              {"{string}"}

The DOM id attribute value to use for the underlying
              {"<input>"} element.

max             {"{number}"}

Maximum value.

min             {"{number}"}

Minimum value.

name            {"{string}"}

The DOM name attribute value to use for the underlying
              {"<input>"} element.

onChange        {"{function}"}

Same as React {"<input onChange= >"}.

step            {"{number}"}

Steps to increase and decrease by.

value           {"{number}"}

The value to put in the input.

Example

          <Example code={
            <Form>
              <FormField>
                <NumberInput id="item2" name="item2" label="Item 2"
                  value={this.state.value} onChange={this._onChange} />
              </FormField>
            </Form>
          } />

      </DocsArticle>
    );
  }
};
<commit_msg>Removed describedBy from NumberInput docs.<commit_after>// (C) Copyright 2014-2016 Hewlett Packard Enterprise Development LP

import React, { Component } from 'react';
import NumberInput from 'grommet/components/NumberInput';
import Form from 'grommet/components/Form';
import FormField from 'grommet/components/FormField';
import DocsArticle from '../../components/DocsArticle';
import Example from '../Example';

NumberInput.displayName = 'NumberInput';

const USAGE =
`import NumberInput from 'grommet/components/NumberInput';
<NumberInput value={} onChange={} />`;

export default class NumberInputDoc extends Component {

  constructor () {
    super();
    this._onChange = this._onChange.bind(this);
    this.state = { value: 10 };
  }

  _onChange (event) {
    this.setState({value: parseInt(event.target.value)});
  }

  render () {
    return (
      <DocsArticle title="NumberInput" colorIndex="neutral-3">

A number input in a web form. We have a separate component from the
            browser base so we can style it.

          <Form>
            <FormField>
              <NumberInput id="item1" name="item1" label="Item 1"
                value={this.state.value} onChange={this._onChange} />
            </FormField>
          </Form>

Usage

{USAGE}

Properties

defaultValue  {"{number}"}

Same as React {"<input defaultValue= >"}.

disabled        true|false

Same as React {"<input disabled= >"}.
              Also adds a hidden input element with the same name so
              form submissions work.

id              {"{string}"}

The DOM id attribute value to use for the underlying
              {"<input>"} element.

max             {"{number}"}

Maximum value.

min             {"{number}"}

Minimum value.

name            {"{string}"}

The DOM name attribute value to use for the underlying
              {"<input>"} element.

onChange        {"{function}"}

Same as React {"<input onChange= >"}.

step            {"{number}"}

Steps to increase and decrease by.

value           {"{number}"}

The value to put in the input.

Example

          <Example code={
            <Form>
              <FormField>
                <NumberInput id="item2" name="item2" label="Item 2"
                  value={this.state.value} onChange={this._onChange} />
              </FormField>
            </Form>
          } />

      </DocsArticle>
    );
  }
};
<|endoftext|>


<commit_before>$(function() {
    $('#report-user-modal').modal('#report-user-abuse', {delegate: '#page'});

    if($('#user_edit').exists()) {
        $('.more-all, .more-none').click(_pd(function() {
            var $this = $(this);
            $this.closest('li').find('input:not([disabled]').attr('checked', $this.hasClass('more-all'));
        }));
    }

    // Hide change password box
    $('#acct-password').hide();
    $('#change-acct-password').click(_pd(function() {
          $('#acct-password').fadeIn();
          $('#id_oldpassword').focus();
          $(this).closest('li').hide();
    }));

    // Show password box if there's an error in it.
    $('#acct-password .errorlist li').exists(function() {
        $('#acct-password').show();
        $('#change-acct-password').closest('li').hide();
    });

    // Display image inline
    var $avatar = $('.profile-photo .avatar'),
        $a = $('<a>', {'text': gettext('use original'), 'class': 'use-original delete', 'href': '#'}).hide();

    $avatar.attr('data-original', $avatar.attr('src'));
    function use_original() {
        $('.use-original').hide();
        $('#id_photo').val("");
        $avatar.attr('src', $avatar.attr('data-original'));
    }
    $a.click(_pd(use_original));

    $avatar.after($a);
    $('#id_photo').change(function() {
        var $li = $(this).closest('li'),
            file = $(this)[0].files[0],
            file_name = file.name || file.fileName;
        $li.find('.errorlist').remove();
        if(!file_name.match(/\.(jpg|png|jpeg)$/)) {
            $ul = $('<ul>', {'class': 'errorlist'});
            $ul.append($('<li>', {'text': gettext('Images must be either PNG or JPG.')}));
            $li.append($ul);
            use_original();
            return;
        }
        var img = $(this).objectUrl();
        if(img) {
            $a.css('display', 'inline');
            $avatar.attr('src', img);
        }
    });
});

// Hijack "Admin / Editor Log in" context menuitem.
$('#admin-login').click(function() {
    window.location = $(this).attr('data-url');
});
<commit_msg>let people upload .JPGs (bug 734231)<commit_after>$(function() {
    $('#report-user-modal').modal('#report-user-abuse', {delegate: '#page'});

    if($('#user_edit').exists()) {
        $('.more-all, .more-none').click(_pd(function() {
            var $this = $(this);
            $this.closest('li').find('input:not([disabled]').attr('checked', $this.hasClass('more-all'));
        }));
    }

    // Hide change password box
    $('#acct-password').hide();
    $('#change-acct-password').click(_pd(function() {
          $('#acct-password').fadeIn();
          $('#id_oldpassword').focus();
          $(this).closest('li').hide();
    }));

    // Show password box if there's an error in it.
    $('#acct-password .errorlist li').exists(function() {
        $('#acct-password').show();
        $('#change-acct-password').closest('li').hide();
    });

    // Display image inline
    var $avatar = $('.profile-photo .avatar'),
        $a = $('<a>', {'text': gettext('use original'), 'class': 'use-original delete', 'href': '#'}).hide();

    $avatar.attr('data-original', $avatar.attr('src'));
    function use_original() {
        $('.use-original').hide();
        $('#id_photo').val("");
        $avatar.attr('src', $avatar.attr('data-original'));
    }
    $a.click(_pd(use_original));

    $avatar.after($a);
    $('#id_photo').change(function() {
        var $li = $(this).closest('li'),
            file = $(this)[0].files[0],
            file_name = file.name || file.fileName;
        $li.find('.errorlist').remove();
        if(!file_name.match(/\.(jpg|png|jpeg)$/i)) {
            $ul = $('<ul>', {'class': 'errorlist'});
            $ul.append($('<li>', {'text': gettext('Images must be either PNG or JPG.')}));
            $li.append($ul);
            use_original();
            return;
        }
        var img = $(this).objectUrl();
        if(img) {
            $a.css('display', 'inline');
            $avatar.attr('src', img);
        }
    });
});

// Hijack "Admin / Editor Log in" context menuitem.
$('#admin-login').click(function() {
    window.location = $(this).attr('data-url');
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */
CLASS({
  package: 'foam.ui.md',
  name: 'CitationView',
  extends: 'foam.ui.md.DetailView',
  requires: [
  ],

  properties: [
    {
      name: 'model',
      defaultValueFn: function() {
        return this.data.model_;
      }
    },
    {
      name: 'className',
      defaultValue: 'md-citation-view'
    },
  ],

  methods: [
    function pickNameProperty() {
      var prop;
      if (this.model.LABEL) {
        prop = this.model.LABEL;
      } else if (this.model.NAME) {
        prop = this.model.NAME;
      } else {
        var props = this.model.getRuntimeProperties();
        var stringProps = [];
        for (var i = 0; i < props.length; i++) {
          var p = props[i];
          if (! p.hidden && p.name !== 'id' && p.model_.id === 'Property' || p.model_.id === 'StringProperty') {
            stringProps.push(p);
          }
        }
        for (var i = 0; i < stringProps.length; i++) {
          var p = stringProps[i];
          var pname = p.name.toLowerCase();
          if (pname.indexOf('name') > -1 || pname.indexOf('label') > -1) {
            prop = p;
            break;
          }
        }
        if (!prop && stringProps.length) prop = stringProps[0];
      }
      if (!prop) prop = this.model.ID;
      return prop;
    }
  ],

  templates: [
    function CSS() {/*
      .md-citation-view {
        align-items: center;
        border-bottom: 1px solid #eee;
        display: flex;
        min-height: 48px;
      }
    */},
    function toHTML() {/*
      <div id="<%= this.id %>" <%= this.cssClassAttr() %>>
        <%= this.createTemplateView(this.pickNameProperty().name, { mode: 'read-only', floatingLabel: false }) %>

    */},
  ]
});
<commit_msg>MD CitationView: Use this.model.getFeature('foo') not this.model.FOO<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */
CLASS({
  package: 'foam.ui.md',
  name: 'CitationView',
  extends: 'foam.ui.md.DetailView',
  requires: [
  ],

  properties: [
    {
      name: 'model',
      defaultValueFn: function() {
        return this.data.model_;
      }
    },
    {
      name: 'className',
      defaultValue: 'md-citation-view'
    },
  ],

  methods: [
    function pickNameProperty() {
      var prop = this.model.getFeature('label') || this.model.getFeature('name');
      if (!prop) {
        var props = this.model.getRuntimeProperties();
        var stringProps = [];
        for (var i = 0; i < props.length; i++) {
          var p = props[i];
          if (! p.hidden && p.name !== 'id' && p.model_.id === 'Property' || p.model_.id === 'StringProperty') {
            stringProps.push(p);
          }
        }
        for (var i = 0; i < stringProps.length; i++) {
          var p = stringProps[i];
          var pname = p.name.toLowerCase();
          if (pname.indexOf('name') > -1 || pname.indexOf('label') > -1) {
            prop = p;
            break;
          }
        }
        if (!prop && stringProps.length) prop = stringProps[0];
      }
      if (!prop) prop = this.model.getFeature('id');
      return prop;
    }
  ],

  templates: [
    function CSS() {/*
      .md-citation-view {
        align-items: center;
        border-bottom: 1px solid #eee;
        display: flex;
        min-height: 48px;
      }
    */},
    function toHTML() {/*
      <div id="<%= this.id %>" <%= this.cssClassAttr() %>>
        <%= this.createTemplateView(this.pickNameProperty().name, { mode: 'read-only', floatingLabel: false }) %>

    */},
  ]
});
<|endoftext|>


<commit_before>/*
 * Copyright IBM Corp. 2015-2017
 *
 * 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.
 */

// Configuration for eslint.
// See: https://eslint.org/docs/rules/

module.exports = {
    "env": {
        "es6": true,
        "node": true,
        "mocha": true
    },
    "plugins": [
        "chai-friendly"
    ],
    "extends": "eslint:recommended",
    "rules": {
        "accessor-pairs": "error",
        "array-bracket-newline": "error",
        "array-bracket-spacing": "off",
        "array-callback-return": "error",
        "array-element-newline": "off",
        "arrow-body-style": "error",
        "arrow-parens": "off",
        "arrow-spacing": [
            "error",
            {
                "after": true,
                "before": true
            }
        ],
        "block-scoped-var": "error",
        "block-spacing": "off",
        "brace-style": [
            "error",
            "1tbs",
            {
                "allowSingleLine": true
            }
        ],
        "callback-return": "error",
        "camelcase": "off",
        "capitalized-comments": "off",
        "class-methods-use-this": "off",
        "comma-dangle": "error",
        "comma-spacing": "off",
        "comma-style": [
            "error",
            "last"
        ],
        "complexity": "error",
        "computed-property-spacing": [
            "error",
            "never"
        ],
        "consistent-return": "off",
        "consistent-this": "error",
        "curly": "off",
        "default-case": "error",
        "dot-location": [
            "error",
            "property"
        ],
        "dot-notation": [
            "error",
            {
                "allowKeywords": true
            }
        ],
        "eol-last": "off",
        "eqeqeq": "off",
        "for-direction": "error",
        "func-call-spacing": "off",
        "func-name-matching": "off",
        "func-names": "off",
        "func-style": "off",
        "generator-star-spacing": "error",
        "global-require": "off",
        "guard-for-in": "error",
        "handle-callback-err": "off",
        "id-blacklist": "error",
        "id-length": "off",
        "id-match": "error",
        "indent": ["error", 2],
        "indent-legacy": "off",
        "init-declarations": "off",
        "jsx-quotes": "error",
        "key-spacing": "off",
        "keyword-spacing": "off",
        "line-comment-position": "off",
        "linebreak-style": [
            "error",
            "unix"
        ],
        "lines-around-comment": "off",
        "lines-around-directive": "off",
        "max-depth": "error",
        "max-len": "off",
        "max-lines": "off",
        "max-nested-callbacks": "error",
        "max-params": "error",
        "max-statements": "off",
        "max-statements-per-line": "off",
        "multiline-ternary": [
            "error",
            "never"
        ],
        "new-parens": "error",
        "newline-after-var": "off",
        "newline-before-return": "off",
        "newline-per-chained-call": "error",
        "no-alert": "error",
        "no-array-constructor": "error",
        "no-await-in-loop": "error",
        "no-bitwise": "error",
        "no-buffer-constructor": "off",
        "no-caller": "error",
        "no-catch-shadow": "error",
        "no-confusing-arrow": "error",
        "no-continue": "off",
        "no-div-regex": "error",
        "no-duplicate-imports": "error",
        "no-else-return": "off",
        "no-empty-function": "error",
        "no-eq-null": "error",
        "no-eval": "error",
        "no-extend-native": "error",
        "no-extra-bind": "error",
        "no-extra-label": "error",
        "no-extra-parens": "off",
        "no-floating-decimal": "error",
        "no-implicit-coercion": "error",
        "no-implicit-globals": "off",
        "no-implied-eval": "error",
        "no-inline-comments": "off",
        "no-inner-declarations": [
            "error",
            "functions"
        ],
        "no-invalid-this": "error",
        "no-iterator": "error",
        "no-label-var": "error",
        "no-labels": "error",
        "no-lone-blocks": "error",
        "no-lonely-if": "off",
        "no-loop-func": "error",
        "no-magic-numbers": "off",
        "no-mixed-operators": "error",
        "no-mixed-requires": "error",
        "no-multi-assign": "off",
        "no-multi-spaces": "off",
        "no-multi-str": "error",
        "no-multiple-empty-lines": "error",
        "no-native-reassign": "error",
        "no-negated-condition": "off",
        "no-negated-in-lhs": "error",
        "no-nested-ternary": "error",
        "no-new": "error",
        "no-new-func": "error",
        "no-new-object": "error",
        "no-new-require": "error",
        "no-new-wrappers": "error",
        "no-octal-escape": "error",
        "no-param-reassign": "off",
        "no-path-concat": "error",
        "no-plusplus": "off",
        "no-process-env": "off",
        "no-process-exit": "off",
        "no-proto": "error",
        "no-prototype-builtins": "off",
        "no-restricted-globals": "error",
        "no-restricted-imports": "error",
        "no-restricted-modules": "error",
        "no-restricted-properties": "error",
        "no-restricted-syntax": "error",
        "no-return-assign": "error",
        "no-return-await": "error",
        "no-script-url": "error",
        "no-self-compare": "error",
        "no-sequences": "error",
        "no-shadow": "off",
        "no-shadow-restricted-names": "error",
        "no-spaced-func": "off",
        "no-sync": "error",
        "no-tabs": "error",
        "no-template-curly-in-string": "error",
        "no-ternary": "off",
        "no-throw-literal": "error",
        "no-trailing-spaces": "off",
        "no-undef-init": "off",
        "no-undefined": "off",
        "no-underscore-dangle": "off",
        "no-unmodified-loop-condition": "error",
        "no-unneeded-ternary": "error",
        "no-unused-expressions": "off",
        "no-use-before-define": "off",
        "no-useless-call": "error",
        "no-useless-computed-key": "error",
        "no-useless-concat": "error",
        "no-useless-constructor": "error",
        "no-useless-rename": "error",
        "no-useless-return": "error",
        "no-var": "off",
        "no-void": "error",
        "no-warning-comments": "off",
        "no-whitespace-before-property": "error",
        "no-with": "error",
        "nonblock-statement-body-position": [
            "error",
            "any"
        ],
        "object-curly-newline": "off",
        "object-curly-spacing": "off",
        "object-property-newline": "off",
        "object-shorthand": "off",
        "one-var": "off",
        "one-var-declaration-per-line": "error",
        "operator-assignment": "error",
        "operator-linebreak": "off",
        "padded-blocks": "off",
        "padding-line-between-statements": "error",
        "prefer-arrow-callback": "off",
        "prefer-const": "error",
        "prefer-numeric-literals": "error",
        "prefer-promise-reject-errors": "off",
        "prefer-reflect": "off",
        "prefer-rest-params": "off",
        "prefer-spread": "error",
        "prefer-template": "off",
        "quote-props": "off",
        "quotes": "off",
        "radix": "error",
        "require-await": "error",
        "require-jsdoc": "off",
        "rest-spread-spacing": "error",
        "semi": "off",
        "semi-spacing": "off",
        "semi-style": [
            "error",
            "last"
        ],
        "sort-imports": "error",
        "sort-keys": "off",
        "sort-vars": "error",
        "space-before-blocks": "off",
        "space-before-function-paren": "off",
        "space-in-parens": "off",
        "space-infix-ops": "off",
        "space-unary-ops": "off",
        "spaced-comment": "off",
        "strict": "off",
        "switch-colon-spacing": "error",
        "symbol-description": "error",
        "template-curly-spacing": "error",
        "template-tag-spacing": "error",
        "unicode-bom": [
            "error",
            "never"
        ],
        "valid-jsdoc": "off",
        "vars-on-top": "off",
        "wrap-iife": "error",
        "wrap-regex": "error",
        "yield-star-spacing": "error",
        "yoda": [
            "error",
            "never"
        ]
    }
};<commit_msg>disable linebreak-style in eslint<commit_after>/*
 * Copyright IBM Corp. 2015-2017
 *
 * 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.
 */

// Configuration for eslint.
// See: https://eslint.org/docs/rules/

module.exports = {
    "env": {
        "es6": true,
        "node": true,
        "mocha": true
    },
    "plugins": [
        "chai-friendly"
    ],
    "extends": "eslint:recommended",
    "rules": {
        "accessor-pairs": "error",
        "array-bracket-newline": "error",
        "array-bracket-spacing": "off",
        "array-callback-return": "error",
        "array-element-newline": "off",
        "arrow-body-style": "error",
        "arrow-parens": "off",
        "arrow-spacing": [
            "error",
            {
                "after": true,
                "before": true
            }
        ],
        "block-scoped-var": "error",
        "block-spacing": "off",
        "brace-style": [
            "error",
            "1tbs",
            {
                "allowSingleLine": true
            }
        ],
        "callback-return": "error",
        "camelcase": "off",
        "capitalized-comments": "off",
        "class-methods-use-this": "off",
        "comma-dangle": "error",
        "comma-spacing": "off",
        "comma-style": [
            "error",
            "last"
        ],
        "complexity": "error",
        "computed-property-spacing": [
            "error",
            "never"
        ],
        "consistent-return": "off",
        "consistent-this": "error",
        "curly": "off",
        "default-case": "error",
        "dot-location": [
            "error",
            "property"
        ],
        "dot-notation": [
            "error",
            {
                "allowKeywords": true
            }
        ],
        "eol-last": "off",
        "eqeqeq": "off",
        "for-direction": "error",
        "func-call-spacing": "off",
        "func-name-matching": "off",
        "func-names": "off",
        "func-style": "off",
        "generator-star-spacing": "error",
        "global-require": "off",
        "guard-for-in": "error",
        "handle-callback-err": "off",
        "id-blacklist": "error",
        "id-length": "off",
        "id-match": "error",
        "indent": ["error", 2],
        "indent-legacy": "off",
        "init-declarations": "off",
        "jsx-quotes": "error",
        "key-spacing": "off",
        "keyword-spacing": "off",
        "line-comment-position": "off",
        "linebreak-style": "off",
        "lines-around-comment": "off",
        "lines-around-directive": "off",
        "max-depth": "error",
        "max-len": "off",
        "max-lines": "off",
        "max-nested-callbacks": "error",
        "max-params": "error",
        "max-statements": "off",
        "max-statements-per-line": "off",
        "multiline-ternary": [
            "error",
            "never"
        ],
        "new-parens": "error",
        "newline-after-var": "off",
        "newline-before-return": "off",
        "newline-per-chained-call": "error",
        "no-alert": "error",
        "no-array-constructor": "error",
        "no-await-in-loop": "error",
        "no-bitwise": "error",
        "no-buffer-constructor": "off",
        "no-caller": "error",
        "no-catch-shadow": "error",
        "no-confusing-arrow": "error",
        "no-continue": "off",
        "no-div-regex": "error",
        "no-duplicate-imports": "error",
        "no-else-return": "off",
        "no-empty-function": "error",
        "no-eq-null": "error",
        "no-eval": "error",
        "no-extend-native": "error",
        "no-extra-bind": "error",
        "no-extra-label": "error",
        "no-extra-parens": "off",
        "no-floating-decimal": "error",
        "no-implicit-coercion": "error",
        "no-implicit-globals": "off",
        "no-implied-eval": "error",
        "no-inline-comments": "off",
        "no-inner-declarations": [
            "error",
            "functions"
        ],
        "no-invalid-this": "error",
        "no-iterator": "error",
        "no-label-var": "error",
        "no-labels": "error",
        "no-lone-blocks": "error",
        "no-lonely-if": "off",
        "no-loop-func": "error",
        "no-magic-numbers": "off",
        "no-mixed-operators": "error",
        "no-mixed-requires": "error",
        "no-multi-assign": "off",
        "no-multi-spaces": "off",
        "no-multi-str": "error",
        "no-multiple-empty-lines": "error",
        "no-native-reassign": "error",
        "no-negated-condition": "off",
        "no-negated-in-lhs": "error",
        "no-nested-ternary": "error",
        "no-new": "error",
        "no-new-func": "error",
        "no-new-object": "error",
        "no-new-require": "error",
        "no-new-wrappers": "error",
        "no-octal-escape": "error",
        "no-param-reassign": "off",
        "no-path-concat": "error",
        "no-plusplus": "off",
        "no-process-env": "off",
        "no-process-exit": "off",
        "no-proto": "error",
        "no-prototype-builtins": "off",
        "no-restricted-globals": "error",
        "no-restricted-imports": "error",
        "no-restricted-modules": "error",
        "no-restricted-properties": "error",
        "no-restricted-syntax": "error",
        "no-return-assign": "error",
        "no-return-await": "error",
        "no-script-url": "error",
        "no-self-compare": "error",
        "no-sequences": "error",
        "no-shadow": "off",
        "no-shadow-restricted-names": "error",
        "no-spaced-func": "off",
        "no-sync": "error",
        "no-tabs": "error",
        "no-template-curly-in-string": "error",
        "no-ternary": "off",
        "no-throw-literal": "error",
        "no-trailing-spaces": "off",
        "no-undef-init": "off",
        "no-undefined": "off",
        "no-underscore-dangle": "off",
        "no-unmodified-loop-condition": "error",
        "no-unneeded-ternary": "error",
        "no-unused-expressions": "off",
        "no-use-before-define": "off",
        "no-useless-call": "error",
        "no-useless-computed-key": "error",
        "no-useless-concat": "error",
        "no-useless-constructor": "error",
        "no-useless-rename": "error",
        "no-useless-return": "error",
        "no-var": "off",
        "no-void": "error",
        "no-warning-comments": "off",
        "no-whitespace-before-property": "error",
        "no-with": "error",
        "nonblock-statement-body-position": [
            "error",
            "any"
        ],
        "object-curly-newline": "off",
        "object-curly-spacing": "off",
        "object-property-newline": "off",
        "object-shorthand": "off",
        "one-var": "off",
        "one-var-declaration-per-line": "error",
        "operator-assignment": "error",
        "operator-linebreak": "off",
        "padded-blocks": "off",
        "padding-line-between-statements": "error",
        "prefer-arrow-callback": "off",
        "prefer-const": "error",
        "prefer-numeric-literals": "error",
        "prefer-promise-reject-errors": "off",
        "prefer-reflect": "off",
        "prefer-rest-params": "off",
        "prefer-spread": "error",
        "prefer-template": "off",
        "quote-props": "off",
        "quotes": "off",
        "radix": "error",
        "require-await": "error",
        "require-jsdoc": "off",
        "rest-spread-spacing": "error",
        "semi": "off",
        "semi-spacing": "off",
        "semi-style": [
            "error",
            "last"
        ],
        "sort-imports": "error",
        "sort-keys": "off",
        "sort-vars": "error",
        "space-before-blocks": "off",
        "space-before-function-paren": "off",
        "space-in-parens": "off",
        "space-infix-ops": "off",
        "space-unary-ops": "off",
        "spaced-comment": "off",
        "strict": "off",
        "switch-colon-spacing": "error",
        "symbol-description": "error",
        "template-curly-spacing": "error",
        "template-tag-spacing": "error",
        "unicode-bom": [
            "error",
            "never"
        ],
        "valid-jsdoc": "off",
        "vars-on-top": "off",
        "wrap-iife": "error",
        "wrap-regex": "error",
        "yield-star-spacing": "error",
        "yoda": [
            "error",
            "never"
        ]
    }
};
<|endoftext|>


<commit_before>import React from 'react';
import * as utils from '../../lib/utils';
import PostItem from '../post-item';
import {postFetchAllRequest} from '../../action/post-actions.js';
import {connect} from 'react-redux';

class PostList extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      sortedArray: this.props.post,

    };
  }

  render () {
    let sorted =  this.props.post.sort(function(a,b) {
      return b.exactTime - a.exactTime;
    });
    console.log('====>THIS IS SORTED', sorted);
    return (

        {utils.renderIf(this.props.post,
          sorted.map(post =>

{
              <PostItem key={post._id} post={post}
              />
            }

          ))}

    );
  }
}

let mapStateToProps = state => ({
  auth: state.auth,
  user: state.user,
  post: state.post,
});

let mapDispatchToProps = dispatch => ({
  postFetch: () => dispatch(postFetchAllRequest()),

});

export default connect(mapStateToProps, mapDispatchToProps)(PostList);
<commit_msg>pushing<commit_after>import React from 'react';
import * as utils from '../../lib/utils';
import PostItem from '../post-item';
import {postFetchAllRequest} from '../../action/post-actions.js';
import {connect} from 'react-redux';

class PostList extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      sortedArray: this.props.post,

    };
  }

  render () {
    let sorted =  this.props.post.sort(function(a,b) {
      return b.exactTime - a.exactTime;
    });
    console.log('====>THIS IS SORTED', sorted);
    return (

        {utils.renderIf(this.props.post,
          sorted.map(post =>

{
              <PostItem key={post._id} post={post}
              />
            }

          ))}

    );
  }
}
//testing

let mapStateToProps = state => ({
  auth: state.auth,
  user: state.user,
  post: state.post,
});

let mapDispatchToProps = dispatch => ({
  postFetch: () => dispatch(postFetchAllRequest()),

});

export default connect(mapStateToProps, mapDispatchToProps)(PostList);
<|endoftext|>


<commit_before>import EmberObject from '@ember/object';
import { bool, mapBy, min, max, map } from '@ember/object/computed';
import { later, cancel } from '@ember/runloop';

import Fix from '../utils/fix';
import slFlightCollection from '../utils/flight-collection';
import flightFromData from '../utils/flight-from-data';

/**
 * List of colors for flight path display
 * @type {Array<String>}
 */
const COLORS = ['#004bbd', '#bf0099', '#cf7c00', '#ff0000', '#00c994', '#ffff00'];

export default EmberObject.extend({
  ajax: null,
  units: null,

  // flights: [],

  /*
   * Global time, can be:
   * null -> no time is set, don't show barogram crosshair/plane position
   * -1 -> always show the latest time/fix for each flight
   * >= 0 -> show the associated time in the barogram and on the map
   * @type {!Number}
   */
  time: null,

  /**
   * Default time - the time to set when no time is set
   * @type {!Number}
   */
  defaultTime: null,

  timer: null,

  isRunning: bool('timer'),

  startTimes: mapBy('flights', 'startTime'),
  minStartTime: min('startTimes'),

  endTimes: mapBy('flights', 'endTime'),
  maxEndTime: max('endTimes'),

  fixes: map('flights', function (flight) {
    return Fix.create({ flight, fixCalc: this });
  }),

  init() {
    this._super(...arguments);
    this.set('flights', slFlightCollection.create());
  },

  startPlayback() {
    let time = this.time;

    if (time === null || time === -1) {
      this.set('time', this.minStartTime);
    }

    this.set('timer', later(this, 'onTick', 50));
  },

  stopPlayback() {
    let timer = this.timer;
    if (timer) {
      cancel(timer);
      this.set('timer', null);
    }
  },

  togglePlayback() {
    if (this.isRunning) {
      this.stopPlayback();
    } else {
      this.startPlayback();
    }
  },

  onTick() {
    let time = this.time + 1;

    if (time > this.maxEndTime) {
      this.stopPlayback();
    }

    this.set('time', time);
    this.set('timer', later(this, 'onTick', 50));
  },

  resetTime() {
    this.set('time', this.defaultTime);
  },

  /**
   * Add a flight to the map and barogram.
   *
   * @param {Object} data The data received from the JSON request.
   */
  addFlight(data) {
    let flights = this.flights;

    let flight = flightFromData(data, this.units);

    if (data.additional && data.additional.color) {
      flight.set('color', data.additional.color);
    } else {
      flight.set('color', COLORS[flights.get('length') % COLORS.length]);
    }

    flights.pushObject(flight);
  },

  /**
   * Perform a JSON request to get a flight.
   *
   * @param {String} url URL to fetch.
   */
  async addFlightFromJSON(url) {
    let flights = this.flights;

    let data = await this.ajax.request(url);
    if (!flights.findBy('id', data.sfid)) {
      this.addFlight(data);
    }
  },
});
<commit_msg>utils/fix-calc: Convert to ES6 class<commit_after>import EmberObject from '@ember/object';
import { bool, mapBy, min, max, map } from '@ember/object/computed';
import { later, cancel } from '@ember/runloop';

import Fix from '../utils/fix';
import slFlightCollection from '../utils/flight-collection';
import flightFromData from '../utils/flight-from-data';

/**
 * List of colors for flight path display
 * @type {Array<String>}
 */
const COLORS = ['#004bbd', '#bf0099', '#cf7c00', '#ff0000', '#00c994', '#ffff00'];

export default class FixCalc extends EmberObject {
  flights = slFlightCollection.create();

  /*
   * Global time, can be:
   * null -> no time is set, don't show barogram crosshair/plane position
   * -1 -> always show the latest time/fix for each flight
   * >= 0 -> show the associated time in the barogram and on the map
   * @type {!Number}
   */
  time = null;

  /**
   * Default time - the time to set when no time is set
   * @type {!Number}
   */
  defaultTime = null;

  timer = null;

  @bool('timer') isRunning;

  @mapBy('flights', 'startTime') startTimes;
  @min('startTimes') minStartTime;

  @mapBy('flights', 'endTime') endTimes;
  @max('endTimes') maxEndTime;

  @map('flights', function (flight) {
    return Fix.create({ flight, fixCalc: this });
  })
  fixes;

  startPlayback() {
    let time = this.time;

    if (time === null || time === -1) {
      this.set('time', this.minStartTime);
    }

    this.set('timer', later(this, 'onTick', 50));
  }

  stopPlayback() {
    let timer = this.timer;
    if (timer) {
      cancel(timer);
      this.set('timer', null);
    }
  }

  togglePlayback() {
    if (this.isRunning) {
      this.stopPlayback();
    } else {
      this.startPlayback();
    }
  }

  onTick() {
    let time = this.time + 1;

    if (time > this.maxEndTime) {
      this.stopPlayback();
    }

    this.set('time', time);
    this.set('timer', later(this, 'onTick', 50));
  }

  resetTime() {
    this.set('time', this.defaultTime);
  }

  /**
   * Add a flight to the map and barogram.
   *
   * @param {Object} data The data received from the JSON request.
   */
  addFlight(data) {
    let flights = this.flights;

    let flight = flightFromData(data, this.units);

    if (data.additional && data.additional.color) {
      flight.set('color', data.additional.color);
    } else {
      flight.set('color', COLORS[flights.get('length') % COLORS.length]);
    }

    flights.pushObject(flight);
  }

  /**
   * Perform a JSON request to get a flight.
   *
   * @param {String} url URL to fetch.
   */
  async addFlightFromJSON(url) {
    let flights = this.flights;

    let data = await this.ajax.request(url);
    if (!flights.findBy('id', data.sfid)) {
      this.addFlight(data);
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.provide('frappe.dashboards.chart_sources');

frappe.ui.form.on('Dashboard Chart', {
	setup: function(frm) {
		// fetch timeseries from source
		frm.add_fetch('source', 'timeseries', 'timeseries');
	},

	refresh: function(frm) {
		frm.chart_filters = null;
		frm.set_df_property("filters_section", "hidden", 1);
		frm.trigger('update_options');
	},

	source: function(frm) {
		frm.trigger("show_filters");
	},

	chart_type: function(frm) {
		// set timeseries based on chart type
		if (['Count', 'Average', 'Sum'].includes(frm.doc.chart_type)) {
			frm.set_value('timeseries', 1);
		}
		frm.set_value('document_type', '');
	},

	document_type: function(frm) {
		// update `based_on` options based on date / datetime fields
		frm.set_value('source', '');
		frm.set_value('based_on', '');
		frm.set_value('value_based_on', '');
		frm.set_value('filters_json', '{}');
		frm.trigger('update_options');
	},

	update_options: function(frm) {
		let doctype = frm.doc.document_type;
		let date_fields = [
			{label: __('Created On'), value: 'creation'},
			{label: __('Last Modified On'), value: 'modified'}
		];
		let value_fields = [];
		let update_form = function() {
			// update select options
			frm.set_df_property('based_on', 'options', date_fields);
			frm.set_df_property('value_based_on', 'options', value_fields);
			frm.trigger("show_filters");
		}

		if (doctype) {
			frappe.model.with_doctype(doctype, () => {
				// get all date and datetime fields
				frappe.get_meta(doctype).fields.map(df => {
					if (['Date', 'Datetime'].includes(df.fieldtype)) {
						date_fields.push({label: df.label, value: df.fieldname});
					}
					if (['Int', 'Float', 'Currency', 'Percent'].includes(df.fieldtype)) {
						value_fields.push({label: df.label, value: df.fieldname});
					}
				});
				update_form();
			});
		} else {
			// update select options
			update_form();
		}

	},

	show_filters: function(frm) {
		if (frm.chart_filters && frm.chart_filters.length) {
			frm.trigger('render_filters_table');
		} else {
			if (frm.doc.chart_type==='Custom') {
				if (frm.doc.source) {
					frappe.xcall('frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config', {name: frm.doc.source})
						.then(config => {
							frappe.dom.eval(config);
							frm.chart_filters = frappe.dashboards.chart_sources[frm.doc.source].filters;
							frm.trigger('render_filters_table');
						});
				} else {
					frm.chart_filters = [];
					frm.trigger('render_filters_table');
				}
			} else {
				// standard filters
				if (frm.doc.document_type) {
					// allow all link and select fields as filters
					frm.chart_filters = [];
					frappe.model.with_doctype(frm.doc.document_type, () => {
						frappe.get_meta(frm.doc.document_type).fields.map(df => {
							if (['Link', 'Select'].includes(df.fieldtype)) {
								let _df = copy_dict(df);

								// nothing is mandatory
								_df.reqd = 0;
								_df.default = null;
								_df.read_only = 0;
								_df.permlevel = 1;
								_df.hidden = 0;

								frm.chart_filters.push(_df);
							}
							frm.trigger('render_filters_table');
						});
					});
				}
			}

		}
	},

	render_filters_table: function(frm) {
		frm.set_df_property("filters_section", "hidden", 0);
		let fields = frm.chart_filters;

		let wrapper = $(frm.get_field('filters_json').wrapper).empty();
		let table = $(`

					${__('Filter')}
					${__('Value')}

`).appendTo(wrapper);
		$(`<p class="text-muted small">${__("Click table to edit")}</p>`).appendTo(wrapper);

		let filters = JSON.parse(frm.doc.filters_json || '{}');
		var filters_set = false;
		fields.map( f => {
			if (filters[f.fieldname]) {
				const filter_row = $(`<tr><td>${f.label}</td><td>${filters[f.fieldname] || ""}</td></tr>`);
				table.find('tbody').append(filter_row);
				filters_set = true;
			}
		});

		if (!filters_set) {
			const filter_row = $(`

				${__("Click to Set Filters")}
`);
			table.find('tbody').append(filter_row);
		}

		table.on('click', () => {
			let dialog = new frappe.ui.Dialog({
				title: __('Set Filters'),
				fields: fields,
				primary_action: function() {
					let values = this.get_values();
					if(values) {
						this.hide();
						frm.set_value('filters_json', JSON.stringify(values));
						frm.trigger('show_filters');
					}
				},
				primary_action_label: "Set"
			});
			dialog.show();
			dialog.set_values(filters);
			frappe.dashboards.filters_dialog = dialog;
		});
	}
});

<commit_msg>fix(minor): dont apply depends_on while selecting chart filters<commit_after>// Copyright (c) 2019, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.provide('frappe.dashboards.chart_sources');

frappe.ui.form.on('Dashboard Chart', {
	setup: function(frm) {
		// fetch timeseries from source
		frm.add_fetch('source', 'timeseries', 'timeseries');
	},

	refresh: function(frm) {
		frm.chart_filters = null;
		frm.set_df_property("filters_section", "hidden", 1);
		frm.trigger('update_options');
	},

	source: function(frm) {
		frm.trigger("show_filters");
	},

	chart_type: function(frm) {
		// set timeseries based on chart type
		if (['Count', 'Average', 'Sum'].includes(frm.doc.chart_type)) {
			frm.set_value('timeseries', 1);
		}
		frm.set_value('document_type', '');
	},

	document_type: function(frm) {
		// update `based_on` options based on date / datetime fields
		frm.set_value('source', '');
		frm.set_value('based_on', '');
		frm.set_value('value_based_on', '');
		frm.set_value('filters_json', '{}');
		frm.trigger('update_options');
	},

	update_options: function(frm) {
		let doctype = frm.doc.document_type;
		let date_fields = [
			{label: __('Created On'), value: 'creation'},
			{label: __('Last Modified On'), value: 'modified'}
		];
		let value_fields = [];
		let update_form = function() {
			// update select options
			frm.set_df_property('based_on', 'options', date_fields);
			frm.set_df_property('value_based_on', 'options', value_fields);
			frm.trigger("show_filters");
		}

		if (doctype) {
			frappe.model.with_doctype(doctype, () => {
				// get all date and datetime fields
				frappe.get_meta(doctype).fields.map(df => {
					if (['Date', 'Datetime'].includes(df.fieldtype)) {
						date_fields.push({label: df.label, value: df.fieldname});
					}
					if (['Int', 'Float', 'Currency', 'Percent'].includes(df.fieldtype)) {
						value_fields.push({label: df.label, value: df.fieldname});
					}
				});
				update_form();
			});
		} else {
			// update select options
			update_form();
		}

	},

	show_filters: function(frm) {
		if (frm.chart_filters && frm.chart_filters.length) {
			frm.trigger('render_filters_table');
		} else {
			if (frm.doc.chart_type==='Custom') {
				if (frm.doc.source) {
					frappe.xcall('frappe.desk.doctype.dashboard_chart_source.dashboard_chart_source.get_config', {name: frm.doc.source})
						.then(config => {
							frappe.dom.eval(config);
							frm.chart_filters = frappe.dashboards.chart_sources[frm.doc.source].filters;
							frm.trigger('render_filters_table');
						});
				} else {
					frm.chart_filters = [];
					frm.trigger('render_filters_table');
				}
			} else {
				// standard filters
				if (frm.doc.document_type) {
					// allow all link and select fields as filters
					frm.chart_filters = [];
					frappe.model.with_doctype(frm.doc.document_type, () => {
						frappe.get_meta(frm.doc.document_type).fields.map(df => {
							if (['Link', 'Select'].includes(df.fieldtype)) {
								let _df = copy_dict(df);

								// nothing is mandatory
								_df.reqd = 0;
								_df.default = null;
								_df.depends_on = null;
								_df.read_only = 0;
								_df.permlevel = 1;
								_df.hidden = 0;

								frm.chart_filters.push(_df);
							}
							frm.trigger('render_filters_table');
						});
					});
				}
			}

		}
	},

	render_filters_table: function(frm) {
		frm.set_df_property("filters_section", "hidden", 0);
		let fields = frm.chart_filters;

		let wrapper = $(frm.get_field('filters_json').wrapper).empty();
		let table = $(`

					${__('Filter')}
					${__('Value')}

`).appendTo(wrapper);
		$(`<p class="text-muted small">${__("Click table to edit")}</p>`).appendTo(wrapper);

		let filters = JSON.parse(frm.doc.filters_json || '{}');
		var filters_set = false;
		fields.map( f => {
			if (filters[f.fieldname]) {
				const filter_row = $(`<tr><td>${f.label}</td><td>${filters[f.fieldname] || ""}</td></tr>`);
				table.find('tbody').append(filter_row);
				filters_set = true;
			}
		});

		if (!filters_set) {
			const filter_row = $(`

				${__("Click to Set Filters")}
`);
			table.find('tbody').append(filter_row);
		}

		table.on('click', () => {
			let dialog = new frappe.ui.Dialog({
				title: __('Set Filters'),
				fields: fields,
				primary_action: function() {
					let values = this.get_values();
					if(values) {
						this.hide();
						frm.set_value('filters_json', JSON.stringify(values));
						frm.trigger('show_filters');
					}
				},
				primary_action_label: "Set"
			});
			dialog.show();
			dialog.set_values(filters);
			frappe.dashboards.filters_dialog = dialog;
		});
	}
});

<|endoftext|>


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

var cp = require('child_process')

var BIN = '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary'
var ARGS = ['--load-and-launch-app=chrome']

var child = cp.spawn(BIN, ARGS)

// Nodemon is trying to kill us, so kill Chrome
process.once('SIGUSR2', function () {
  child.kill()
  process.kill(process.pid, 'SIGUSR2')
})<commit_msg>Improve the accessibility of the project for linux users.<commit_after>#!/usr/bin/env node

var cp = require('child_process')

var BIN = process.platform=='linux' ? '/bin/google-chrome' : '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary';
var ARGS = ['--load-and-launch-app=chrome']

var child = cp.spawn(BIN, ARGS)

// Nodemon is trying to kill us, so kill Chrome
process.once('SIGUSR2', function () {
  child.kill()
  process.kill(process.pid, 'SIGUSR2')
})
<|endoftext|>