<commit_before>var _ = require('underscore');
var bcrypt = require('bcrypt-nodejs');
var FieldType = require('../Type');
var util = require('util');

/**
 * password FieldType Constructor
 * @extends Field
 * @api public
 */
function password (list, path, options) {
	this._nativeType = String;
	this._underscoreMethods = ['format', 'compare'];
	this._fixedSize = 'full';
	// You can't sort on password fields
	options.nosort = true;
	options.nofilter = true; // TODO: remove this when 0.4 is merged
	this.workFactor = options.workFactor || 10;
	password.super_.call(this, list, path, options);
}
util.inherits(password, FieldType);

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * Adds ...
 *
 * @api public
 */
password.prototype.addToSchema = function () {
	var field = this;
	var schema = this.list.schema;
	var needs_hashing = '__' + field.path + '_needs_hashing';

	this.paths = {
		confirm: this.options.confirmPath || this._path.append('_confirm'),
		hash: this.options.hashPath || this._path.append('_hash'),
	};

	schema.path(this.path, _.defaults({
		type: String,
		set: function (newValue) {
			this[needs_hashing] = true;
			return newValue;
		},
	}, this.options));

	schema.virtual(this.paths.hash).set(function (newValue) {
		this.set(field.path, newValue);
		this[needs_hashing] = false;
	});

	schema.pre('save', function (next) {
		if (!this.isModified(field.path) || !this[needs_hashing]) {
			return next();
		}
		if (!this.get(field.path)) {
			this.set(field.path, undefined);
			return next();
		}
		var item = this;
		bcrypt.genSalt(field.workFactor, function (err, salt) {
			if (err) {
				return next(err);
			}
			bcrypt.hash(item.get(field.path), salt, function () {}, function (err, hash) {
				if (err) {
					return next(err);
				}
				// override the cleartext password with the hashed one
				item.set(field.path, hash);
				next();
			});
		});
	});
	this.bindUnderscoreMethods();
};

/**
 * Add filters to a query
 */
password.prototype.addFilterToQuery = function (filter, query) {
	query = query || {};
	query[this.path] = (filter.exists) ? { $ne: null } : null;
	return query;
};

/**
 * Formats the field value
 *
 * Password fields are always formatted as a random no. of asterisks,
 * because the saved hash should never be displayed nor the length
 * of the actual password hinted at.
 *
 * @api public
 */
password.prototype.format = function (item) {
	if (!item.get(this.path)) return '';
	var len = Math.round(Math.random() * 4) + 6;
	var stars = '';
	for (var i = 0; i < len; i++) stars += '*';
	return stars;
};

/**
 * Compares
 *
 * @api public
 */
password.prototype.compare = function (item, candidate, callback) {
	if (typeof callback !== 'function') throw new Error('Password.compare() requires a callback function.');
	var value = item.get(this.path);
	if (!value) return callback(null, false);
	bcrypt.compare(candidate, item.get(this.path), callback);
};

/**
 * Asynchronously confirms that the provided password is valid
 */
password.prototype.validateInput = function (data, callback) {
	var detail;
	var result = true;
	var confirmValue = this.getValueFromData(data, '_confirm');
	var passwordValue = this.getValueFromData(data);
	if (passwordValue !== undefined && confirmValue !== undefined && passwordValue !== confirmValue) {
		result = false;
		detail = 'passwords must match';
	}
	// TODO: we could support a password complexity option (or regexp) here
	process.nextTick(function () { callback(result, detail); });
};

/**
 * Asynchronously confirms that the provided password is valid
 */
password.prototype.validateRequiredInput = function (item, data, callback) {
	var hashValue = this.getValueFromData(data, '_hash');
	var passwordValue = this.getValueFromData(data);
	var result = hashValue || passwordValue ? true : false;
	if (!result && passwordValue === undefined && hashValue === undefined && item.get(this.path)) result = true;
	process.nextTick(function () { callback(result); });
};

/**
 * If password fields are required, check that either a value has been
 * provided or already exists in the field.
 *
 * Otherwise, input is always considered valid, as providing an empty
 * value will not change the password.
 *
 * Deprecated
 */
password.prototype.inputIsValid = function (data, required, item) {
	if (data[this.path] && this.paths.confirm in data) {
		return data[this.path] === data[this.paths.confirm] ? true : false;
	}
	if (data[this.path] || data[this.paths.hash] || (item && item.get(this.path))) return true;
	return required ? false : true;
};

/**
 * Updates the value for this field in the item from a data object
 *
 * Will accept either the field path, or paths.hash to bypass bcrypt
 *
 * @api public
 */
password.prototype.updateItem = function (item, data, callback) {
	// TODO: this is brittle and won't work with nested fields. needs better
	// support of pulling nested paths out of objects before we can fix it.
	if (this.path in data) {
		item.set(this.path, data[this.path]);
	} else if (this.paths.hash in data) {
		item.set(this.paths.hash, data[this.paths.hash]);
	}
	process.nextTick(callback);
};

/* Export Field Type */
module.exports = password;
<commit_msg>Fixes updating nested Password fields<commit_after>var _ = require('underscore');
var bcrypt = require('bcrypt-nodejs');
var FieldType = require('../Type');
var util = require('util');

/**
 * password FieldType Constructor
 * @extends Field
 * @api public
 */
function password (list, path, options) {
	this._nativeType = String;
	this._underscoreMethods = ['format', 'compare'];
	this._fixedSize = 'full';
	// You can't sort on password fields
	options.nosort = true;
	options.nofilter = true; // TODO: remove this when 0.4 is merged
	this.workFactor = options.workFactor || 10;
	password.super_.call(this, list, path, options);
}
util.inherits(password, FieldType);

/**
 * Registers the field on the List's Mongoose Schema.
 *
 * Adds ...
 *
 * @api public
 */
password.prototype.addToSchema = function () {
	var field = this;
	var schema = this.list.schema;
	var needs_hashing = '__' + field.path + '_needs_hashing';

	this.paths = {
		confirm: this.options.confirmPath || this._path.append('_confirm'),
		hash: this.options.hashPath || this._path.append('_hash'),
	};

	schema.path(this.path, _.defaults({
		type: String,
		set: function (newValue) {
			this[needs_hashing] = true;
			return newValue;
		},
	}, this.options));

	schema.virtual(this.paths.hash).set(function (newValue) {
		this.set(field.path, newValue);
		this[needs_hashing] = false;
	});

	schema.pre('save', function (next) {
		if (!this.isModified(field.path) || !this[needs_hashing]) {
			return next();
		}
		if (!this.get(field.path)) {
			this.set(field.path, undefined);
			return next();
		}
		var item = this;
		bcrypt.genSalt(field.workFactor, function (err, salt) {
			if (err) {
				return next(err);
			}
			bcrypt.hash(item.get(field.path), salt, function () {}, function (err, hash) {
				if (err) {
					return next(err);
				}
				// override the cleartext password with the hashed one
				item.set(field.path, hash);
				next();
			});
		});
	});
	this.bindUnderscoreMethods();
};

/**
 * Add filters to a query
 */
password.prototype.addFilterToQuery = function (filter, query) {
	query = query || {};
	query[this.path] = (filter.exists) ? { $ne: null } : null;
	return query;
};

/**
 * Formats the field value
 *
 * Password fields are always formatted as a random no. of asterisks,
 * because the saved hash should never be displayed nor the length
 * of the actual password hinted at.
 *
 * @api public
 */
password.prototype.format = function (item) {
	if (!item.get(this.path)) return '';
	var len = Math.round(Math.random() * 4) + 6;
	var stars = '';
	for (var i = 0; i < len; i++) stars += '*';
	return stars;
};

/**
 * Compares
 *
 * @api public
 */
password.prototype.compare = function (item, candidate, callback) {
	if (typeof callback !== 'function') throw new Error('Password.compare() requires a callback function.');
	var value = item.get(this.path);
	if (!value) return callback(null, false);
	bcrypt.compare(candidate, item.get(this.path), callback);
};

/**
 * Asynchronously confirms that the provided password is valid
 */
password.prototype.validateInput = function (data, callback) {
	var detail;
	var result = true;
	var confirmValue = this.getValueFromData(data, '_confirm');
	var passwordValue = this.getValueFromData(data);
	if (passwordValue !== undefined && confirmValue !== undefined && passwordValue !== confirmValue) {
		result = false;
		detail = 'passwords must match';
	}
	// TODO: we could support a password complexity option (or regexp) here
	process.nextTick(function () { callback(result, detail); });
};

/**
 * Asynchronously confirms that the provided password is valid
 */
password.prototype.validateRequiredInput = function (item, data, callback) {
	var hashValue = this.getValueFromData(data, '_hash');
	var passwordValue = this.getValueFromData(data);
	var result = hashValue || passwordValue ? true : false;
	if (!result && passwordValue === undefined && hashValue === undefined && item.get(this.path)) result = true;
	process.nextTick(function () { callback(result); });
};

/**
 * If password fields are required, check that either a value has been
 * provided or already exists in the field.
 *
 * Otherwise, input is always considered valid, as providing an empty
 * value will not change the password.
 *
 * Deprecated
 */
password.prototype.inputIsValid = function (data, required, item) {
	if (data[this.path] && this.paths.confirm in data) {
		return data[this.path] === data[this.paths.confirm] ? true : false;
	}
	if (data[this.path] || data[this.paths.hash] || (item && item.get(this.path))) return true;
	return required ? false : true;
};

/**
 * Updates the value for this field in the item from a data object
 *
 * Will accept either the field path, or paths.hash to bypass bcrypt
 *
 * @api public
 */
password.prototype.updateItem = function (item, data, callback) {
	var hashValue = this.getValueFromData(data, '_hash');
	var passwordValue = this.getValueFromData(data);
	if (passwordValue !== undefined) {
		item.set(this.path, passwordValue);
	} else if (hashValue !== undefined) {
		item.set(this.paths.hash, hashValue);
	}
	process.nextTick(callback);
};

/* Export Field Type */
module.exports = password;
<|endoftext|>


<commit_before>/**
* 1v1 Plugin
* because jd is a shit fucker
* by: panpawn
*/

exports.commands = {
	one: function (target, room, user, connection) {
		if (room.id !== '1v1') return this.sendReply("Hey u bish, get in 1v1 to use this command,,,");
		if (!this.canTalk()) return;
		if (!this.canBroadcast()) return;
		var one = toId(target);
		var reply = "";
		if (!one || one === 'help' || one === 'help' || one === 'git') return this.sendReplyBox("For help, see here.");
		if (one === 'poll') return user.chat('/poll Next 1v1 Tour?, reg, cc1v1, inverse, mono gen, monoletter, monotype, monocolor, cap, eevee only, mega evos, bst based, metronome, lc starters, ubers, lc, 2v2, monopoke, ou choice, almost any ability 1v1, stabmons 1v1, abc cup, averagemons 1v1, balanced hackmons 1v1, tier shift 1v1, mediocremons 1v1, retro1v1',room,connection);

		switch (one) {
			case 'regular':
			case 'reg': reply += 			"Banlist is Sleep Inducing moves excluding rest, Focus Sash, and Ubers excluding Mega Gengar."; break;
			case 'onevone': reply +=		"Banlist includes Imprison/Transform on the same moveset, Sleep Inducing moves excluding rest, Moody, Imposter, Sturdy if it does not naturally obtain it, Parental Bond if it does not naturally obtain it, Focus Sash, and your pokemon must be level 100."; break;
			case 'uu': reply += 			"Anything OU or above."; break;
			case 'ru': reply += 			"Anything UU or above."; break;
			case 'ubers': reply +=			"Bring a team of ONE pokemon, Banlist is Sleep Inducing moves excluding rest, Focus Sash."; break;
			case 'nu': reply += 			"Anything RU or above."; break;
			case 'lc': reply += 			"Bring a team of ONE pokemon. These pokemon should be level 5. Banlist is Sleep Inducing moves excluding rest, Focus Sash."; break;
			case 'ubers': reply += 			"Nothing but Ditto and Smeargle."; break;
			case 'monoletter': reply += 		"A random letter is picked, only Pokemon starting with this letter can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'monotype': reply += 		"A random type is picked, only Pokemon of this type can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'monocolor': reply +=		"A random color is picked, only Pokemon of this color can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash. Helpul Link."; break;
			case 'monopoke': reply +=  		"A random Pokemon is picked, and only that pokemon can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'monogen': reply += 		"A random Pokemon generation is picked, and only Pokemon from that gen can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'cap': reply += 			"Only Pokemon in the Create-a-Pokemon project can be used here. Ask staff for CAP Info. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'eeveelutions': reply += 		"Only Eevee and its many evolutions can be used. Banlist is Sleep Inducing moves excluding rest, Focus sash."; break;
                	case 'lcstarters': reply +=  		"Only the first form of starter pokemon from and generation may be used. These pokemon should be level 5. Banlist is Sleep inducing moves excluding rest, Focus Sash."; break;
			case 'starters': reply +=		"Only Starter Pokemon (from any game) may be used."; break;
			case 'bstbased': reply += 		"Staff does !pickrandom 200-300, 300-400, 400-500, 500-600, 600-700, 700-800 Then, you must ONLY use pokemon within the range of base stat total chosen"; break;
			case 'inverse': reply += 		"1v1 Tour set in the Inverse Gamemode. Not-Very-Effective is not Super Effective and vice-versa. Banlist is Ambipom, Sleep Inducing moves, Focus Sash."; break;
			case 'metronome': reply +=		"Only the move metronome is allowed in this tour, but on any Pokemon with a BST of 600 or less. Here is the banlist."; break;
			case 'megaevos': reply += 		"Custom Game format, this one allowing only Mega Evolutions to be used (with items other than mega stones). Here is its banlist."; break;
			case 'stabmons': reply += 		"Bring a team of ONE pokemon. Pokemon may use any move sharing a type with them in addition to normally learned moves."; break;
			case 'alphabetcup': reply += 		"Bring a team of ONE pokemon. Abbreviated as \"abc cup,\" this is a 1v1 tour set in the alphabet cup tier."; break;
			case 'averagemons': reply += 		"Bring a team of ONE pokemon. All stats of Pokemon are set to 100! See here."; break;
			case 'balancedhackmons':
			case 'bhacks': reply +=			"Straight up balanced hackmons 1v1. Almost anything goes. Reference. Selection: These tours require you to pick one Pokemon from a team of six."; break;
			case 'ou': reply += 			"Bring an OU team and pick one, forfeit/be disqualified if it dies."; break;
			case 'cc1v1': reply += 			"Six completely random (Moves, IVs, Species, Item, etc) pokemon are given to you to choose one. Pick the best one and try to win!"; break;
			case 'twovtwo': reply += 		"
" +
								"These tours are 2v2 but have the flavor of 1v1 as they are set in the Doubles format.
" +
								"- Reg 2v2: Everything banned in Smogon Doubles is banned here. 1 Focus sash maximum per team."; break;
		}
		this.sendReplyBox("" + one + " - " + reply);
	}
};
<commit_msg>Update 1v1.js format, because Sublime Text 2/3 have plugins to auto format Javascript files.<commit_after>/**
 * 1v1 Plugin
 * because jd is a shit fucker
 * by: panpawn
 */

exports.commands = {
	one: function(target, room, user, connection) {
		if (room.id !== '1v1') return this.sendReply("Hey u bish, get in 1v1 to use this command,,,");
		if (!this.canTalk()) return;
		if (!this.canBroadcast()) return;
		var one = toId(target);
		var reply = "";
		if (!one || one === 'help' || one === 'help' || one === 'git') return this.sendReplyBox("For help, see here.");
		if (one === 'poll') return user.chat('/poll Next 1v1 Tour?, reg, cc1v1, inverse, mono gen, monoletter, monotype, monocolor, cap, eevee only, mega evos, bst based, metronome, lc starters, ubers, lc, 2v2, monopoke, ou choice, almost any ability 1v1, stabmons 1v1, abc cup, averagemons 1v1, balanced hackmons 1v1, tier shift 1v1, mediocremons 1v1, retro1v1', room, connection);

		switch (one) {
			case 'regular':
			case 'reg':
				reply += "Banlist is Sleep Inducing moves excluding rest, Focus Sash, and Ubers excluding Mega Gengar.";
				break;
			case 'onevone':
				reply += "Banlist includes Imprison/Transform on the same moveset, Sleep Inducing moves excluding rest, Moody, Imposter, Sturdy if it does not naturally obtain it, Parental Bond if it does not naturally obtain it, Focus Sash, and your pokemon must be level 100.";
				break;
			case 'uu':
				reply += "Anything OU or above.";
				break;
			case 'ru':
				reply += "Anything UU or above.";
				break;
			case 'ubers':
				reply += "Bring a team of ONE pokemon, Banlist is Sleep Inducing moves excluding rest, Focus Sash.";
				break;
			case 'nu':
				reply += "Anything RU or above.";
				break;
			case 'lc':
				reply += "Bring a team of ONE pokemon. These pokemon should be level 5. Banlist is Sleep Inducing moves excluding rest, Focus Sash.";
				break;
			case 'ubers':
				reply += "Nothing but Ditto and Smeargle.";
				break;
			case 'monoletter':
				reply += "A random letter is picked, only Pokemon starting with this letter can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'monotype':
				reply += "A random type is picked, only Pokemon of this type can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'monocolor':
				reply += "A random color is picked, only Pokemon of this color can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash. Helpul Link.";
				break;
			case 'monopoke':
				reply += "A random Pokemon is picked, and only that pokemon can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'monogen':
				reply += "A random Pokemon generation is picked, and only Pokemon from that gen can be used. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'cap':
				reply += "Only Pokemon in the Create-a-Pokemon project can be used here. Ask staff for CAP Info. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'eeveelutions':
				reply += "Only Eevee and its many evolutions can be used. Banlist is Sleep Inducing moves excluding rest, Focus sash.";
				break;
			case 'lcstarters':
				reply += "Only the first form of starter pokemon from and generation may be used. These pokemon should be level 5. Banlist is Sleep inducing moves excluding rest, Focus Sash.";
				break;
			case 'starters':
				reply += "Only Starter Pokemon (from any game) may be used.";
				break;
			case 'bstbased':
				reply += "Staff does !pickrandom 200-300, 300-400, 400-500, 500-600, 600-700, 700-800 Then, you must ONLY use pokemon within the range of base stat total chosen";
				break;
			case 'inverse':
				reply += "1v1 Tour set in the Inverse Gamemode. Not-Very-Effective is not Super Effective and vice-versa. Banlist is Ambipom, Sleep Inducing moves, Focus Sash.";
				break;
			case 'metronome':
				reply += "Only the move metronome is allowed in this tour, but on any Pokemon with a BST of 600 or less. Here is the banlist.";
				break;
			case 'megaevos':
				reply += "Custom Game format, this one allowing only Mega Evolutions to be used (with items other than mega stones). Here is its banlist.";
				break;
			case 'stabmons':
				reply += "Bring a team of ONE pokemon. Pokemon may use any move sharing a type with them in addition to normally learned moves.";
				break;
			case 'alphabetcup':
				reply += "Bring a team of ONE pokemon. Abbreviated as \"abc cup,\" this is a 1v1 tour set in the alphabet cup tier.";
				break;
			case 'averagemons':
				reply += "Bring a team of ONE pokemon. All stats of Pokemon are set to 100! See here.";
				break;
			case 'balancedhackmons':
			case 'bhacks':
				reply += "Straight up balanced hackmons 1v1. Almost anything goes. Reference. Selection: These tours require you to pick one Pokemon from a team of six.";
				break;
			case 'ou':
				reply += "Bring an OU team and pick one, forfeit/be disqualified if it dies.";
				break;
			case 'cc1v1':
				reply += "Six completely random (Moves, IVs, Species, Item, etc) pokemon are given to you to choose one. Pick the best one and try to win!";
				break;
			case 'twovtwo':
				reply += "
" +
					"These tours are 2v2 but have the flavor of 1v1 as they are set in the Doubles format.
" +
					"- Reg 2v2: Everything banned in Smogon Doubles is banned here. 1 Focus sash maximum per team.";
				break;
		}
		this.sendReplyBox("" + one + " - " + reply);
	}
};<|endoftext|>


<commit_before>import React from 'react';

import Link from 'gatsby-link';

import Anchor from '../../ui/Anchor';
import CodeBlock from '../../ui/CodeBlock';
import DocPage from '../../containers/DocPage';
import ApiDocs from '../../containers/ApiDocs';

export default () => (
  <DocPage title="DayPickerInput API">
    <CodeBlock
    >{`import DayPickerInput from 'react-day-picker/DayPickerInput'`}</CodeBlock>

API summary

Component’s Props

      classNames,{' '}
      clickUnselectsDay,{' '}
      component,{' '}
      dayPickerProps, format,{' '}
      formatDate,{' '}
      hideOnDayClick,{' '}
      inputProps,{' '}
      overlayComponent,{' '}
      parseDate, placeholder,{' '}
      showOverlay, value,{' '}
      keepFocus

Event handlers

      onDayChange

Public methods

      getDayPicker, getInput,{' '}
      hideDayPicker,{' '}
      showDayPicker

    <ApiDocs>

DayPickerInput Props

        <Anchor id="classNames" />
        classNames Object

Customize the CSS class names used when rendering the component.

The object expects the following keys:

      <CodeBlock>{`{
  container,            // The container element
  overlayWrapper,       // The overlay's wrapper
  overlay,              // The overlay's container
}`}</CodeBlock>

        <Anchor id="clickUnselectsDay" />
        clickUnselectsDay boolean = false

        Unselect and clear the input when clicking on a previously selected day.

        <Anchor id="component" />
        component string | React.Component = "input"

The component class to render the input field.

        The component must be compatible with the standard HTML{' '}
        input: i.e. it should support the
        onChange, onFocus, onKeyUp,{' '}
        onClick and onBlur and the focus{' '}
        props.

        If your custom component doesn’t support such props, wrap it in a
        component contaning them. For example:

      <CodeBlock>{`import React from 'react';
import { DayPickerInput } from 'react-day-picker';
import MyInputWithoutFocus from './MyInputWithoutFocus';

class MyInputWithFocus extends React.Component {
  focus = () => {
    this.input.focus();
  }
  render() {
    return (
      <MyInputWithoutFocus
        ref={el => (this.input = el)}
        {...this.props}
      />
    );
  }
}

function MyDayPickerInput(props) {
  return <DayPickerInput component={MyInputWithFocus} />
}
`}</CodeBlock>

        <Anchor id="dayPickerProps" />
        dayPickerProps Object

        The <Link to="/api/DayPicker">DayPicker props</Link> to customize the
        calendar rendered in the overlay.

        <Anchor id="format" />
        format string | string[]

        The format string(s) used for formatting and parsing dates. It works
        with{' '}

          parseDate
        {' '}
        and{' '}

          formatDate

        <Anchor id="formatDate" />
        formatDate{' '}

          (date: Date?, format: string? | string[]?, locale: string?) ⇒ string

        Date formatter used for displaying the selected date as value of the
        input field. As default, it returns dates formatted as{' '}
        YYYY-M-D.

        Arguments: format is the value coming from the{' '}

          format
        {' '}
        prop, while locale is from{' '}

          dayPickerProps
        .

        See also{' '}

          parseDate
        .

        If you are using moment.js in your
        app, we already provide this function as addon: see{' '}
        <Link to="/examples/input-moment">this example</Link>.

        <Anchor id="hideOnDayClick" />
        hideOnDayClick boolean = true

Hide the overlay when the user clicks on a day cell.

        <Anchor id="inputProps" />
        inputProps Object

        Additional props to add to the input component. The{' '}
        value key is ignored: use the{' '}

          value
        {' '}
        prop instead.

        <Anchor id="overlayComponent" />
        overlayComponent React.Component

        A React element or constructor to use as overlay. The element will
        receive the following props:

          selectedDay: ?Date The currently selected day

          month: Date The month displayed in the calendar

          input: DOM Element The input field

        See also <Link to="/examples/input-custom-overlay">this example</Link>.

        <Anchor id="parseDate" />
        parseDate{' '}

          (str: string?, format: string? | string[]?, locale: string?) ⇒ Date |
          void

        Date parser used for parsing the string typed in the input field. As
        default, it parses only dates formatted as YYYY-M-D.

        Arguments: format is the value coming from the{' '}

          format
        {' '}
        prop, while locale is from{' '}

          dayPickerProps
        .
See also{' '}

          formatDate
        .

        If you are using moment.js in your
        app, we already provide this function as addon: see{' '}
        <Link to="/examples/input-moment">this example</Link>.

        <Anchor id="placeholder" />
        placeholder string

        The placeholder to use for the input field.

        <Anchor id="showOverlay" />
        showOverlay boolean = false

        Show the overlay during the initial rendering of the component. This is
        useful if you want to keep the overlay visibile while styling it.

        <Anchor id="value" />
        value string | Date

        The value of the input field.

        <Anchor id="keepFocus" />
        keepFocus boolean = true

        Keep focus on the input when switching focus to something inside the
        dayPickerOverlay. You should disable this if you have custom inputs in
        something like an
        overlayComponent.

Event handlers

        <Anchor id="onDayChange" />
        onDayChange (day: Date, modifiers: Object) ⇒ void

        Handler function called when the user types a valid day (according to
        the format prop) or when a day is clicked on the calendar.
        If the day is not valid, day and modifiers arguments will be{' '}
        undefined (useful to display validation warnings).

Public methods

        <Anchor id="getDayPicker" />
        getDayPicker () ⇒ DayPicker

Return the DayPicker instance.

        <Anchor id="getInput" />
        getInput () ⇒ DOMNode | ReactNode

Return the input element instance.

        <Anchor id="showDayPicker" />
        showDayPicker () ⇒ void

Show the Day Picker overlay.

        <Anchor id="hideDayPicker" />
        hideDayPicker () ⇒ void

Hide the Day Picker overlay.

    </ApiDocs>
  </DocPage>
);
<commit_msg>Fix docs for keepFocus<commit_after>import React from 'react';

import Link from 'gatsby-link';

import Anchor from '../../ui/Anchor';
import CodeBlock from '../../ui/CodeBlock';
import DocPage from '../../containers/DocPage';
import ApiDocs from '../../containers/ApiDocs';

export default () => (
  <DocPage title="DayPickerInput API">
    <CodeBlock
    >{`import DayPickerInput from 'react-day-picker/DayPickerInput'`}</CodeBlock>

API summary

Component’s Props

      classNames,{' '}
      clickUnselectsDay,{' '}
      component,{' '}
      dayPickerProps, format,{' '}
      formatDate, keepFocus
      hideOnDayClick,{' '}
      inputProps,{' '}
      overlayComponent,{' '}
      parseDate, placeholder,{' '}
      showOverlay, value,{' '}

Event handlers

      onDayChange

Public methods

      getDayPicker, getInput,{' '}
      hideDayPicker,{' '}
      showDayPicker

    <ApiDocs>

DayPickerInput Props

        <Anchor id="classNames" />
        classNames Object

Customize the CSS class names used when rendering the component.

The object expects the following keys:

      <CodeBlock>{`{
  container,            // The container element
  overlayWrapper,       // The overlay's wrapper
  overlay,              // The overlay's container
}`}</CodeBlock>

        <Anchor id="clickUnselectsDay" />
        clickUnselectsDay boolean = false

        Unselect and clear the input when clicking on a previously selected day.

        <Anchor id="component" />
        component string | React.Component = "input"

The component class to render the input field.

        The component must be compatible with the standard HTML{' '}
        input: i.e. it should support the
        onChange, onFocus, onKeyUp,{' '}
        onClick and onBlur and the focus{' '}
        props.

        If your custom component doesn’t support such props, wrap it in a
        component contaning them. For example:

      <CodeBlock>{`import React from 'react';
import { DayPickerInput } from 'react-day-picker';
import MyInputWithoutFocus from './MyInputWithoutFocus';

class MyInputWithFocus extends React.Component {
  focus = () => {
    this.input.focus();
  }
  render() {
    return (
      <MyInputWithoutFocus
        ref={el => (this.input = el)}
        {...this.props}
      />
    );
  }
}

function MyDayPickerInput(props) {
  return <DayPickerInput component={MyInputWithFocus} />
}
`}</CodeBlock>

        <Anchor id="dayPickerProps" />
        dayPickerProps Object

        The <Link to="/api/DayPicker">DayPicker props</Link> to customize the
        calendar rendered in the overlay.

        <Anchor id="format" />
        format string | string[]

        The format string(s) used for formatting and parsing dates. It works
        with{' '}

          parseDate
        {' '}
        and{' '}

          formatDate

        <Anchor id="formatDate" />
        formatDate{' '}

          (date: Date?, format: string? | string[]?, locale: string?) ⇒ string

        Date formatter used for displaying the selected date as value of the
        input field. As default, it returns dates formatted as{' '}
        YYYY-M-D.

        Arguments: format is the value coming from the{' '}

          format
        {' '}
        prop, while locale is from{' '}

          dayPickerProps
        .

        See also{' '}

          parseDate
        .

        If you are using moment.js in your
        app, we already provide this function as addon: see{' '}
        <Link to="/examples/input-moment">this example</Link>.

        <Anchor id="hideOnDayClick" />
        hideOnDayClick boolean = true

Hide the overlay when the user clicks on a day cell.

        <Anchor id="inputProps" />
        inputProps Object

        Additional props to add to the input component. The{' '}
        value key is ignored: use the{' '}

          value
        {' '}
        prop instead.

        <Anchor id="keepFocus" />
        keepFocus boolean = true

        Keep focus on the input field after switching the focus into the
        overlay. You may want to disable the focus on the input field when using
        an an
        overlayComponent.

        <Anchor id="overlayComponent" />
        overlayComponent React.Component

        A React element or constructor to use as overlay. The element will
        receive the following props:

          selectedDay: ?Date The currently selected day

          month: Date The month displayed in the calendar

          input: DOM Element The input field

        See also <Link to="/examples/input-custom-overlay">this example</Link>.

        <Anchor id="parseDate" />
        parseDate{' '}

          (str: string?, format: string? | string[]?, locale: string?) ⇒ Date |
          void

        Date parser used for parsing the string typed in the input field. As
        default, it parses only dates formatted as YYYY-M-D.

        Arguments: format is the value coming from the{' '}

          format
        {' '}
        prop, while locale is from{' '}

          dayPickerProps
        .
See also{' '}

          formatDate
        .

        If you are using moment.js in your
        app, we already provide this function as addon: see{' '}
        <Link to="/examples/input-moment">this example</Link>.

        <Anchor id="placeholder" />
        placeholder string

        The placeholder to use for the input field.

        <Anchor id="showOverlay" />
        showOverlay boolean = false

        Show the overlay during the initial rendering of the component. This is
        useful if you want to keep the overlay visibile while styling it.

        <Anchor id="value" />
        value string | Date

        The value of the input field.

Event handlers

        <Anchor id="onDayChange" />
        onDayChange (day: Date, modifiers: Object) ⇒ void

        Handler function called when the user types a valid day (according to
        the format prop) or when a day is clicked on the calendar.
        If the day is not valid, day and modifiers arguments will be{' '}
        undefined (useful to display validation warnings).

Public methods

        <Anchor id="getDayPicker" />
        getDayPicker () ⇒ DayPicker

Return the DayPicker instance.

        <Anchor id="getInput" />
        getInput () ⇒ DOMNode | ReactNode

Return the input element instance.

        <Anchor id="showDayPicker" />
        showDayPicker () ⇒ void

Show the Day Picker overlay.

        <Anchor id="hideDayPicker" />
        hideDayPicker () ⇒ void

Hide the Day Picker overlay.

    </ApiDocs>
  </DocPage>
);
<|endoftext|>


<commit_before>// Wait for the first part of the page to load
$(document).ready(function () {

    // Wait for the rest of the fancy dynamic stuff to load.
    // 5 seconds should be enough.
    setTimeout(function () {

        // Get a handle on the calendar grid
        $('div[role="grid"]').on('mousewheel', function (e) {

            // Scrolling.... hahhahahaha I don't think so
            if (e.target.id == 'el') return;
            e.preventDefault();
            e.stopPropagation();
        });
    }, 5000);
});
<commit_msg>Add use of MutationObserver to fix issues with new Google Calendar UI<commit_after>var calendar_grid = document.querySelector('div[role="grid"]');
var body = document.querySelector('body');

var disable_scroll = function () {
// Get a handle on the calendar grid
    $('div[role="grid"]').on('mousewheel', function (e) {

        // Scrolling.... hahhahahaha I don't think so
        if (e.target.id == 'el') return;
        e.preventDefault();
        e.stopPropagation();
    });
};

var mutation_breaks_scroll_blocker = function (mutation) {
    if (mutation.attributeName && mutation.attributeName == 'data-viewfamily') {
        if ($('body').attr('data-viewfamily') == 'EVENT')
            return true;
    }
};

var calendar_observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        if (mutation_breaks_scroll_blocker(mutation)) {
            disable_scroll();
        }
    });
});

// Wait for the first part of the page to load
$(document).ready(function () {
    if (!calendar_grid) {
        window.setTimeout(observe_if_calendar_available, 500);
        return;
    }

    // start observer
    calendar_observer.observe(body, {attributes: true});
});<|endoftext|>


<commit_before>ColorListGenerators._HARDCODED_CATEGORICAL_COLORS =new ColorList(
	"#dd4411", "#2200bb", "#1f77b4", "#ff660e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf", "#dd8811",
	"#dd0011", "#221140", "#1f66a3", "#ff220e", "#2ba01c", "#442728", "#945600", "#8c453a", "#e37700"
)

/**
* ColorListGenerators
* @constructor
*
*/
function ColorListGenerators(){};

/**
 * create a simple list of categorical colors
 * @param  {Number} nColors
 *
 * @param  {Number} alpha 0.5 by default
 * @return {ColorList}
 * tags:generator
 */
ColorListGenerators.createDefaultCategoricalColorList = function(nColors, alpha){
	alpha = alpha==null?0.5:alpha;
	return ColorListGenerators.createCategoricalColors(1, nColors).getInterpolated('black', 0.15).addAlpha(alpha);
}

/**
 * create a colorList based on a colorScale and values from a numberList (that will be normalized)
 * @param  {NumberList} numberList
 * @param  {ColorScale} colorScale
 * @param  {Number} mode 0:normalize numberList
 * @return {ColorList}
 * tags:generator
 */
ColorListGenerators.createColorListFromNumberList=function(numberList, colorScale, mode){
	mode = mode==null?0:mode;

	var colorList = new ColorList();
	var newNumberList;
	var i;

	switch(mode){
		case 0://0 to max
			newNumberList = numberList.getNormalizedToMax();
			break;
		case 1://min to max
			break;
		case 2://values between 0 and 1
			break;
	}

	for(i=0; newNumberList[i]!=null; i++){
		colorList.push(colorScale(newNumberList[i]));
	}

	return colorList;
}

ColorListGenerators.createColorListWithSingleColor=function(nColors, color){
	var colorList = new ColorList();
	for(var i=0; i<nColors; i++){
		colorList.push(color);
	}
	return colorList;
}

/**
 * Creates a ColorList of categorical colors
 * @param {Number} mode 0:simple picking from color scale function, 1:random (with seed), 2:hardcoded colors, 3:, 4:, 5:evolutionary algorithm, guarantees non consecutive similar colors
 * @param {Number} nColors
 *
 * @param {ColorScale} colorScaleFunction
 * @param {Number} alpha transparency
 * @param {String} interpolateColor color to interpolate
 * @param {Number} interpolateValue interpolation value [0, 1]
 * @return {ColorList} ColorList with categorical colors
 * tags:generator
 */
ColorListGenerators.createCategoricalColors=function(mode, nColors, colorScaleFunction, alpha, interpolateColor, interpolateValue){
	colorScaleFunction = colorScaleFunction==null?ColorScales.temperature:colorScaleFunction;

	var i;
	var colorList = new ColorList();
	switch(mode){
		case 0: //picking from ColorScale
			for(i=0;i<nColors;i++){
				colorList[i] = colorScaleFunction(i/(nColors-1));
			}
			break;
		case 1: //seeded random numbers
			var values = NumberListGenerators.createRandomNumberList(nColors, null, 0)
			for(i=0;i<nColors;i++){
				colorList[i] = colorScaleFunction(values[i]);
			}
			break;
		case 2:
			for(i=0;i<nColors;i++){
				colorList[i] = ColorListGenerators._HARDCODED_CATEGORICAL_COLORS[i%ColorListGenerators._HARDCODED_CATEGORICAL_COLORS.length];
			}
			break;
		case 5:
			var randomNumbersSource = NumberListGenerators.createRandomNumberList(1001, null, 0);
			var positions = NumberListGenerators.createSortedNumberList(nColors);
			var randomNumbers = NumberListGenerators.createRandomNumberList(nColors, null, 0);
			var randomPositions = ListOperators.sortListByNumberList(positions, randomNumbers);

			var nGenerations = Math.floor(nColors*2)+100;
			var nChildren = Math.floor(nColors*0.6)+5;
			var bestEvaluation = ColorListGenerators._evaluationFunction(randomPositions);
			var child;
			var bestChildren = randomPositions;
			var j;
			var nr=0;
			var evaluation;

			for(i=0;i<nGenerations;i++){
				for(j=0;j<nChildren;j++){
					child = ColorListGenerators._sortingVariation(randomPositions, randomNumbersSource[nr], randomNumbersSource[nr+1]);
					nr = (nr+2)%1001;
					evaluation = ColorListGenerators._evaluationFunction(child);
					if(evaluation>bestEvaluation){
						bestChildren = child;
						bestEvaluation = evaluation;
					}
				}
				randomPositions = bestChildren;
			}

			for(i=0; i<nColors; i++){
				colorList.push(colorScaleFunction((1/nColors) + randomPositions[i]/(nColors+1))); //TODO: make more efficient by pre-nuilding the colorList
			}
			break;
	}

	if(interpolateColor!=null && interpolateValue!=null){
		colorList = colorList.getInterpolated(interpolateColor, interpolateValue);
	}

	if(alpha){
		colorList = colorList.addAlpha(alpha);
	}

	return colorList;
}

ColorListGenerators._sortingVariation=function(numberList, rnd0, rnd1){ //private
	var newNumberList = numberList.clone();
	var pos0 = Math.floor(rnd0*newNumberList.length);
	var pos1 = Math.floor(rnd1*newNumberList.length);
	var cache = newNumberList[pos1];
	newNumberList[pos1] = newNumberList[pos0];
	newNumberList[pos0] = cache;
	return newNumberList;
}
ColorListGenerators._evaluationFunction=function(numberList){ //private
	var sum=0;
	var i;
	for(i=0; numberList[i+1]!=null; i++){
		sum+=Math.sqrt(Math.abs(numberList[i+1]-numberList[i]));
	}
	return sum;
}

/**
 * Creates a ColorList of categorical colors based on an input List. All entries with the same value will get the same color.
 * @param {List} the list containing categorical data
 *
 * @param {Number} alpha transparency
 * @param {String} color to mix
 * @param {Number} interpolation value (0-1) for color mix
 * @return {ColorList} ColorList with categorical colors
 * tags:generator
 */
ColorListGenerators.createCategoricalColorListForList = function( list, alpha, color, interpolate )
{
	if( !list )
		return new ColorList();
	if( !alpha )
		alpha = 1;
	if( !color )
		color = "#fff";
	if( !interpolate )
		interpolate = 0;

	list = List.fromArray( list );
	var diffValues = list.getWithoutRepetitions();
	var diffColors = ColorListGenerators.createCategoricalColors( 2, diffValues.length, null, alpha, color, interpolate );
	//var diffColors = ColorListGenerators.createDefaultCategoricalColorList( diffValues.length, 1 ).getInterpolated( color, interpolate );
	diffColors = diffColors.addAlpha(alpha);
	var colorDict = Table.fromArray( [ diffValues, diffColors ] );
	var fullColorList = ListOperators.translateWithDictionary(list, colorDict, "NULL" );
	return ColorList.fromArray( fullColorList );
}

<commit_msg>added colorList param to createCategoricalColorListForList<commit_after>ColorListGenerators._HARDCODED_CATEGORICAL_COLORS =new ColorList(
	"#dd4411", "#2200bb", "#1f77b4", "#ff660e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf", "#dd8811",
	"#dd0011", "#221140", "#1f66a3", "#ff220e", "#2ba01c", "#442728", "#945600", "#8c453a", "#e37700"
)

/**
* ColorListGenerators
* @constructor
*
*/
function ColorListGenerators(){};

/**
 * create a simple list of categorical colors
 * @param  {Number} nColors
 *
 * @param  {Number} alpha 0.5 by default
 * @return {ColorList}
 * tags:generator
 */
ColorListGenerators.createDefaultCategoricalColorList = function(nColors, alpha){
	alpha = alpha==null?0.5:alpha;
	return ColorListGenerators.createCategoricalColors(1, nColors).getInterpolated('black', 0.15).addAlpha(alpha);
}

/**
 * create a colorList based on a colorScale and values from a numberList (that will be normalized)
 * @param  {NumberList} numberList
 * @param  {ColorScale} colorScale
 * @param  {Number} mode 0:normalize numberList
 * @return {ColorList}
 * tags:generator
 */
ColorListGenerators.createColorListFromNumberList=function(numberList, colorScale, mode){
	mode = mode==null?0:mode;

	var colorList = new ColorList();
	var newNumberList;
	var i;

	switch(mode){
		case 0://0 to max
			newNumberList = numberList.getNormalizedToMax();
			break;
		case 1://min to max
			break;
		case 2://values between 0 and 1
			break;
	}

	for(i=0; newNumberList[i]!=null; i++){
		colorList.push(colorScale(newNumberList[i]));
	}

	return colorList;
}

ColorListGenerators.createColorListWithSingleColor=function(nColors, color){
	var colorList = new ColorList();
	for(var i=0; i<nColors; i++){
		colorList.push(color);
	}
	return colorList;
}

/**
 * Creates a ColorList of categorical colors
 * @param {Number} mode 0:simple picking from color scale function, 1:random (with seed), 2:hardcoded colors, 3:, 4:, 5:evolutionary algorithm, guarantees non consecutive similar colors
 * @param {Number} nColors
 *
 * @param {ColorScale} colorScaleFunction
 * @param {Number} alpha transparency
 * @param {String} interpolateColor color to interpolate
 * @param {Number} interpolateValue interpolation value [0, 1]
 * @return {ColorList} ColorList with categorical colors
 * tags:generator
 */
ColorListGenerators.createCategoricalColors=function(mode, nColors, colorScaleFunction, alpha, interpolateColor, interpolateValue){
	colorScaleFunction = colorScaleFunction==null?ColorScales.temperature:colorScaleFunction;

	var i;
	var colorList = new ColorList();
	switch(mode){
		case 0: //picking from ColorScale
			for(i=0;i<nColors;i++){
				colorList[i] = colorScaleFunction(i/(nColors-1));
			}
			break;
		case 1: //seeded random numbers
			var values = NumberListGenerators.createRandomNumberList(nColors, null, 0)
			for(i=0;i<nColors;i++){
				colorList[i] = colorScaleFunction(values[i]);
			}
			break;
		case 2:
			for(i=0;i<nColors;i++){
				colorList[i] = ColorListGenerators._HARDCODED_CATEGORICAL_COLORS[i%ColorListGenerators._HARDCODED_CATEGORICAL_COLORS.length];
			}
			break;
		case 5:
			var randomNumbersSource = NumberListGenerators.createRandomNumberList(1001, null, 0);
			var positions = NumberListGenerators.createSortedNumberList(nColors);
			var randomNumbers = NumberListGenerators.createRandomNumberList(nColors, null, 0);
			var randomPositions = ListOperators.sortListByNumberList(positions, randomNumbers);

			var nGenerations = Math.floor(nColors*2)+100;
			var nChildren = Math.floor(nColors*0.6)+5;
			var bestEvaluation = ColorListGenerators._evaluationFunction(randomPositions);
			var child;
			var bestChildren = randomPositions;
			var j;
			var nr=0;
			var evaluation;

			for(i=0;i<nGenerations;i++){
				for(j=0;j<nChildren;j++){
					child = ColorListGenerators._sortingVariation(randomPositions, randomNumbersSource[nr], randomNumbersSource[nr+1]);
					nr = (nr+2)%1001;
					evaluation = ColorListGenerators._evaluationFunction(child);
					if(evaluation>bestEvaluation){
						bestChildren = child;
						bestEvaluation = evaluation;
					}
				}
				randomPositions = bestChildren;
			}

			for(i=0; i<nColors; i++){
				colorList.push(colorScaleFunction((1/nColors) + randomPositions[i]/(nColors+1))); //TODO: make more efficient by pre-nuilding the colorList
			}
			break;
	}

	if(interpolateColor!=null && interpolateValue!=null){
		colorList = colorList.getInterpolated(interpolateColor, interpolateValue);
	}

	if(alpha){
		colorList = colorList.addAlpha(alpha);
	}

	return colorList;
}

ColorListGenerators._sortingVariation=function(numberList, rnd0, rnd1){ //private
	var newNumberList = numberList.clone();
	var pos0 = Math.floor(rnd0*newNumberList.length);
	var pos1 = Math.floor(rnd1*newNumberList.length);
	var cache = newNumberList[pos1];
	newNumberList[pos1] = newNumberList[pos0];
	newNumberList[pos0] = cache;
	return newNumberList;
}
ColorListGenerators._evaluationFunction=function(numberList){ //private
	var sum=0;
	var i;
	for(i=0; numberList[i+1]!=null; i++){
		sum+=Math.sqrt(Math.abs(numberList[i+1]-numberList[i]));
	}
	return sum;
}

/**
 * Creates a ColorList of categorical colors based on an input List. All entries with the same value will get the same color.
 * @param {List} the list containing categorical data
 *
 * @param {ColorList} ColorList with categorical colors
 * @param {Number} alpha transparency
 * @param {String} color to mix
 * @param {Number} interpolation value (0-1) for color mix
 * @return {ColorList} ColorList with categorical colors
 * tags:generator
 */
ColorListGenerators.createCategoricalColorListForList = function( list, colorList, alpha, color, interpolate )
{
	console.log( "createCategoricalColorListForList: ", colorList);

	if( !list )
		return new ColorList();
	if( !alpha )
		alpha = 1;
	if( !color )
		color = "#fff";
	if( !interpolate )
		interpolate = 0;

	list = List.fromArray( list );
	var diffValues = list.getWithoutRepetitions();
	var diffColors;
	if( colorList )
		diffColors = colorList;
	else
		diffColors = ColorListGenerators.createCategoricalColors( 2, diffValues.length, null, alpha, color, interpolate );
	//var diffColors = ColorListGenerators.createDefaultCategoricalColorList( diffValues.length, 1 ).getInterpolated( color, interpolate );
	diffColors = diffColors.addAlpha(alpha);
	var colorDict = Table.fromArray( [ diffValues, diffColors ] );
	var fullColorList = ListOperators.translateWithDictionary(list, colorDict, "NULL" );
	return ColorList.fromArray( fullColorList );
}

<|endoftext|>


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

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('xtend')
var fs = require('fs')
var mkdirp = require('mkdirp')
var os = require('os')
var parallelLimit = require('run-parallel-limit')
var path = require('path')
var test = require('tape')

var GIT = 'git'
var STANDARD = path.join(__dirname, '..', 'bin', 'cmd.js')
var TMP = path.join(__dirname, '..', 'tmp')

var PARALLEL_LIMIT = Math.min(os.cpus().length * 1.5)

var URLS = [
  /**
   * IF YOUR REPO USES STANDARD STYLE, PLEASE SUBMIT A PR WITH THE URL!
   */
  'https://github.com/ahmadnassri/echint.git',
  'https://github.com/ahmadnassri/forwarded-http.git',
  'https://github.com/ahmadnassri/har-convert.git',
  'https://github.com/ahmadnassri/har-expander.git',
  'https://github.com/ahmadnassri/har-validator.git',
  'https://github.com/ahmadnassri/har.git',
  'https://github.com/ahmadnassri/metalsmith-imagemin.git',
  'https://github.com/ahmadnassri/metalsmith-jade.git',
  'https://github.com/ahmadnassri/metalsmith-paths.git',
  'https://github.com/ahmadnassri/metalsmith-request.git',
  'https://github.com/ahmadnassri/node-clone-benchmark.git',
  'https://github.com/ahmadnassri/pkg-config.git',
  'https://github.com/ahmadnassri/stringify-clone.git',
  'https://github.com/ahmadnassri/winston-tcp.git',
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/brandonhorst/coverage-test.git',
  'https://github.com/cjb/GitTorrent.git',
  'https://github.com/feross/available.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-protocol.git',
  'https://github.com/feross/bittorrent-swarm.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/blob-to-buffer.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/create-torrent.git',
  'https://github.com/feross/downgrade.git',
  'https://github.com/feross/drag-drop.git',
  'https://github.com/feross/ieee754.git',
  'https://github.com/feross/instant.io.git',
  'https://github.com/feross/is-buffer.git',
  'https://github.com/feross/load-ip-set.git',
  'https://github.com/feross/magnet-uri.git',
  'https://github.com/feross/multistream.git',
  'https://github.com/feross/parse-torrent-file.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/run-auto.git',
  'https://github.com/feross/run-parallel-limit.git',
  'https://github.com/feross/run-parallel.git',
  'https://github.com/feross/run-series.git',
  'https://github.com/feross/run-waterfall.git',
  'https://github.com/feross/simple-peer.git',
  'https://github.com/feross/simple-websocket.git',
  'https://github.com/feross/snazzy.git',
  'https://github.com/feross/standard-www.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/torrent-discovery.git',
  'https://github.com/feross/typedarray-to-buffer.git',
  'https://github.com/feross/unlimited.git',
  'https://github.com/feross/webtorrent-hybrid.git',
  'https://github.com/feross/webtorrent-www.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/feross/whiteboard.git',
  'https://github.com/Flet/battery.git',
  'https://github.com/Flet/clockmoji.git',
  'https://github.com/Flet/dailyconnect.git',
  'https://github.com/Flet/exitzero.git',
  'https://github.com/Flet/standard-engine.git',
  'https://github.com/karma-runner/karma-coverage.git',
  'https://github.com/mafintosh/airpaste.git',
  'https://github.com/mafintosh/chromecasts.git',
  'https://github.com/mafintosh/cyclist.git',
  'https://github.com/mafintosh/difffs.git',
  'https://github.com/mafintosh/fuse-bindings.git',
  'https://github.com/mafintosh/hms-protocol.git',
  'https://github.com/mafintosh/hms.git',
  // 'https://github.com/mafintosh/hyperlog.git',
  'https://github.com/mafintosh/idlecast.git',
  'https://github.com/mafintosh/json-format-stream.git',
  'https://github.com/mafintosh/level-enumerate.git',
  'https://github.com/mafintosh/level-logs.git',
  'https://github.com/mafintosh/level-temp.git',
  // 'https://github.com/mafintosh/multileveldown.git',
  'https://github.com/mafintosh/node-gyp-install.git',
  // 'https://github.com/mafintosh/pbs.git',
  'https://github.com/mafintosh/random-iterate.git',
  'https://github.com/mafintosh/sorted-intersect-stream.git',
  'https://github.com/mafintosh/ssh-exec.git',
  'https://github.com/mafintosh/swap-to-level.git',
  'https://github.com/mafintosh/telephone.git',
  'https://github.com/mafintosh/transport-stream.git',
  'https://github.com/mafintosh/what-line-is-this.git',
  'https://github.com/Mashape/alf-validator.git',
  'https://github.com/Mashape/httpsnippet.git',
  'https://github.com/maxogden/atomic-queue.git',
  'https://github.com/maxogden/dat-core.git',
  'https://github.com/maxogden/dat.git',
  'https://github.com/maxogden/dependency-check.git',
  'https://github.com/maxogden/electron-packager.git',
  'https://github.com/maxogden/requirebin.git',
  'https://github.com/maxogden/screencat.git',
  'https://github.com/maxogden/standard-format.git',
  'https://github.com/maxogden/tape-spawn.git',
  'https://github.com/maxogden/temporary-directory.git',
  'https://github.com/maxogden/torrent.git',
  'https://github.com/mcollina/fastfall.git',
  'https://github.com/mcollina/fastparallel.git',
  'https://github.com/mcollina/fastq.git',
  'https://github.com/mcollina/fastseries.git',
  'https://github.com/mcollina/hyperemitter.git',
  'https://github.com/mcollina/mqemitter-mongodb.git',
  'https://github.com/mcollina/mqemitter-p2p.git',
  'https://github.com/mcollina/mqemitter-redis.git',
  'https://github.com/mcollina/mqemitter.git',
  'https://github.com/mcollina/pruneold.git',
  'https://github.com/moose-team/friends-swarm.git',
  'https://github.com/moose-team/friends.git',
  'https://github.com/moose-team/peerbot.git',
  'https://github.com/motdotla/dotenv.git',
  'https://github.com/ngoldman/changelog-parser.git',
  'https://github.com/ngoldman/gh-release.git',
  'https://github.com/ngoldman/magnet-link.git',
  'https://github.com/ngoldman/module-init.git',
  'https://github.com/ngoldman/wireframe.css.git',
  'https://github.com/npm/fstream.git',
  // 'https://github.com/npm/npm.git',
  'https://github.com/npm/docs.git',
  'https://github.com/npm/fstream-npm.git',
  'https://github.com/othiym23/nothingness-level.git',
  'https://github.com/othiym23/nothingness.git',
  'https://github.com/yoshuawuyts/assert-npm-version.git',
  'https://github.com/yoshuawuyts/brick-router.git',
  'https://github.com/yoshuawuyts/brick-server.git',
  'https://github.com/yoshuawuyts/event-bulk-attach.git',
  'https://github.com/yoshuawuyts/fat-arrow.git',
  'https://github.com/yoshuawuyts/from2-string.git',
  'https://github.com/yoshuawuyts/fsm-event.git',
  'https://github.com/yoshuawuyts/initialize.git',
  'https://github.com/yoshuawuyts/koa-logger-ndjson.git',
  'https://github.com/yoshuawuyts/mdjson.git',
  'https://github.com/yoshuawuyts/promise-assert.git',
  'https://github.com/yoshuawuyts/simple-store.git',
  'https://github.com/yoshuawuyts/urit.git',
  'https://github.com/yoshuawuyts/virtual-raf.git',
  'https://github.com/yoshuawuyts/vmd.git',
  'https://github.com/yoshuawuyts/wayfarer.git',
  'https://github.com/yoshuawuyts/year-of-code.git'
]

var MODULES = {}
URLS.forEach(function (url) {
  var name = /\/([^\/]+)\.git$/.exec(url)[1]
  MODULES[name] = url
})

test('test github repos that use `standard`', function (t) {
  t.plan(URLS.length)

  mkdirp.sync(TMP)

  // test an empty repo
  mkdirp.sync(path.join(TMP, 'empty'))

  parallelLimit(Object.keys(MODULES).map(function (name) {
    var url = MODULES[name]
    var folder = path.join(TMP, name)
    return function (cb) {
      fsAccess(path.join(TMP, name), fs.R_OK | fs.W_OK, function (err) {
        var gitArgs = err
          ? [ 'clone', '--depth', 1, url, path.join(TMP, name) ]
          : [ 'pull' ]
        var gitOpts = err
          ? {}
          : { cwd: folder }
        spawn(GIT, gitArgs, gitOpts, function (err) {
          if (err) {
            err.message += ' (' + name + ')'
            return cb(err)
          }

          spawn(STANDARD, [ '--verbose' ], { cwd: folder }, function (err) {
            t.error(err, name)
            cb(null)
          })
        })
      })
    }
  }), PARALLEL_LIMIT, function (err) {
    if (err) throw err
  })
})

// TODO: Spawn in a way that works on Windows – PR welcome!
function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', cb)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}

function fsAccess (path, mode, cb) {
  if (typeof fs.access === 'function') {
    fs.access(path, mode, cb)
  } else {
    fs.stat(path, cb)
  }
}
<commit_msg>disable new failing test<commit_after>#!/usr/bin/env node

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('xtend')
var fs = require('fs')
var mkdirp = require('mkdirp')
var os = require('os')
var parallelLimit = require('run-parallel-limit')
var path = require('path')
var test = require('tape')

var GIT = 'git'
var STANDARD = path.join(__dirname, '..', 'bin', 'cmd.js')
var TMP = path.join(__dirname, '..', 'tmp')

var PARALLEL_LIMIT = Math.min(os.cpus().length * 1.5)

var URLS = [
  /**
   * IF YOUR REPO USES STANDARD STYLE, PLEASE SUBMIT A PR WITH THE URL!
   */
  'https://github.com/ahmadnassri/echint.git',
  'https://github.com/ahmadnassri/forwarded-http.git',
  'https://github.com/ahmadnassri/har-convert.git',
  'https://github.com/ahmadnassri/har-expander.git',
  'https://github.com/ahmadnassri/har-validator.git',
  'https://github.com/ahmadnassri/har.git',
  'https://github.com/ahmadnassri/metalsmith-imagemin.git',
  'https://github.com/ahmadnassri/metalsmith-jade.git',
  'https://github.com/ahmadnassri/metalsmith-paths.git',
  'https://github.com/ahmadnassri/metalsmith-request.git',
  'https://github.com/ahmadnassri/node-clone-benchmark.git',
  'https://github.com/ahmadnassri/pkg-config.git',
  'https://github.com/ahmadnassri/stringify-clone.git',
  'https://github.com/ahmadnassri/winston-tcp.git',
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/brandonhorst/coverage-test.git',
  'https://github.com/cjb/GitTorrent.git',
  'https://github.com/feross/available.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-protocol.git',
  'https://github.com/feross/bittorrent-swarm.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/blob-to-buffer.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/create-torrent.git',
  'https://github.com/feross/downgrade.git',
  'https://github.com/feross/drag-drop.git',
  'https://github.com/feross/ieee754.git',
  'https://github.com/feross/instant.io.git',
  'https://github.com/feross/is-buffer.git',
  'https://github.com/feross/load-ip-set.git',
  'https://github.com/feross/magnet-uri.git',
  'https://github.com/feross/multistream.git',
  'https://github.com/feross/parse-torrent-file.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/run-auto.git',
  'https://github.com/feross/run-parallel-limit.git',
  'https://github.com/feross/run-parallel.git',
  'https://github.com/feross/run-series.git',
  'https://github.com/feross/run-waterfall.git',
  'https://github.com/feross/simple-peer.git',
  'https://github.com/feross/simple-websocket.git',
  'https://github.com/feross/snazzy.git',
  'https://github.com/feross/standard-www.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/torrent-discovery.git',
  'https://github.com/feross/typedarray-to-buffer.git',
  'https://github.com/feross/unlimited.git',
  'https://github.com/feross/webtorrent-hybrid.git',
  'https://github.com/feross/webtorrent-www.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/feross/whiteboard.git',
  'https://github.com/Flet/battery.git',
  'https://github.com/Flet/clockmoji.git',
  'https://github.com/Flet/dailyconnect.git',
  'https://github.com/Flet/exitzero.git',
  'https://github.com/Flet/standard-engine.git',
  // 'https://github.com/karma-runner/karma-coverage.git',
  'https://github.com/mafintosh/airpaste.git',
  'https://github.com/mafintosh/chromecasts.git',
  'https://github.com/mafintosh/cyclist.git',
  'https://github.com/mafintosh/difffs.git',
  'https://github.com/mafintosh/fuse-bindings.git',
  'https://github.com/mafintosh/hms-protocol.git',
  'https://github.com/mafintosh/hms.git',
  // 'https://github.com/mafintosh/hyperlog.git',
  'https://github.com/mafintosh/idlecast.git',
  'https://github.com/mafintosh/json-format-stream.git',
  'https://github.com/mafintosh/level-enumerate.git',
  'https://github.com/mafintosh/level-logs.git',
  'https://github.com/mafintosh/level-temp.git',
  // 'https://github.com/mafintosh/multileveldown.git',
  'https://github.com/mafintosh/node-gyp-install.git',
  // 'https://github.com/mafintosh/pbs.git',
  'https://github.com/mafintosh/random-iterate.git',
  'https://github.com/mafintosh/sorted-intersect-stream.git',
  'https://github.com/mafintosh/ssh-exec.git',
  'https://github.com/mafintosh/swap-to-level.git',
  'https://github.com/mafintosh/telephone.git',
  'https://github.com/mafintosh/transport-stream.git',
  'https://github.com/mafintosh/what-line-is-this.git',
  'https://github.com/Mashape/alf-validator.git',
  'https://github.com/Mashape/httpsnippet.git',
  'https://github.com/maxogden/atomic-queue.git',
  'https://github.com/maxogden/dat-core.git',
  'https://github.com/maxogden/dat.git',
  'https://github.com/maxogden/dependency-check.git',
  'https://github.com/maxogden/electron-packager.git',
  'https://github.com/maxogden/requirebin.git',
  'https://github.com/maxogden/screencat.git',
  'https://github.com/maxogden/standard-format.git',
  'https://github.com/maxogden/tape-spawn.git',
  'https://github.com/maxogden/temporary-directory.git',
  'https://github.com/maxogden/torrent.git',
  'https://github.com/mcollina/fastfall.git',
  'https://github.com/mcollina/fastparallel.git',
  'https://github.com/mcollina/fastq.git',
  'https://github.com/mcollina/fastseries.git',
  'https://github.com/mcollina/hyperemitter.git',
  'https://github.com/mcollina/mqemitter-mongodb.git',
  'https://github.com/mcollina/mqemitter-p2p.git',
  'https://github.com/mcollina/mqemitter-redis.git',
  'https://github.com/mcollina/mqemitter.git',
  'https://github.com/mcollina/pruneold.git',
  'https://github.com/moose-team/friends-swarm.git',
  'https://github.com/moose-team/friends.git',
  'https://github.com/moose-team/peerbot.git',
  'https://github.com/motdotla/dotenv.git',
  'https://github.com/ngoldman/changelog-parser.git',
  'https://github.com/ngoldman/gh-release.git',
  'https://github.com/ngoldman/magnet-link.git',
  'https://github.com/ngoldman/module-init.git',
  'https://github.com/ngoldman/wireframe.css.git',
  'https://github.com/npm/fstream.git',
  // 'https://github.com/npm/npm.git',
  'https://github.com/npm/docs.git',
  'https://github.com/npm/fstream-npm.git',
  'https://github.com/othiym23/nothingness-level.git',
  'https://github.com/othiym23/nothingness.git',
  'https://github.com/yoshuawuyts/assert-npm-version.git',
  'https://github.com/yoshuawuyts/brick-router.git',
  'https://github.com/yoshuawuyts/brick-server.git',
  'https://github.com/yoshuawuyts/event-bulk-attach.git',
  'https://github.com/yoshuawuyts/fat-arrow.git',
  'https://github.com/yoshuawuyts/from2-string.git',
  'https://github.com/yoshuawuyts/fsm-event.git',
  'https://github.com/yoshuawuyts/initialize.git',
  'https://github.com/yoshuawuyts/koa-logger-ndjson.git',
  'https://github.com/yoshuawuyts/mdjson.git',
  'https://github.com/yoshuawuyts/promise-assert.git',
  'https://github.com/yoshuawuyts/simple-store.git',
  'https://github.com/yoshuawuyts/urit.git',
  'https://github.com/yoshuawuyts/virtual-raf.git',
  'https://github.com/yoshuawuyts/vmd.git',
  'https://github.com/yoshuawuyts/wayfarer.git',
  'https://github.com/yoshuawuyts/year-of-code.git'
]

var MODULES = {}
URLS.forEach(function (url) {
  var name = /\/([^\/]+)\.git$/.exec(url)[1]
  MODULES[name] = url
})

test('test github repos that use `standard`', function (t) {
  t.plan(URLS.length)

  mkdirp.sync(TMP)

  // test an empty repo
  mkdirp.sync(path.join(TMP, 'empty'))

  parallelLimit(Object.keys(MODULES).map(function (name) {
    var url = MODULES[name]
    var folder = path.join(TMP, name)
    return function (cb) {
      fsAccess(path.join(TMP, name), fs.R_OK | fs.W_OK, function (err) {
        var gitArgs = err
          ? [ 'clone', '--depth', 1, url, path.join(TMP, name) ]
          : [ 'pull' ]
        var gitOpts = err
          ? {}
          : { cwd: folder }
        spawn(GIT, gitArgs, gitOpts, function (err) {
          if (err) {
            err.message += ' (' + name + ')'
            return cb(err)
          }

          spawn(STANDARD, [ '--verbose' ], { cwd: folder }, function (err) {
            t.error(err, name)
            cb(null)
          })
        })
      })
    }
  }), PARALLEL_LIMIT, function (err) {
    if (err) throw err
  })
})

// TODO: Spawn in a way that works on Windows – PR welcome!
function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', cb)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}

function fsAccess (path, mode, cb) {
  if (typeof fs.access === 'function') {
    fs.access(path, mode, cb)
  } else {
    fs.stat(path, cb)
  }
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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.                                             */
/* -------------------------------------------------------------------------- */

define(function(require) {
  /*
    DEPENDENCIES
   */

  var DomDataTable = require('utils/dom-datatable');
  var Locale = require('utils/locale');
  var OpenNebulaRole = require('opennebula/role');
  var OpenNebulaVM = require("opennebula/vm");
  var RolesButtons = require('./roles/roles-buttons');
  var RolesVmButtons = require('./roles/roles-vm-buttons');
  var StateRolesButtons = require('./roles/state-roles-buttons');
  var StateRolesVmButtons = require('./roles/state-roles-vm-buttons');
  var Sunstone = require('sunstone');
  var Tips = require('utils/tips');
  var VMRemoteActions = require('utils/remote-actions');

  /*
    TEMPLATES
   */

  var TemplateHTML = require("hbs!./roles/html");
  var TemplateRoleInfo = require("hbs!./roles/roleInfo");

  /*
    CONSTANTS
   */

  var TAB_ID = require("../tabId");
  var PANEL_ID = require("./roles/panelId");
  var XML_ROOT = "DOCUMENT";

  var lastRoleIndexSelected = undefined;

  /*
    CONSTRUCTOR
   */

  function Panel(info) {
    this.title = Locale.tr("Roles");
    this.icon = "fa-wrench";

    this.element = info[XML_ROOT];

    // Controls visibility of buttons only available to OneFlow services. This
    // panel is also used by the OneFlow templates
    this.servicePanel = true;

    this.panelId = PANEL_ID;

    return this;
  }

  Panel.PANEL_ID = PANEL_ID;
  Panel.prototype.html = _html;
  Panel.prototype.setup = _setup;
  Panel.prototype.getState = _getState;
  Panel.prototype.setState = _setState;
  Panel.prototype.roleHTML = _roleHTML;
  Panel.prototype.roleSetup = _roleSetup;

  return Panel;

  /*
    FUNCTION DEFINITIONS
   */

  function _html() {
    var roleList = [];

    var roles = this.element.TEMPLATE.BODY.roles;
    if (roles && roles.length) {
      $.each(roles, function(){
        roleList.push(
          {
            "name": this.name,
            "state": OpenNebulaRole.state(this.state),
            "cardinality": this.cardinality,
            "vm_template": this.vm_template,
            "parents": this.parents ? this.parents.join(", ") : "-"
          });
      });
    }

    return TemplateHTML({
      "element": this.element,
      "panelId": this.panelId,
      "servicePanel": this.servicePanel,
      "roleList": roleList
    });
  }

  function _getState() {
    var state = {};

    if (this.servicerolesDataTable){
      var selectedCheck = $(".check_item:checked", this.servicerolesDataTable.dataTable);

      if (selectedCheck.length > 0){
        state["selectedRole"] = selectedCheck.attr("id");

        if(this.serviceroleVMsDataTable){
          var selectedVMs = [];

          $.each($(".check_item:checked", this.serviceroleVMsDataTable.dataTable), function(){
            selectedVMs.push($(this).attr("id"));
          });

          if (selectedVMs.length > 0){
            state["selectedVMs"] = selectedVMs;
          }
        }
      }
    }

    return state;
  }

  function _setState(state, _) {
    var that = this;

    if (that.servicerolesDataTable && state["selectedRole"]){
      $(".check_item[id=\""+state["selectedRole"]+"\"]", that.servicerolesDataTable.dataTable).closest("tr").click();
    }

    if (that.serviceroleVMsDataTable && state["selectedVMs"]){
      $.each(state["selectedVMs"], function(){
        $(".check_item[id=\""+this+"\"]", that.serviceroleVMsDataTable.dataTable).closest("tr").click();
      });
    }
  }

  function _setup(context) {
    var that = this;
    var roles = this.roles = that.element.TEMPLATE.BODY.roles;

    Tips.setup(context);

    console.log()

    $('#addRoleBtn').on('click', function(event){
      event.preventDefault();
      Sunstone.runAction("Role.add_dialog");
    });

    if (roles && roles.length) {
      that.servicerolesDataTable = new DomDataTable(
        "datatable_roles_"+this.panelId,
        {
          actions: true,
          info: false,
          oneSelection: true,
          customTabContext: $("#role_actions", context),
          customTrListener: function(tableObj, tr){
            var rowData = tableObj.dataTable.fnGetData(tr);
            var roleName = $(rowData[0]).data().name

            var roleIndexSelected = roles.findIndex(function(role) {
              return role.name === String(roleName)
            })

            var roleSelected = roles[roleIndexSelected];
            var isEqualLastIndex = lastRoleIndexSelected === roleIndexSelected;

            StateRolesButtons.enableStateActions(roleSelected.state);

            if (!isEqualLastIndex) {
              lastRoleIndexSelected = roleIndexSelected;
            }

            $("#roles_extended_info, context")
              .fadeOut(isEqualLastIndex ? 0 : "slow", function() {
                $(this).html(that.roleHTML(context, roleSelected));
                that.roleSetup($(this), roleSelected);
              })
              .fadeIn(isEqualLastIndex ? 0 : "slow");

            // The info listener is triggered instead of
            // the row selection. So we click the check input to select
            // the row also
            var check = $(".check_item", tr);
            if (!check.is(":checked")) {
              check.trigger("click");
            }
          }
        });

      this.servicerolesDataTable.initialize();

      Sunstone.insertButtonsInTab(TAB_ID, "service_roles_tab", RolesButtons, $("#role_actions", context));
    }
  }

  function _roleHTML(context, role, callback) {
    var that = this;
    var ready_status_gate = that.element.TEMPLATE.BODY.ready_status_gate;
    var promises = [];
    var roleVms = [];

    if (role.nodes) {
      $.each(role.nodes, function(index, node){
        var vm_info = node.vm_info;

        var id = vm_info ? vm_info.VM.ID : node.deploy_id;
        var name = vm_info ? vm_info.VM.NAME : "";
        var uname = vm_info ? vm_info.VM.UNAME : "";
        var gname = vm_info ? vm_info.VM.GNAME : "";
        var ips = "", actions = "";

        function successCallback (data) {
          if (data && data.ID === id) {
            var ready = "";
            if (ready_status_gate) {
              ready = (data.USER_TEMPLATE && data.USER_TEMPLATE.READY == "YES")
                ? ""
                : "";
            }
            ips = OpenNebulaVM.ipsDropdown(data);

            actions = VMRemoteActions.renderActionsHtml(data);
          }

          roleVms[index] = rowInfoRoleVm(ready, id, name, uname, gname, ips, actions, data.STATE, data.LCM_STATE);
        }

        promises.push(OpenNebulaVM.promiseGetVm({ id, success: successCallback }));
      });
    }

    $.when.apply($, promises).then(function() {
        if (that.serviceroleVMsDataTable) {
          that.serviceroleVMsDataTable.updateView(null, roleVms, true);
          VMRemoteActions.bindActionsToContext(context);
        }

        if (callback && typeof callback === "function") {
          callback();
        }

        Tips.setup(context);
      });

    return TemplateRoleInfo({
      "role": role,
      "servicePanel": that.servicePanel,
      "panelId": that.panelId,
      "vmsTableColumns": [
        Locale.tr("ID"),
        Locale.tr("Name"),
        Locale.tr("Owner"),
        Locale.tr("Group"),
        Locale.tr("IPs"),
        "" // Remote actions
      ],
      "vms": roleVms
    });
  }

  function rowInfoRoleVm(ready, id, name = "", uname = "", gname = "", ips = "", actions = "", state, lcm_state) {
    return [
      ready,
      "<input class=\"check_item\" " +
        "style=\"vertical-align: inherit;\" " +
        "type=\"checkbox\" " +
        "id=\"vm_" + id + "\" " +
        "name=\"selected_items\" " +
        "value=\"" + id + "\" " +
        "state=\"" + state + "\" " +
        "lcm_state=\"" + lcm_state + "\" />",
      ""+ id +"",
      name,
      uname,
      gname,
      ips,
      actions
    ];
  }

  function _roleSetup(context, role) {
    var that = this;

    if(that.servicePanel) {
      that.serviceroleVMsDataTable = new DomDataTable(
        "datatable_vms_" + that.panelId + "_" + role.name,
        {
          actions: true,
          info: false,
          customTabContext: $("#role_vms_actions", context),
          dataTableOptions: {
            "bAutoWidth": false,
            "bSortClasses" : false,
            "bDeferRender": true,
            "aoColumnDefs": [
              {"bSortable": false, "aTargets": ["check", 5, 6]}
            ]
          }
        }
      );

      that.serviceroleVMsDataTable.initialize();

      Sunstone.insertButtonsInTab(
        TAB_ID,
        "service_roles_tab",
        RolesVmButtons,
        $("div#role_vms_actions", context)
      );

      $("#role_vms_actionsrefresh_buttons", context).on("click", function(event) {
        event.preventDefault();

        var prevRowsSelected = $(".check_item:checked", that.serviceroleVMsDataTable.dataTable);
        var prevIdsSelected = $.map(prevRowsSelected, function(row) {
          return $(row).attr("id");
        });

        var roleSelected = that.roles[lastRoleIndexSelected];

        that.roleHTML(context, roleSelected, function() {
          // for each previous selected vms
          $.each(prevIdsSelected, function(_, id) {
            // if exists yet, check it
            var currentRow = $("input#" + id, that.serviceroleVMsDataTable.dataTable);
            currentRow.length && currentRow.trigger("click");
          });
        });

        event.stopPropagation();
      });

      $("#" + that.serviceroleVMsDataTable.dataTableId)
        .on("change", "tbody input.check_item", function() {
          StateRolesVmButtons.disableAllStateActions();

          // Enable actions available to any of the selected VMs
          var nodes = $("tr", that.serviceroleVMsDataTable.dataTable); //visible nodes only
          $.each($("input.check_item:checked", nodes), function() {
            StateRolesVmButtons.enableStateActions($(this).attr("state"), $(this).attr("lcm_state"));
          });

          return true;
        });
    }
  }
});
<commit_msg>M #~: fix show icon in role datatable (#1397)<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2021, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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.                                             */
/* -------------------------------------------------------------------------- */

define(function(require) {
  /*
    DEPENDENCIES
   */

  var DomDataTable = require("utils/dom-datatable");
  var Locale = require("utils/locale");
  var OpenNebulaRole = require("opennebula/role");
  var OpenNebulaVM = require("opennebula/vm");
  var RolesButtons = require("./roles/roles-buttons");
  var RolesVmButtons = require("./roles/roles-vm-buttons");
  var StateRolesButtons = require("./roles/state-roles-buttons");
  var StateRolesVmButtons = require("./roles/state-roles-vm-buttons");
  var Sunstone = require("sunstone");
  var Tips = require("utils/tips");
  var VMRemoteActions = require("utils/remote-actions");

  /*
    TEMPLATES
   */

  var TemplateHTML = require("hbs!./roles/html");
  var TemplateRoleInfo = require("hbs!./roles/roleInfo");

  /*
    CONSTANTS
   */

  var TAB_ID = require("../tabId");
  var PANEL_ID = require("./roles/panelId");
  var XML_ROOT = "DOCUMENT";

  var lastRoleIndexSelected = undefined;

  /*
    CONSTRUCTOR
   */

  function Panel(info) {
    this.title = Locale.tr("Roles");
    this.icon = "fa-wrench";

    this.element = info[XML_ROOT];

    // Controls visibility of buttons only available to OneFlow services. This
    // panel is also used by the OneFlow templates
    this.servicePanel = true;

    this.panelId = PANEL_ID;

    return this;
  }

  Panel.PANEL_ID = PANEL_ID;
  Panel.prototype.html = _html;
  Panel.prototype.setup = _setup;
  Panel.prototype.getState = _getState;
  Panel.prototype.setState = _setState;
  Panel.prototype.roleHTML = _roleHTML;
  Panel.prototype.roleSetup = _roleSetup;

  return Panel;

  /*
    FUNCTION DEFINITIONS
   */

  function _html() {
    var roleList = [];

    var roles = this.element.TEMPLATE.BODY.roles;
    if (roles && roles.length) {
      $.each(roles, function(){
        roleList.push(
          {
            "name": this.name,
            "state": OpenNebulaRole.state(this.state),
            "cardinality": this.cardinality,
            "vm_template": this.vm_template,
            "parents": this.parents ? this.parents.join(", ") : "-"
          });
      });
    }

    return TemplateHTML({
      "element": this.element,
      "panelId": this.panelId,
      "servicePanel": this.servicePanel,
      "roleList": roleList
    });
  }

  function _getState() {
    var state = {};

    if (this.servicerolesDataTable){
      var selectedCheck = $(".check_item:checked", this.servicerolesDataTable.dataTable);

      if (selectedCheck.length > 0){
        state["selectedRole"] = selectedCheck.attr("id");

        if(this.serviceroleVMsDataTable){
          var selectedVMs = [];

          $.each($(".check_item:checked", this.serviceroleVMsDataTable.dataTable), function(){
            selectedVMs.push($(this).attr("id"));
          });

          if (selectedVMs.length > 0){
            state["selectedVMs"] = selectedVMs;
          }
        }
      }
    }

    return state;
  }

  function _setState(state, _) {
    var that = this;

    if (that.servicerolesDataTable && state["selectedRole"]){
      $(".check_item[id=\""+state["selectedRole"]+"\"]", that.servicerolesDataTable.dataTable).closest("tr").click();
    }

    if (that.serviceroleVMsDataTable && state["selectedVMs"]){
      $.each(state["selectedVMs"], function(){
        $(".check_item[id=\""+this+"\"]", that.serviceroleVMsDataTable.dataTable).closest("tr").click();
      });
    }
  }

  function _setup(context) {
    var that = this;
    var roles = this.roles = that.element.TEMPLATE.BODY.roles;

    Tips.setup(context);

    $("#addRoleBtn").on("click", function(event){
      event.preventDefault();
      Sunstone.runAction("Role.add_dialog");
    });

    if (roles && roles.length) {
      that.servicerolesDataTable = new DomDataTable(
        "datatable_roles_"+this.panelId,
        {
          actions: true,
          info: false,
          oneSelection: true,
          customTabContext: $("#role_actions", context),
          customTrListener: function(tableObj, tr){
            var rowData = tableObj.dataTable.fnGetData(tr);
            var roleName = $(rowData[0]).data().name;

            var roleIndexSelected = roles.findIndex(function(role) {
              return role.name === String(roleName);
            });

            var roleSelected = roles[roleIndexSelected];
            var isEqualLastIndex = lastRoleIndexSelected === roleIndexSelected;

            StateRolesButtons.enableStateActions(roleSelected.state);

            if (!isEqualLastIndex) {
              lastRoleIndexSelected = roleIndexSelected;
            }

            $("#roles_extended_info, context")
              .fadeOut(isEqualLastIndex ? 0 : "slow", function() {
                $(this).html(that.roleHTML(context, roleSelected));
                that.roleSetup($(this), roleSelected);
              })
              .fadeIn(isEqualLastIndex ? 0 : "slow");

            // The info listener is triggered instead of
            // the row selection. So we click the check input to select
            // the row also
            var check = $(".check_item", tr);
            if (!check.is(":checked")) {
              check.trigger("click");
            }
          }
        });

      this.servicerolesDataTable.initialize();

      Sunstone.insertButtonsInTab(TAB_ID, "service_roles_tab", RolesButtons, $("#role_actions", context));
    }
  }

  function _roleHTML(context, role, callback) {
    var that = this;
    var ready_status_gate = that.element.TEMPLATE.BODY.ready_status_gate;
    var promises = [];
    var roleVms = [];

    if (role.nodes) {
      $.each(role.nodes, function(index, node){
        var vm_info = node.vm_info;

        var id = vm_info ? vm_info.VM.ID : node.deploy_id;
        var name = vm_info ? vm_info.VM.NAME : "";
        var uname = vm_info ? vm_info.VM.UNAME : "";
        var gname = vm_info ? vm_info.VM.GNAME : "";
        var ips = "", actions = "";

        function successCallback (data) {
          if (data && data.ID === id) {
            var ready = "";
            var check = "";
            if (ready_status_gate && data.VM.USER_TEMPLATE && data.VM.USER_TEMPLATE.READY){
                ready = (data.VM.USER_TEMPLATE.READY === "YES")
                ? check
                : "";
            }else if(data.VM && data.VM.LCM_STATE && data.VM.LCM_STATE === "3"){
              ready = check;
            }
            ips = OpenNebulaVM.ipsDropdown(data);

            actions = VMRemoteActions.renderActionsHtml(data);
          }

          roleVms[index] = rowInfoRoleVm(ready, id, name, uname, gname, ips, actions, data.STATE, data.LCM_STATE);
        }

        promises.push(OpenNebulaVM.promiseGetVm({ id, success: successCallback }));
      });
    }

    $.when.apply($, promises).then(function() {
        if (that.serviceroleVMsDataTable) {
          that.serviceroleVMsDataTable.updateView(null, roleVms, true);
          VMRemoteActions.bindActionsToContext(context);
        }

        if (callback && typeof callback === "function") {
          callback();
        }

        Tips.setup(context);
      });

    return TemplateRoleInfo({
      "role": role,
      "servicePanel": that.servicePanel,
      "panelId": that.panelId,
      "vmsTableColumns": [
        Locale.tr("ID"),
        Locale.tr("Name"),
        Locale.tr("Owner"),
        Locale.tr("Group"),
        Locale.tr("IPs"),
        "" // Remote actions
      ],
      "vms": roleVms
    });
  }

  function rowInfoRoleVm(ready, id, name = "", uname = "", gname = "", ips = "", actions = "", state, lcm_state) {
    return [
      ready,
      "<input class=\"check_item\" " +
        "style=\"vertical-align: inherit;\" " +
        "type=\"checkbox\" " +
        "id=\"vm_" + id + "\" " +
        "name=\"selected_items\" " +
        "value=\"" + id + "\" " +
        "state=\"" + state + "\" " +
        "lcm_state=\"" + lcm_state + "\" />",
      ""+ id +"",
      name,
      uname,
      gname,
      ips,
      actions
    ];
  }

  function _roleSetup(context, role) {
    var that = this;

    if(that.servicePanel) {
      that.serviceroleVMsDataTable = new DomDataTable(
        "datatable_vms_" + that.panelId + "_" + role.name,
        {
          actions: true,
          info: false,
          customTabContext: $("#role_vms_actions", context),
          dataTableOptions: {
            "bAutoWidth": false,
            "bSortClasses" : false,
            "bDeferRender": true,
            "aoColumnDefs": [
              {"bSortable": false, "aTargets": ["check", 5, 6]}
            ]
          }
        }
      );

      that.serviceroleVMsDataTable.initialize();

      Sunstone.insertButtonsInTab(
        TAB_ID,
        "service_roles_tab",
        RolesVmButtons,
        $("div#role_vms_actions", context)
      );

      $("#role_vms_actionsrefresh_buttons", context).on("click", function(event) {
        event.preventDefault();

        var prevRowsSelected = $(".check_item:checked", that.serviceroleVMsDataTable.dataTable);
        var prevIdsSelected = $.map(prevRowsSelected, function(row) {
          return $(row).attr("id");
        });

        var roleSelected = that.roles[lastRoleIndexSelected];

        that.roleHTML(context, roleSelected, function() {
          // for each previous selected vms
          $.each(prevIdsSelected, function(_, id) {
            // if exists yet, check it
            var currentRow = $("input#" + id, that.serviceroleVMsDataTable.dataTable);
            currentRow.length && currentRow.trigger("click");
          });
        });

        event.stopPropagation();
      });

      $("#" + that.serviceroleVMsDataTable.dataTableId)
        .on("change", "tbody input.check_item", function() {
          StateRolesVmButtons.disableAllStateActions();

          // Enable actions available to any of the selected VMs
          var nodes = $("tr", that.serviceroleVMsDataTable.dataTable); //visible nodes only
          $.each($("input.check_item:checked", nodes), function() {
            StateRolesVmButtons.enableStateActions($(this).attr("state"), $(this).attr("lcm_state"));
          });

          return true;
        });
    }
  }
});
<|endoftext|>