<commit_before>/** @jsx React.DOM */
'use strict';
var React = require('react');
var jsonScriptEscape = require('../libs/jsonScriptEscape');
var globals = require('./globals');
var mixins = require('./mixins');
var NavBar = require('./navbar');
var Footer = require('./footer');
var fs = require('fs');
var url = require('url');

var portal = {
    portal_title: 'ENCODE',
    global_sections: [
        {id: 'data', title: 'Data', children: [
            {id: 'experiments', title: 'Experiments', url: '/search/?type=experiment'},
            {id: 'biosamples', title: 'Biosamples', url: '/search/?type=biosample'},
            {id: 'antibodies', title: 'Antibodies', url: '/search/?type=antibody_approval'},
            {id: 'targets', title: 'Targets', url: '/search/?type=target'},
            {id: 'datarelease', title: 'Data release policy', url: '/about/data-use-policy'}
        ]},
        {id: 'methods', title: 'Methods', children: [
            {id: 'integrativeanalysis', title: 'Integrative analysis', url: '/about/analysis'},
            {id: 'softwaretools', title: 'Software tools', url: '/about/tools'},
            {id: 'experimentguides', title: 'Experiment guidelines', url: '/about/experiment-guidelines'},
            {id: 'platformchar', title: 'Platform characterization', url: '/about/platform-characterizations'},
            {id: 'qualitymetrics', title: 'Quality metrics', url: '/about/quality-metrics'}
        ]},
        {id: 'about', title: 'About ENCODE', children: [
            {id: 'projectoverview', title: 'Project overview', url: '/about/contributors'},
            {id: 'publications', title: 'Publications', url: '/search/?type=publication'},
            {id: 'datarelease', title: 'Data release policy', url: '/about/data-use-policy'}
        ]},
        {id: 'help', title: 'Help', children: [
            {id: 'restapi', title: 'REST API', url: '/help/rest-api'},
            {id: 'fileformats', title: 'File formats', url: '/help/file-formats'},
            {id: 'contact', title: 'Contact', url: '/about/contacts'}
        ]}
    ]
};

var user_actions = [
    {id: 'signout', title: 'Sign out', trigger: 'logout'}
];

var scriptjs = fs.readFileSync(__dirname + '/../../../../node_modules/scriptjs/dist/script.min.js', 'utf-8');
var inline = fs.readFileSync(__dirname + '/../inline.js', 'utf8');

// App is the root component, mounted on document.body.
// It lives for the entire duration the page is loaded.
// App maintains state for the
var App = React.createClass({
    mixins: [mixins.Persona, mixins.HistoryAndTriggers],
    triggers: {
        login: 'triggerLogin',
        logout: 'triggerLogout',
    },

    getInitialState: function() {
        return {
            errors: [],
            portal: portal,
            user_actions: user_actions,
            dropdownComponent: undefined,
            activeComponent: undefined
        };
    },

    // Dropdown context using React context mechanism.
    childContextTypes: {
        dropdownComponent: React.PropTypes.string,
        onDropdownChange: React.PropTypes.func
    },

    // Retrieve current React context
    getChildContext: function() {
        return {
            dropdownComponent: this.state.dropdownComponent, // ID of component with visible dropdown
            onDropdownChange: this.handleDropdownChange // Function to process dropdown state change
        };
    },

    // When current dropdown changes; componentID is _rootNodeID of newly dropped-down component
    handleDropdownChange: function(componentID) {
        // Use React _rootNodeID to uniquely identify a dropdown menu;
        // It's passed in as componentID
        this.setState({dropdownComponent: componentID});
    },

    // Handle a click outside a dropdown menu by clearing currently dropped down menu
    handleLayoutClick: function(e) {
        if (this.state.dropdownComponent !== undefined) {
            this.setState({dropdownComponent: undefined});
        }
    },

    bindEvent: function (el, eventName, eventHandler) {
        if (el.addEventListener){
            el.addEventListener(eventName, eventHandler, false);
        } else if (el.attachEvent){
            el.attachEvent('on' + eventName, eventHandler);
        }
    },

    handleKey: function(e) {
        if (e.which === 27 && this.state.dropdownComponent !== undefined) {
            e.preventDefault();
            this.handleDropdownChange(undefined);
        }
    },

    componentDidMount: function() {
        this.bindEvent(window, 'keydown', this.handleKey);
    },

    render: function() {
        console.log('render app');
        var content;
        var context = this.props.context;
        var hash = url.parse(this.props.href).hash || '';
        var name;
        var context_actions = [];
        if (hash.slice(0, 2) === '#!') {
            name = hash.slice(2);
        }
        // Switching between collections may leave component in place
        var key = context && context['@id'];
        if (context) {
            Array.prototype.push.apply(context_actions, context.actions || []);
            if (!name && context.default_page) {
                context = context.default_page;
                var actions = context.actions || [];
                for (var i = 0; i < actions.length; i++) {
                    var action = actions[i];
                    if (action.href[0] == '#') {
                        action.href = context['@id'] + action.href;
                    }
                    context_actions.push(action);
                }
            }

            var ContentView = globals.content_views.lookup(context, name);
            content = this.transferPropsTo(ContentView({
                context: context,
                loadingComplete: this.state.loadingComplete,
                session: this.state.session,
                portal: this.state.portal,
                navigate: this.navigate
            }));
        }
        var errors = this.state.errors.map(function (error) {
            return

;
        });

        var appClass = 'done';
        if (this.props.slow) {
            appClass = 'communicating';
        }

        var title = context.title || context.name || context.accession || context['@id'];
        if (title && title != 'Home') {
            title = title + ' – ' + portal.portal_title;
        } else {
            title = portal.portal_title;
        }

        var canonical = context.canonical_uri || this.props.href;

        return (

                    <meta charSet="utf-8" />
                    <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
                    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                    <title>{title}</title>
                    <link rel="canonical" href={canonical} />

                    <link rel="stylesheet" href="/static/css/style.css" />

                                <NavBar href={this.props.href} portal={this.state.portal}
                                        context_actions={context_actions}
                                        user_actions={this.state.user_actions} session={this.state.session}
                                        loadingComplete={this.state.loadingComplete} />

                                    {content}

                                {errors}

        );
    }

});

module.exports = App;
<commit_msg>Merging in 1659-chtool. All further development for #1659 will happen in this branch.<commit_after>/** @jsx React.DOM */
'use strict';
var React = require('react');
var jsonScriptEscape = require('../libs/jsonScriptEscape');
var globals = require('./globals');
var mixins = require('./mixins');
var NavBar = require('./navbar');
var Footer = require('./footer');
var fs = require('fs');
var url = require('url');

var portal = {
    portal_title: 'ENCODE',
    global_sections: [
        {id: 'data', title: 'Data', children: [
            {id: 'assays', title: 'Assays', url: '/search/?type=experiment'},
            {id: 'biosamples', title: 'Biosamples', url: '/search/?type=biosample'},
            {id: 'antibodies', title: 'Antibodies', url: '/search/?type=antibody_approval'},
            {id: 'targets', title: 'Targets', url: '/search/?type=target'},
            {id: 'datarelease', title: 'Data release policy', url: '/about/data-use-policy'},
            {id: 'datastandards', title: 'Data standards', url: '/data-standards'},
            {id: 'otherresources', title: 'Other resources', url: '/about'}
        ]},
        {id: 'methods', title: 'Methods', children: [
            {id: 'softwaretools', title: 'Software tools', url: '/software'},
            {id: 'experimentguides', title: 'Experiment guidelines', url: '/about/experiment-guidelines'}
        ]},
        {id: 'about', title: 'About ENCODE', children: [
            {id: 'projectoverview', title: 'Project overview', url: '/about/contributors'},
            {id: 'news', title: 'News', url: '/news'},
            {id: 'publications', title: 'Publications', url: '/publications'},
            {id: 'datause', title: 'Data release policy', url: '/about/data-use-policy'}
        ]},
        {id: 'help', title: 'Help', children: [
            {id: 'restapi', title: 'REST API', url: '/help/rest-api'},
            {id: 'fileformats', title: 'File formats', url: '/help/file-formats'},
            {id: 'contact', title: 'Contact', url: '/help/contacts'}
        ]}
    ]
};

var user_actions = [
    {id: 'signout', title: 'Sign out', trigger: 'logout'}
];

var scriptjs = fs.readFileSync(__dirname + '/../../../../node_modules/scriptjs/dist/script.min.js', 'utf-8');
var inline = fs.readFileSync(__dirname + '/../inline.js', 'utf8');

// App is the root component, mounted on document.body.
// It lives for the entire duration the page is loaded.
// App maintains state for the
var App = React.createClass({
    mixins: [mixins.Persona, mixins.HistoryAndTriggers],
    triggers: {
        login: 'triggerLogin',
        logout: 'triggerLogout',
    },

    getInitialState: function() {
        return {
            errors: [],
            portal: portal,
            user_actions: user_actions,
            dropdownComponent: undefined,
            activeComponent: undefined
        };
    },

    // Dropdown context using React context mechanism.
    childContextTypes: {
        dropdownComponent: React.PropTypes.string,
        onDropdownChange: React.PropTypes.func
    },

    // Retrieve current React context
    getChildContext: function() {
        return {
            dropdownComponent: this.state.dropdownComponent, // ID of component with visible dropdown
            onDropdownChange: this.handleDropdownChange // Function to process dropdown state change
        };
    },

    // When current dropdown changes; componentID is _rootNodeID of newly dropped-down component
    handleDropdownChange: function(componentID) {
        // Use React _rootNodeID to uniquely identify a dropdown menu;
        // It's passed in as componentID
        this.setState({dropdownComponent: componentID});
    },

    // Handle a click outside a dropdown menu by clearing currently dropped down menu
    handleLayoutClick: function(e) {
        if (this.state.dropdownComponent !== undefined) {
            this.setState({dropdownComponent: undefined});
        }
    },

    bindEvent: function (el, eventName, eventHandler) {
        if (el.addEventListener){
            el.addEventListener(eventName, eventHandler, false);
        } else if (el.attachEvent){
            el.attachEvent('on' + eventName, eventHandler);
        }
    },

    handleKey: function(e) {
        if (e.which === 27 && this.state.dropdownComponent !== undefined) {
            e.preventDefault();
            this.handleDropdownChange(undefined);
        }
    },

    componentDidMount: function() {
        this.bindEvent(window, 'keydown', this.handleKey);
    },

    render: function() {
        console.log('render app');
        var content;
        var context = this.props.context;
        var hash = url.parse(this.props.href).hash || '';
        var name;
        var context_actions = [];
        if (hash.slice(0, 2) === '#!') {
            name = hash.slice(2);
        }
        // Switching between collections may leave component in place
        var key = context && context['@id'];
        if (context) {
            Array.prototype.push.apply(context_actions, context.actions || []);
            if (!name && context.default_page) {
                context = context.default_page;
                var actions = context.actions || [];
                for (var i = 0; i < actions.length; i++) {
                    var action = actions[i];
                    if (action.href[0] == '#') {
                        action.href = context['@id'] + action.href;
                    }
                    context_actions.push(action);
                }
            }

            var ContentView = globals.content_views.lookup(context, name);
            content = this.transferPropsTo(ContentView({
                context: context,
                loadingComplete: this.state.loadingComplete,
                session: this.state.session,
                portal: this.state.portal,
                navigate: this.navigate
            }));
        }
        var errors = this.state.errors.map(function (error) {
            return

;
        });

        var appClass = 'done';
        if (this.props.slow) {
            appClass = 'communicating';
        }

        var title = context.title || context.name || context.accession || context['@id'];
        if (title && title != 'Home') {
            title = title + ' – ' + portal.portal_title;
        } else {
            title = portal.portal_title;
        }

        var canonical = context.canonical_uri || this.props.href;

        return (

                    <meta charSet="utf-8" />
                    <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
                    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                    <title>{title}</title>
                    <link rel="canonical" href={canonical} />

                    <link rel="stylesheet" href="/static/css/style.css" />

                                <NavBar href={this.props.href} portal={this.state.portal}
                                        context_actions={context_actions}
                                        user_actions={this.state.user_actions} session={this.state.session}
                                        loadingComplete={this.state.loadingComplete} />

                                    {content}

                                {errors}

        );
    }

});

module.exports = App;
<|endoftext|>


<commit_before>var color = require('../config/color');

var bubbleLetterMap = new Map([
	['a', '\u24D0'], ['b', '\u24D1'], ['c', '\u24D2'], ['d', '\u24D3'], ['e', '\u24D4'], ['f', '\u24D5'], ['g', '\u24D6'], ['h', '\u24D7'], ['i', '\u24D8'], ['j', '\u24D9'], ['k', '\u24DA'], ['l', '\u24DB'], ['m', '\u24DC'],
	['n', '\u24DD'], ['o', '\u24DE'], ['p', '\u24DF'], ['q', '\u24E0'], ['r', '\u24E1'], ['s', '\u24E2'], ['t', '\u24E3'], ['u', '\u24E4'], ['v', '\u24E5'], ['w', '\u24E6'], ['x', '\u24E7'], ['y', '\u24E8'], ['z', '\u24E9'],
	['A', '\u24B6'], ['B', '\u24B7'], ['C', '\u24B8'], ['D', '\u24B9'], ['E', '\u24BA'], ['F', '\u24BB'], ['G', '\u24BC'], ['H', '\u24BD'], ['I', '\u24BE'], ['J', '\u24BF'], ['K', '\u24C0'], ['L', '\u24C1'], ['M', '\u24C2'],
	['N', '\u24C3'], ['O', '\u24C4'], ['P', '\u24C5'], ['Q', '\u24C6'], ['R', '\u24C7'], ['S', '\u24C8'], ['T', '\u24C9'], ['U', '\u24CA'], ['V', '\u24CB'], ['W', '\u24CC'], ['X', '\u24CD'], ['Y', '\u24CE'], ['Z', '\u24CF'],
	['1', '\u2460'], ['2', '\u2461'], ['3', '\u2462'], ['4', '\u2463'], ['5', '\u2464'], ['6', '\u2465'], ['7', '\u2466'], ['8', '\u2467'], ['9', '\u2468'], ['0', '\u24EA']
]);

var asciiMap = new Map([
	['\u24D0', 'a'], ['\u24D1', 'b'], ['\u24D2', 'c'], ['\u24D3', 'd'], ['\u24D4', 'e'], ['\u24D5', 'f'], ['\u24D6', 'g'], ['\u24D7', 'h'], ['\u24D8', 'i'], ['\u24D9', 'j'], ['\u24DA', 'k'], ['\u24DB', 'l'], ['\u24DC', 'm'],
	['\u24DD', 'n'], ['\u24DE', 'o'], ['\u24DF', 'p'], ['\u24E0', 'q'], ['\u24E1', 'r'], ['\u24E2', 's'], ['\u24E3', 't'], ['\u24E4', 'u'], ['\u24E5', 'v'], ['\u24E6', 'w'], ['\u24E7', 'x'], ['\u24E8', 'y'], ['\u24E9', 'z'],
	['\u24B6', 'A'], ['\u24B7', 'B'], ['\u24B8', 'C'], ['\u24B9', 'D'], ['\u24BA', 'E'], ['\u24BB', 'F'], ['\u24BC', 'G'], ['\u24BD', 'H'], ['\u24BE', 'I'], ['\u24BF', 'J'], ['\u24C0', 'K'], ['\u24C1', 'L'], ['\u24C2', 'M'],
	['\u24C3', 'N'], ['\u24C4', 'O'], ['\u24C5', 'P'], ['\u24C6', 'Q'], ['\u24C7', 'R'], ['\u24C8', 'S'], ['\u24C9', 'T'], ['\u24CA', 'U'], ['\u24CB', 'V'], ['\u24CC', 'W'], ['\u24CD', 'X'], ['\u24CE', 'Y'], ['\u24CF', 'Z'],
	['\u2460', '1'], ['\u2461', '2'], ['\u2462', '3'], ['\u2463', '4'], ['\u2464', '5'], ['\u2465', '6'], ['\u2466', '7'], ['\u2467', '8'], ['\u2468', '9'], ['\u24EA', '0']
]);

function parseStatus(text, encoding) {
	if (encoding) {
		text = text.split('').map(function (char) {
			return bubbleLetterMap.get(char);
		}).join('');
	} else {
		text = text.split('').map(function (char) {
			return asciiMap.get(char);
		}).join('');
	}
	return text;
}

exports.commands = {
	away: function (target, room, user) {
		if (!user.isAway && user.name.length > 15) return this.sendReply('Your username is too long for any kind of use of this command.');

		target = target ? target.replace(/[^a-zA-Z0-9]/g, '') : 'AWAY';
		var newName = user.name;
		var status = parseStatus(target, true);
		var statusLen = status.length;
		if (statusLen > 14) return this.sendReply('Your away status should be short and to-the-point, not a dissertation on why you are away.');

		if (user.isAway) {
			var statusIdx = newName.search(/\s\-\s[\u24B6-\u24E9\u2460-\u2468\u24EA]+$/);
			if (statusIdx > -1) newName = newName.substr(0, statusIdx);
			if (user.name.substr(-statusLen) === status) return this.sendReply('Your away status is already set to "' + target + '".');
		}

		newName += ' - ' + status;
		if (newName.length > 18) return this.sendReply('"' + target + '" is too long to use as your away status.');

		// forcerename any possible impersonators
		var targetUser = Users.getExact(user.userid + target);
		if (targetUser && targetUser !== user && targetUser.name === user.name + ' - ' + target) {
			targetUser.resetName();
			targetUser.send('|nametaken||Your name conflicts with ' + user.name + (user.name.substr(-1) === 's' ? '\'' : '\'s') + ' new away status.');
		}

		if (user.can('lock', null, room)) this.add('|raw|-- ' + Tools.escapeHTML(user.name) + ' is now ' + target.toLowerCase() + '.');
		user.forceRename(newName, user.registered);
		user.updateIdentity();
		user.isAway = true;
	},

	back: function (target, room, user) {
		if (!user.isAway) return this.sendReply('You are not set as away.');
		user.isAway = false;

		var newName = user.name;
		var statusIdx = newName.search(/\s\-\s[\u24B6-\u24E9\u2460-\u2468\u24EA]+$/);
		if (statusIdx < 0) {
			user.isAway = false;
			if (user.can('lock', null, room)) this.add('|raw|-- ' + Tools.escapeHTML(user.name) + ' is no longer away.');
			return false;
		}

		var status = parseStatus(newName.substr(statusIdx + 3), false);
		newName = newName.substr(0, statusIdx);
		user.forceRename(newName, user.registered);
		user.updateIdentity();
		user.isAway = false;
		if (user.can('lock', null, room)) this.add('|raw|-- ' + Tools.escapeHTML(newName) + ' is no longer ' + status.toLowerCase() + '.');
	},

	afk: function (target, room, user) {
		this.parse('/away AFK', room, user);
	},

	busy: function (target, room, user) {
		this.parse('/away BUSY', room, user);
	},

	work: function (target, room, user) {
		this.parse('/away WORK', room, user);
	},

	working: function (target, room, user) {
		this.parse('/away WORKING', room, user);
	},

	eating: function (target, room, user) {
		this.parse('/away EATING', room, user);
	},

	gaming: function (target, room, user) {
		this.parse('/away GAMING', room, user);
	},

	sleep: function (target, room, user) {
		this.parse('/away SLEEP', room, user);
	},

	sleeping: function (target, room, user) {
		this.parse('/away SLEEPING', room, user);
	},

	fap: function (target, room, user) {
		this.parse('/away FAP', room, user);
	},

	fapping: function (target, room, user) {
		this.parse('/away FAPPING', room, user);
	},

	nerd: function (target, room, user) {
		this.parse('/away NERD', room, user);
	},

	nerding: function (target, room, user) {
		this.parse('/away NERDING', room, user);
	},

	mimis: function (target, room, user) {
		this.parse('/away MIMIS', room, user);
	}
};
<commit_msg>Fix quotes to se double quotes for human readable text<commit_after>var color = require('../config/color');

var bubbleLetterMap = new Map([
	['a', '\u24D0'], ['b', '\u24D1'], ['c', '\u24D2'], ['d', '\u24D3'], ['e', '\u24D4'], ['f', '\u24D5'], ['g', '\u24D6'], ['h', '\u24D7'], ['i', '\u24D8'], ['j', '\u24D9'], ['k', '\u24DA'], ['l', '\u24DB'], ['m', '\u24DC'],
	['n', '\u24DD'], ['o', '\u24DE'], ['p', '\u24DF'], ['q', '\u24E0'], ['r', '\u24E1'], ['s', '\u24E2'], ['t', '\u24E3'], ['u', '\u24E4'], ['v', '\u24E5'], ['w', '\u24E6'], ['x', '\u24E7'], ['y', '\u24E8'], ['z', '\u24E9'],
	['A', '\u24B6'], ['B', '\u24B7'], ['C', '\u24B8'], ['D', '\u24B9'], ['E', '\u24BA'], ['F', '\u24BB'], ['G', '\u24BC'], ['H', '\u24BD'], ['I', '\u24BE'], ['J', '\u24BF'], ['K', '\u24C0'], ['L', '\u24C1'], ['M', '\u24C2'],
	['N', '\u24C3'], ['O', '\u24C4'], ['P', '\u24C5'], ['Q', '\u24C6'], ['R', '\u24C7'], ['S', '\u24C8'], ['T', '\u24C9'], ['U', '\u24CA'], ['V', '\u24CB'], ['W', '\u24CC'], ['X', '\u24CD'], ['Y', '\u24CE'], ['Z', '\u24CF'],
	['1', '\u2460'], ['2', '\u2461'], ['3', '\u2462'], ['4', '\u2463'], ['5', '\u2464'], ['6', '\u2465'], ['7', '\u2466'], ['8', '\u2467'], ['9', '\u2468'], ['0', '\u24EA']
]);

var asciiMap = new Map([
	['\u24D0', 'a'], ['\u24D1', 'b'], ['\u24D2', 'c'], ['\u24D3', 'd'], ['\u24D4', 'e'], ['\u24D5', 'f'], ['\u24D6', 'g'], ['\u24D7', 'h'], ['\u24D8', 'i'], ['\u24D9', 'j'], ['\u24DA', 'k'], ['\u24DB', 'l'], ['\u24DC', 'm'],
	['\u24DD', 'n'], ['\u24DE', 'o'], ['\u24DF', 'p'], ['\u24E0', 'q'], ['\u24E1', 'r'], ['\u24E2', 's'], ['\u24E3', 't'], ['\u24E4', 'u'], ['\u24E5', 'v'], ['\u24E6', 'w'], ['\u24E7', 'x'], ['\u24E8', 'y'], ['\u24E9', 'z'],
	['\u24B6', 'A'], ['\u24B7', 'B'], ['\u24B8', 'C'], ['\u24B9', 'D'], ['\u24BA', 'E'], ['\u24BB', 'F'], ['\u24BC', 'G'], ['\u24BD', 'H'], ['\u24BE', 'I'], ['\u24BF', 'J'], ['\u24C0', 'K'], ['\u24C1', 'L'], ['\u24C2', 'M'],
	['\u24C3', 'N'], ['\u24C4', 'O'], ['\u24C5', 'P'], ['\u24C6', 'Q'], ['\u24C7', 'R'], ['\u24C8', 'S'], ['\u24C9', 'T'], ['\u24CA', 'U'], ['\u24CB', 'V'], ['\u24CC', 'W'], ['\u24CD', 'X'], ['\u24CE', 'Y'], ['\u24CF', 'Z'],
	['\u2460', '1'], ['\u2461', '2'], ['\u2462', '3'], ['\u2463', '4'], ['\u2464', '5'], ['\u2465', '6'], ['\u2466', '7'], ['\u2467', '8'], ['\u2468', '9'], ['\u24EA', '0']
]);

function parseStatus(text, encoding) {
	if (encoding) {
		text = text.split('').map(function (char) {
			return bubbleLetterMap.get(char);
		}).join('');
	} else {
		text = text.split('').map(function (char) {
			return asciiMap.get(char);
		}).join('');
	}
	return text;
}

exports.commands = {
	away: function (target, room, user) {
		if (!user.isAway && user.name.length > 15) return this.sendReply("Your username is too long for any kind of use of this command.");

		target = target ? target.replace(/[^a-zA-Z0-9]/g, '') : 'AWAY';
		var newName = user.name;
		var status = parseStatus(target, true);
		var statusLen = status.length;
		if (statusLen > 14) return this.sendReply("Your away status should be short and to-the-point, not a dissertation on why you are away.");

		if (user.isAway) {
			var statusIdx = newName.search(/\s\-\s[\u24B6-\u24E9\u2460-\u2468\u24EA]+$/);
			if (statusIdx > -1) newName = newName.substr(0, statusIdx);
			if (user.name.substr(-statusLen) === status) return this.sendReply("Your away status is already set to \"" + target + "\".");
		}

		newName += ' - ' + status;
		if (newName.length > 18) return this.sendReply("\"" + target + "\" is too long to use as your away status.");

		// forcerename any possible impersonators
		var targetUser = Users.getExact(user.userid + target);
		if (targetUser && targetUser !== user && targetUser.name === user.name + ' - ' + target) {
			targetUser.resetName();
			targetUser.send("|nametaken||Your name conflicts with " + user.name + (user.name.substr(-1) === "s" ? "'" : "'s") + " new away status.");
		}

		if (user.can('lock', null, room)) this.add("|raw|-- " + Tools.escapeHTML(user.name) + " is now " + target.toLowerCase() + ".");
		user.forceRename(newName, user.registered);
		user.updateIdentity();
		user.isAway = true;
	},

	back: function (target, room, user) {
		if (!user.isAway) return this.sendReply("You are not set as away.");
		user.isAway = false;

		var newName = user.name;
		var statusIdx = newName.search(/\s\-\s[\u24B6-\u24E9\u2460-\u2468\u24EA]+$/);
		if (statusIdx < 0) {
			user.isAway = false;
			if (user.can('lock', null, room)) this.add("|raw|-- " + Tools.escapeHTML(user.name) + " is no longer away.");
			return false;
		}

		var status = parseStatus(newName.substr(statusIdx + 3), false);
		newName = newName.substr(0, statusIdx);
		user.forceRename(newName, user.registered);
		user.updateIdentity();
		user.isAway = false;
		if (user.can('lock', null, room)) this.add("|raw|-- " + Tools.escapeHTML(newName) + " is no longer " + status.toLowerCase() + ".");
	},

	afk: function (target, room, user) {
		this.parse('/away AFK', room, user);
	},

	busy: function (target, room, user) {
		this.parse('/away BUSY', room, user);
	},

	work: function (target, room, user) {
		this.parse('/away WORK', room, user);
	},

	working: function (target, room, user) {
		this.parse('/away WORKING', room, user);
	},

	eating: function (target, room, user) {
		this.parse('/away EATING', room, user);
	},

	gaming: function (target, room, user) {
		this.parse('/away GAMING', room, user);
	},

	sleep: function (target, room, user) {
		this.parse('/away SLEEP', room, user);
	},

	sleeping: function (target, room, user) {
		this.parse('/away SLEEPING', room, user);
	},

	fap: function (target, room, user) {
		this.parse('/away FAP', room, user);
	},

	fapping: function (target, room, user) {
		this.parse('/away FAPPING', room, user);
	},

	nerd: function (target, room, user) {
		this.parse('/away NERD', room, user);
	},

	nerding: function (target, room, user) {
		this.parse('/away NERDING', room, user);
	},

	mimis: function (target, room, user) {
		this.parse('/away MIMIS', room, user);
	}
};
<|endoftext|>


<commit_before>/*Dice Game plugin by SilverTactic (Silveee)*/

'use strict';

const INACTIVE_END_TIME = 1 * 60 * 1000; // 1 minute
//const TAX = 0.10; // 10%
const TAX = 0;

function diceImg(num) {
	switch (num) {
	case 0:
		return "http://i.imgur.com/nUbpLTD.png";
	case 1:
		return "http://i.imgur.com/BSt9nfV.png";
	case 2:
		return "http://i.imgur.com/eTQMVhY.png";
	case 3:
		return "http://i.imgur.com/3Y2hCAJ.png";
	case 4:
		return "http://i.imgur.com/KP3Za7O.png";
	case 5:
		return "http://i.imgur.com/lvi2ZZe.png";
	}
}

class Dice {
	constructor(room, amount, starter) {
		this.room = room;
		if (!this.room.diceCount) this.room.diceCount = 0;
		this.bet = amount;
		this.players = [];
		this.timer = setTimeout(() => {
			this.room.add('|uhtmlchange|' + this.room.diceCount + '|
(This game of dice has been ended due to inactivity.)
').update();
			delete this.room.dice;
		}, INACTIVE_END_TIME);

		let buck = (this.bet === 1 ? 'buck' : 'bucks');
		this.startMessage = '
' + Tools.escapeHTML(starter) + ' has started a game of dice for ' + amount + ' ' + buck + '!
' +
			'' +
			'
' +
			'<button name="send" value="/joindice">Click to join!</button>';
		this.room.add('|uhtml|' + (++this.room.diceCount) + '|' + this.startMessage + '
').update();
	}

	join(user, self) {
		if (this.players.length >= 2) return self.errorReply("Two users have already joined this game of dice.");
		Economy.readMoney(user.userid, money => {
			if (money < this.bet) return self.sendReply('You don\'t have enough money for this game of dice.');
			if (this.players.includes(user)) return self.sendReply('You have already joined this game of dice.');
			if (this.players.length && this.players[0].latestIp === user.latestIp) return self.errorReply("You have already joined this game of dice under the alt '" + this.players[0].name + "'.");
			this.players.push(user);
			this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + Wisp.nameColor(user.name) + ' has joined the game!
').update();
			if (this.players.length === 2) this.play();
		});
	}

	leave(user, self) {
		if (!this.players.includes(user)) return self.sendReply('You haven\'t joined the game of dice yet.');
		this.players.remove(user);
		this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '
');
	}

	play() {
		let p1 = this.players[0], p2 = this.players[1];
		Economy.readMoney(p1.userid, money1 => {
			Economy.readMoney(p2.userid, money2 => {
				if (money1 < this.bet || money2 < this.bet) {
					let user = (money1 < this.bet ? p1 : p2);
					let other = (user === p1 ? p2 : p1);
					user.sendTo(this.room, 'You have been removed from this game of dice, as you do not have enough money.');
					other.sendTo(this.room, user.name + ' has been removed from this game of dice, as they do not have enough money. Wait for another user to join.');
					this.players.remove(user);
					this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + this.players.map(user => Wisp.nameColor(user.name)) + ' has joined the game!').update();
					return;
				}
				let players = this.players.map(user => Wisp.nameColor(user.name)).join(' and ');
				this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + players + ' have joined the game!
').update();
				let roll1, roll2;
				do {
					roll1 = Math.floor(Math.random() * 6);
					roll2 = Math.floor(Math.random() * 6);
				} while (roll1 === roll2);
				if (roll2 > roll1) this.players.reverse();
				let winner = this.players[0], loser = this.players[1];

				let taxedAmt = Math.round(this.bet * TAX);
				setTimeout(() => {
					let buck = (this.bet === 1 ? 'buck' : 'bucks');
					this.room.add('|uhtmlchange|' + this.room.diceCount + '|
' + players + ' have joined the game!

' +
						'The game has been started! Rolling the dice...
' +
						'
' +
						Wisp.nameColor(p1.name, true) + ' rolled ' + (roll1 + 1) + '!
' +
						Wisp.nameColor(p2.name, true) + ' rolled ' + (roll2 + 1) + '!
' +
						Wisp.nameColor(winner.name, true) + ' has won ' + (this.bet - taxedAmt) + ' ' + buck + '!
' +
						'Better luck next time, ' + Tools.escapeHTML(loser.name) + '!'
					).update();
					Economy.writeMoney(winner.userid, (this.bet - taxedAmt), () => {
						Economy.writeMoney(loser.userid, -this.bet, () => {
							this.end();
						});
					});
				}, 800);
			});
		});
	}

	end(user) {
		if (user) this.room.add('|uhtmlchange|' + this.room.diceCount + '|
(This game of dice has been forcibly ended by ' + Tools.escapeHTML(user.name) + '.)
').update();
		clearTimeout(this.timer);
		delete this.room.dice;
	}
}

exports.commands = {
	startdice: 'dicegame',
	dicegame: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!user.can('broadcast', null, room) && room.id !== 'casino' && room.id !== 'coldfrontcasino') return this.errorReply("You must be ranked + or higher in this room to start a game of dice outside the Casino.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.errorReply("You cannot use this command while unable to talk.");
		if (room.dice) return this.errorReply("There is already a game of dice going on in this room.");

		let amount = Number(target) || 1;
		if (isNaN(target)) return this.errorReply('"' + target + '" isn\'t a valid number.');
		if (target.includes('.') || amount < 1 || amount > 5000) return this.sendReply('The number of bucks must be between 1 and 5,000 and cannot contain a decimal.');
		Economy.readMoney(user.userid, bucks => {
			if (bucks < amount) return this.sendReply("You don't have " + amount + " " + (amount === 1 ? "buck" : "bucks") + ".");
			room.dice = new Dice(room, amount, user.name);
			this.parse("/joindice");
		});
	},

	dicejoin: 'joindice',
	joindice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.sendReply("You cannot use this command while unable to talk.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.join(user, this);
	},

	diceleave: 'leavedice',
	leavedice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.leave(user, this);
	},

	diceend: 'enddice',
	enddice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!this.can('broadcast', null, room)) return this.errorReply("You must be ranked + or higher in this room to end a game of dice.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.sendReply("You cannot use this command while unable to talk.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.end(user);
	},
	dicegamehelp: [
		'/startdice or /dicegame [amount] - Starts a game of dice in the room for a given number of bucks, 1 by default (NOTE: There is a 10% tax on bucks you win from dice games).',
		'/joindice - Joins the game of dice. You cannot use this command if you don\'t have the number of bucks the game is for.',
		'/leavedice - Leaves the game of dice.',
		'/enddice - Ends the game of dice. Requires + or higher to use.',
	],
};
<commit_msg>Fix a crash in dice<commit_after>/*Dice Game plugin by SilverTactic (Silveee)*/

'use strict';

const INACTIVE_END_TIME = 1 * 60 * 1000; // 1 minute
//const TAX = 0.10; // 10%
const TAX = 0;

function diceImg(num) {
	switch (num) {
	case 0:
		return "http://i.imgur.com/nUbpLTD.png";
	case 1:
		return "http://i.imgur.com/BSt9nfV.png";
	case 2:
		return "http://i.imgur.com/eTQMVhY.png";
	case 3:
		return "http://i.imgur.com/3Y2hCAJ.png";
	case 4:
		return "http://i.imgur.com/KP3Za7O.png";
	case 5:
		return "http://i.imgur.com/lvi2ZZe.png";
	}
}

class Dice {
	constructor(room, amount, starter) {
		this.room = room;
		if (!this.room.diceCount) this.room.diceCount = 0;
		this.bet = amount;
		this.players = [];
		this.timer = setTimeout(() => {
			this.room.add('|uhtmlchange|' + this.room.diceCount + '|
(This game of dice has been ended due to inactivity.)
').update();
			delete this.room.dice;
		}, INACTIVE_END_TIME);

		let buck = (this.bet === 1 ? 'buck' : 'bucks');
		this.startMessage = '
' + Tools.escapeHTML(starter) + ' has started a game of dice for ' + amount + ' ' + buck + '!
' +
			'' +
			'
' +
			'<button name="send" value="/joindice">Click to join!</button>';
		this.room.add('|uhtml|' + (++this.room.diceCount) + '|' + this.startMessage + '
').update();
	}

	join(user, self) {
		if (this.players.length >= 2) return self.errorReply("Two users have already joined this game of dice.");
		Economy.readMoney(user.userid, money => {
			if (money < this.bet) return self.sendReply('You don\'t have enough money for this game of dice.');
			if (this.players.includes(user)) return self.sendReply('You have already joined this game of dice.');
			if (this.players.length && this.players[0].latestIp === user.latestIp) return self.errorReply("You have already joined this game of dice under the alt '" + this.players[0].name + "'.");
			this.players.push(user);
			this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + Wisp.nameColor(user.name) + ' has joined the game!
').update();
			if (this.players.length === 2) this.play();
		});
	}

	leave(user, self) {
		if (!this.players.includes(user)) return self.sendReply('You haven\'t joined the game of dice yet.');
		this.players.splice(this.players.indexOf(user), 1);
		this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '
');
	}

	play() {
		let p1 = this.players[0], p2 = this.players[1];
		Economy.readMoney(p1.userid, money1 => {
			Economy.readMoney(p2.userid, money2 => {
				if (money1 < this.bet || money2 < this.bet) {
					let user = (money1 < this.bet ? p1 : p2);
					let other = (user === p1 ? p2 : p1);
					user.sendTo(this.room, 'You have been removed from this game of dice, as you do not have enough money.');
					other.sendTo(this.room, user.name + ' has been removed from this game of dice, as they do not have enough money. Wait for another user to join.');
					this.players.splice(this.players.indexOf(user), 1);
					this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + this.players.map(user => Wisp.nameColor(user.name)) + ' has joined the game!').update();
					return;
				}
				let players = this.players.map(user => Wisp.nameColor(user.name)).join(' and ');
				this.room.add('|uhtmlchange|' + this.room.diceCount + '|' + this.startMessage + '' + players + ' have joined the game!
').update();
				let roll1, roll2;
				do {
					roll1 = Math.floor(Math.random() * 6);
					roll2 = Math.floor(Math.random() * 6);
				} while (roll1 === roll2);
				if (roll2 > roll1) this.players.reverse();
				let winner = this.players[0], loser = this.players[1];

				let taxedAmt = Math.round(this.bet * TAX);
				setTimeout(() => {
					let buck = (this.bet === 1 ? 'buck' : 'bucks');
					this.room.add('|uhtmlchange|' + this.room.diceCount + '|
' + players + ' have joined the game!

' +
						'The game has been started! Rolling the dice...
' +
						'
' +
						Wisp.nameColor(p1.name, true) + ' rolled ' + (roll1 + 1) + '!
' +
						Wisp.nameColor(p2.name, true) + ' rolled ' + (roll2 + 1) + '!
' +
						Wisp.nameColor(winner.name, true) + ' has won ' + (this.bet - taxedAmt) + ' ' + buck + '!
' +
						'Better luck next time, ' + Tools.escapeHTML(loser.name) + '!'
					).update();
					Economy.writeMoney(winner.userid, (this.bet - taxedAmt), () => {
						Economy.writeMoney(loser.userid, -this.bet, () => {
							this.end();
						});
					});
				}, 800);
			});
		});
	}

	end(user) {
		if (user) this.room.add('|uhtmlchange|' + this.room.diceCount + '|
(This game of dice has been forcibly ended by ' + Tools.escapeHTML(user.name) + '.)
').update();
		clearTimeout(this.timer);
		delete this.room.dice;
	}
}

exports.commands = {
	startdice: 'dicegame',
	dicegame: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!user.can('broadcast', null, room) && room.id !== 'casino' && room.id !== 'coldfrontcasino') return this.errorReply("You must be ranked + or higher in this room to start a game of dice outside the Casino.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.errorReply("You cannot use this command while unable to talk.");
		if (room.dice) return this.errorReply("There is already a game of dice going on in this room.");

		let amount = Number(target) || 1;
		if (isNaN(target)) return this.errorReply('"' + target + '" isn\'t a valid number.');
		if (target.includes('.') || amount < 1 || amount > 5000) return this.sendReply('The number of bucks must be between 1 and 5,000 and cannot contain a decimal.');
		Economy.readMoney(user.userid, bucks => {
			if (bucks < amount) return this.sendReply("You don't have " + amount + " " + (amount === 1 ? "buck" : "bucks") + ".");
			room.dice = new Dice(room, amount, user.name);
			this.parse("/joindice");
		});
	},

	dicejoin: 'joindice',
	joindice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.sendReply("You cannot use this command while unable to talk.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.join(user, this);
	},

	diceleave: 'leavedice',
	leavedice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.leave(user, this);
	},

	diceend: 'enddice',
	enddice: function (target, room, user) {
		if (room.id === 'lobby') return this.errorReply("This command cannot be used in the Lobby.");
		if (!this.can('broadcast', null, room)) return this.errorReply("You must be ranked + or higher in this room to end a game of dice.");
		if ((user.locked || room.isMuted(user)) && !user.can('bypassall')) return this.sendReply("You cannot use this command while unable to talk.");
		if (!room.dice) return this.errorReply('There is no game of dice going on in this room.');

		room.dice.end(user);
	},
	dicegamehelp: [
		'/startdice or /dicegame [amount] - Starts a game of dice in the room for a given number of bucks, 1 by default (NOTE: There is a 10% tax on bucks you win from dice games).',
		'/joindice - Joins the game of dice. You cannot use this command if you don\'t have the number of bucks the game is for.',
		'/leavedice - Leaves the game of dice.',
		'/enddice - Ends the game of dice. Requires + or higher to use.',
	],
};
<|endoftext|>


<commit_before>const Command = require("../base/Command");

/**
 * The list of acronyms defined in data/acronym.json was transposed from the SWGoH forum. Any update there will need to make it's way into here.
 * //https://forums.galaxy-of-heroes.starwars.ea.com/discussion/154048/guide-to-the-acronyms-and-terms-of-star-wars-galaxy-of-heroes-swgoh
 */
class Acronyms extends Command {
    constructor(client) {
        super(client, {
            name: "acronyms",
            category: "Misc",
            aliases: ["acr", "acronym"],
        });
    }

    async run(client, message, [ ...acronym ], options) { // eslint-disable-line no-unused-vars
        const acronymsLookup = client.acronyms;
        const acronyms = Object.keys(acronymsLookup);

        if (!acronym.length) {
            return message.channel.send(message.language.get("COMMAND_ACRONYMS_INVALID");
        }

        const lookupList = acronym.map(a => a.trim().toLowerCase());
        const matchingItems = acronyms.filter(acr => lookupList.includes(acr.toLowerCase()));

        if (!matchingItems.length) {
            return message.channel.send(message.language.get("COMMAND_ACRONYMS_NOT_FOUND"));
        }

        let acronymMeaningMessage = "";
        for (let i = 0; i < matchingItems.length; i++) {
            if (acronymMeaningMessage !== "") {
                acronymMeaningMessage += "\n";
            }
            /*
             * TODO
             * This next line won't translate well, as is. BUT we could move this to
             * const acronymMeaning = message.language.get("COMMAND_ACRONYM_" + matchingItems[i]);
             * acronymMeaningMessage += `**${matchingItems[i]}**: ${acronymMeaning}`;
             */
            acronymMeaningMessage += `**${matchingItems[i]}**: ${acronymsLookup[matchingItems[i]]}`;
        }

        return message.channel.send(acronymMeaningMessage);
    }
}

module.exports = Acronyms;

<commit_msg>Whoops<commit_after>const Command = require("../base/Command");

/**
 * The list of acronyms defined in data/acronym.json was transposed from the SWGoH forum. Any update there will need to make it's way into here.
 * //https://forums.galaxy-of-heroes.starwars.ea.com/discussion/154048/guide-to-the-acronyms-and-terms-of-star-wars-galaxy-of-heroes-swgoh
 */
class Acronyms extends Command {
    constructor(client) {
        super(client, {
            name: "acronyms",
            category: "Misc",
            aliases: ["acr", "acronym"],
        });
    }

    async run(client, message, [ ...acronym ], options) { // eslint-disable-line no-unused-vars
        const acronymsLookup = client.acronyms;
        const acronyms = Object.keys(acronymsLookup);

        if (!acronym.length) {
            return message.channel.send(message.language.get("COMMAND_ACRONYMS_INVALID"));
        }

        const lookupList = acronym.map(a => a.trim().toLowerCase());
        const matchingItems = acronyms.filter(acr => lookupList.includes(acr.toLowerCase()));

        if (!matchingItems.length) {
            return message.channel.send(message.language.get("COMMAND_ACRONYMS_NOT_FOUND"));
        }

        let acronymMeaningMessage = "";
        for (let i = 0; i < matchingItems.length; i++) {
            if (acronymMeaningMessage !== "") {
                acronymMeaningMessage += "\n";
            }
            /*
             * TODO
             * This next line won't translate well, as is. BUT we could move this to
             * const acronymMeaning = message.language.get("COMMAND_ACRONYM_" + matchingItems[i]);
             * acronymMeaningMessage += `**${matchingItems[i]}**: ${acronymMeaning}`;
             */
            acronymMeaningMessage += `**${matchingItems[i]}**: ${acronymsLookup[matchingItems[i]]}`;
        }

        return message.channel.send(acronymMeaningMessage);
    }
}

module.exports = Acronyms;

<|endoftext|>


<commit_before>const config = require('../userconfig/config.json'); // Import configuration
const fs = require('fs'); // For custom emotes
const Discord = require('discord.js'); // For defining the embed
const moment = require('moment'); // For embed timestamp
const quotes = require('../userconfig/saved_quotes.json'); // Load saved quotes object

exports.main = function(selfbot, msg, msgArray) { // Export command function
    var command = "addQuote";
    if(msg.content == config.commandPrefix + command.toLowerCase()) {
    // If no arguments were specified...
        msg.edit('Specify a username and snippet!').then(msg => msg.delete(2000));
        // ...tell the user to do so and set auto-delete to 2s.
        return; // Abort command execution
    };
    var quoteName;
    // Define quote name placeholder
    var user;
    // Define user placeholder
    if(msgArray[1].startsWith('"')) {
    // If the quote name is a multi-word name...
        quoteName = msg.content.substring(msg.content.indexOf('"')+1, msg.content.lastIndexOf('"')).replace(/ /g,"_");
        // ...assign the quote name value to the cut-out "" part and replace all spaces with underscores...
        user = emoteURL = msg.content.substring(msg.content.lastIndexOf('"')+2, msg.content.indexOf(" ", msg.content.lastIndexOf('"')+2));
        // ...and assign the user value out of the message content beyond the quote name.
    }
    else {
    // If the quote name is a single-word name...
        quoteName = msgArray[1];
        // ...assign the quote name value out of the array...
        user = msgArray[2];
        // ...and assign the user out out the array.
    }
    var snippet = msg.content.substring(config.commandPrefix.length + command.length + quoteName.length + user.length + 3);
    // Define quote snippet out of message content
    var isDM = false;
    // Define the "isDM" indicator bool, default to false
    var users;
    // Define the users placeholder for gathering messages later on
    var embed = new Discord.RichEmbed();
     // Define the embed as new RichEmbed
    if(msg.channel.type == "text") {
    // 1) If the command is called from a server's channel...
        users = msg.guild.members.array();
        //...get all members of the server to match the ID below.
    }
    else if(msg.channel.type == "dm") {
    // 2) If the command is called in a DM channel...
        isDM = true;
        // ...switch "isDM" indicator bool to true...
        user = msg.channel.recipient.id;
        // ...and define user as the recipient's ID.
    }
    else {
    // If the command is called in neither a server's channel nor pm...
        msg.edit("Quote only supported on Servers or DMs, sorry.").then(msg => msg.delete(2000));
        // ...notify user and set auto-delete to 2s.
        return; // Abort command execution
    };
    if(!isDM) {
    // If the channel is not a DM channel...
        for(var i=0; i<users.length; i++) {
        // ...loop through server users.
            if(users[i].displayName.startsWith(user) || users[i].user.username.startsWith(user)) {
            // If the displayName or username of current user in iteration matches the username of the user to quote...
                user = users[i].id;
                // ...redefine the user argument as the user ID of the current user in iteration.
            };
        };
    };
    msg.channel.fetchMessages({limit: 100}).then((messages) => {
    // Get last 100 messages
        msg.delete();
        // Delete the command call
        messages = messages.array();
        // Convert messages collection to array
        for(var j=1; j<messages.length; j++) {
        // Loop through the fetched messages
            if(messages[j].author.id == user && messages[j].content.includes(snippet)) {
            // If the message is by the specified user and contains the snippet...
                if(!isDM) {
                // ...1) and if the channel is not a DM channel...
                    embed.setColor(5267072)
                         .setAuthor(`${msg.guild.member(user).displayName} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, msg.guild.member(user).user.avatarURL)
                         .setDescription(messages[j].content);
                    // ...set the embed properties.
                    quotes[quoteName] = {"author": `${msg.guild.member(user).displayName} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, "content": messages[j].content, "avatar": msg.guild.member(user).user.avatarURL};
                    // Save the quote to the quotes list...
                    fs.writeFileSync(`userconfig/saved_quotes.json`, JSON.stringify(quotes));
                    // ...and save the list to the file.
                    msg.channel.sendEmbed(embed, `**__The following quote was successfully saved under the '${quoteName}' name:__**`).then(msg => {msg.delete(2000)});
                    // Send confirmation message and set auto-delete to 2s
                    return; // Abort command execution
                };
                // ...2) and the channel is a DM channel...
                embed.setColor(5267072)
                     .setAuthor(`${msg.channel.recipient.username} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, msg.channel.recipient.avatarURL)
                     .setDescription(messages[j].content);
                // ...set the embed properties.
                quotes[quoteName] = {"author": `${msg.channel.recipient.username} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, "content": messages[j].content, "avatar": msg.channel.recipient.avatarURL};
                // Save the quote to the quotes list...
                fs.writeFileSync(`userconfig/saved_quotes.json`, JSON.stringify(quotes));
                // ...and save the list to the file.
                msg.channel.sendEmbed(embed, `**__The following quote was successfully saved under the '${quoteName}' name:__**`).then(msg => {msg.delete(2000)});
                // Send confirmation message and set auto-delete to 2s
                return; // Abort command execution
            };
        };
    })
};

exports.desc = "Save a quote from within the last 100 overall messages"; // Export command description
exports.syntax = "<quoteName> <username> <message snippet>"; // Export command syntax<commit_msg>Fix stupid copy-and-paste error<commit_after>const config = require('../userconfig/config.json'); // Import configuration
const fs = require('fs'); // For custom emotes
const Discord = require('discord.js'); // For defining the embed
const moment = require('moment'); // For embed timestamp
const quotes = require('../userconfig/saved_quotes.json'); // Load saved quotes object

exports.main = function(selfbot, msg, msgArray) { // Export command function
    var command = "addQuote";
    if(msg.content == config.commandPrefix + command.toLowerCase()) {
    // If no arguments were specified...
        msg.edit('Specify a username and snippet!').then(msg => msg.delete(2000));
        // ...tell the user to do so and set auto-delete to 2s.
        return; // Abort command execution
    };
    var quoteName;
    // Define quote name placeholder
    var user;
    // Define user placeholder
    if(msgArray[1].startsWith('"')) {
    // If the quote name is a multi-word name...
        quoteName = msg.content.substring(msg.content.indexOf('"')+1, msg.content.lastIndexOf('"')).replace(/ /g,"_");
        // ...assign the quote name value to the cut-out "" part and replace all spaces with underscores...
        user = msg.content.substring(msg.content.lastIndexOf('"')+2, msg.content.indexOf(" ", msg.content.lastIndexOf('"')+2));
        // ...and assign the user value out of the message content beyond the quote name.
    }
    else {
    // If the quote name is a single-word name...
        quoteName = msgArray[1];
        // ...assign the quote name value out of the array...
        user = msgArray[2];
        // ...and assign the user out out the array.
    }
    var snippet = msg.content.substring(config.commandPrefix.length + command.length + quoteName.length + user.length + 3);
    // Define quote snippet out of message content
    var isDM = false;
    // Define the "isDM" indicator bool, default to false
    var users;
    // Define the users placeholder for gathering messages later on
    var embed = new Discord.RichEmbed();
     // Define the embed as new RichEmbed
    if(msg.channel.type == "text") {
    // 1) If the command is called from a server's channel...
        users = msg.guild.members.array();
        //...get all members of the server to match the ID below.
    }
    else if(msg.channel.type == "dm") {
    // 2) If the command is called in a DM channel...
        isDM = true;
        // ...switch "isDM" indicator bool to true...
        user = msg.channel.recipient.id;
        // ...and define user as the recipient's ID.
    }
    else {
    // If the command is called in neither a server's channel nor pm...
        msg.edit("Quote only supported on Servers or DMs, sorry.").then(msg => msg.delete(2000));
        // ...notify user and set auto-delete to 2s.
        return; // Abort command execution
    };
    if(!isDM) {
    // If the channel is not a DM channel...
        for(var i=0; i<users.length; i++) {
        // ...loop through server users.
            if(users[i].displayName.startsWith(user) || users[i].user.username.startsWith(user)) {
            // If the displayName or username of current user in iteration matches the username of the user to quote...
                user = users[i].id;
                // ...redefine the user argument as the user ID of the current user in iteration.
            };
        };
    };
    msg.channel.fetchMessages({limit: 100}).then((messages) => {
    // Get last 100 messages
        msg.delete();
        // Delete the command call
        messages = messages.array();
        // Convert messages collection to array
        for(var j=1; j<messages.length; j++) {
        // Loop through the fetched messages
            if(messages[j].author.id == user && messages[j].content.includes(snippet)) {
            // If the message is by the specified user and contains the snippet...
                if(!isDM) {
                // ...1) and if the channel is not a DM channel...
                    embed.setColor(5267072)
                         .setAuthor(`${msg.guild.member(user).displayName} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, msg.guild.member(user).user.avatarURL)
                         .setDescription(messages[j].content);
                    // ...set the embed properties.
                    quotes[quoteName] = {"author": `${msg.guild.member(user).displayName} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, "content": messages[j].content, "avatar": msg.guild.member(user).user.avatarURL};
                    // Save the quote to the quotes list...
                    fs.writeFileSync(`userconfig/saved_quotes.json`, JSON.stringify(quotes));
                    // ...and save the list to the file.
                    msg.channel.sendEmbed(embed, `**__The following quote was successfully saved under the '${quoteName}' name:__**`).then(msg => {msg.delete(2000)});
                    // Send confirmation message and set auto-delete to 2s
                    return; // Abort command execution
                };
                // ...2) and the channel is a DM channel...
                embed.setColor(5267072)
                     .setAuthor(`${msg.channel.recipient.username} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, msg.channel.recipient.avatarURL)
                     .setDescription(messages[j].content);
                // ...set the embed properties.
                quotes[quoteName] = {"author": `${msg.channel.recipient.username} wrote on the ${moment(messages[j].createdTimestamp).format('Do MMM YYYY')} at ${moment(messages[j].createdTimestamp).format('HH:mm:ss')}:`, "content": messages[j].content, "avatar": msg.channel.recipient.avatarURL};
                // Save the quote to the quotes list...
                fs.writeFileSync(`userconfig/saved_quotes.json`, JSON.stringify(quotes));
                // ...and save the list to the file.
                msg.channel.sendEmbed(embed, `**__The following quote was successfully saved under the '${quoteName}' name:__**`).then(msg => {msg.delete(2000)});
                // Send confirmation message and set auto-delete to 2s
                return; // Abort command execution
            };
        };
    })
};

exports.desc = "Save a quote from within the last 100 overall messages"; // Export command description
exports.syntax = "<quoteName> <username> <message snippet>"; // Export command syntax<|endoftext|>


<commit_before>// module.exports = function getDefaultTextForLanguage(language) {
export function getDefaultTextForLanguage(language) {
  switch (language) {
    case 'javascript':
      return javascriptDefaultText;
    case 'js':
      return javascriptDefaultText;
    case 'css':
      return cssDefaultText;
    case 'html':
      return htmlDefaultText;
    default:
      return htmlDefaultText;
  }
// };
}

const javascriptDefaultText =
  `function helloWorld(){
    console.log('hello world!');
  }
  helloWorld();
 `
;

const htmlDefaultText = `<!DOCTYPE html>

`;

const cssDefaultText =
  `html, body{
   height: 100%;
  }
  `;
<commit_msg>replace js example with a React one<commit_after>// module.exports = function getDefaultTextForLanguage(language) {
export function getDefaultTextForLanguage(language) {
    switch (language) {
        case 'javascript':
            return javascriptDefaultText;
        case 'js':
            return javascriptDefaultText;
        case 'css':
            return cssDefaultText;
        case 'html':
            return htmlDefaultText;
        default:
            return htmlDefaultText;
    }
// };
}

const javascriptDefaultText =
    `const X = (props)=>
{props.val}<button onClick={props.onClick}>click here</button>
;
const onClick= e=>{console.log('click')};
ReactDOM.render(<X val="hi there!" onClick={onClick} />, document.querySelector("#root"));
 `
;

const htmlDefaultText = `<!DOCTYPE html>

<!DOCTYPE html>

`;

const cssDefaultText =
    `html, body{
   height: 100%;
  }
  span {
    color: blue;
  }
  `;
<|endoftext|>


<commit_before>"use strict";

const yaml = require($SRC + "yaml");
const path = require("path");
const fs = require("fs-promise");
const os = require("os");

const aliasManager = require("../../hosts_manager");

const Command = require('../../system/system_command');
const ContainerBase = require('../container_base');
const Template = require('../../template');

const DOCKER_FILES_DIRNAME = ".docker-files";

/**
 * Container handler for Docker.
 *
 * @id docker
 * @filename docker-compose.yml
 */
class DockerContainer extends ContainerBase {

  /**
   * @inheritdoc
   */
  getIp(serviceOrGroupName = "") {
    // Generate the container name for the service or the first from group.
    if (serviceOrGroupName === "") {
      this.env.services.each((service) => {
        serviceOrGroupName += `${this.env.config.env_name}_${service.ann("id")}_1 `;
      });
    }
    else {
      if (!this.env.services.has(serviceOrGroupName)) {
        let group = this.env.services.ofGroup(serviceOrGroupName);

        if (group === false) {
          throw new Error("No services found in the group: " + serviceOrGroupName);
        }

        serviceOrGroupName = group[Object.keys(group)[0]].ann("id");
      }

      serviceOrGroupName = `${this.env.config.env_name}_${serviceOrGroupName}_1`;
    }

    let cmd = new Command("docker", [
      "inspect",
      ["-f", '"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"'],
      serviceOrGroupName,
    ]);

    return cmd.execute().then((output) => {
      if (output.length < 5) {
        throw new Error("IPs could not be determined. Does the service exist and is the container started?\nCommand: " + cmd);
      }

      let ips = output.split("\n");
      ips.pop();

      if (ips.length == 1) {
        return ips[0];
      }

      let serviceIps = {};
      this.env.services.each((service) => {
        serviceIps[service.ann("id")] = ips.shift();
      });

      return serviceIps;
    });
  }

  /**
   * @inheritdoc
   */
  start() {
    this.directoryToPath();

    return new Command("docker-compose", [
      ["-p", this.env.config.env_name],
      ["up", "-d"],
    ]).execute().catch((error) => {
      throw new Error("Failed to start environment container:\n" + error);
    }).then(() => {
      // This provides workaround for windows. By default on linux container
      // IPs get exposed to hosts. On windows tough docker creates a Hyper-V
      // VM in which it puts the containers, and this VM is private. This is
      // the way to route those IPs to host.
      if (os.platform() === "win32") {
        return this.getIp().then((ips) => {
            return ips[Object.keys(ips)[0]].replace(/(\d+.\d+.)\d+.\d+/, "$10.0");
          })
        // Initially this first command was enough to make it work, but in the
        // newer version docker changed things.
          .then((ip) => new Command("route", [
              ["add", ip],
              ["mask", "255.255.0.0"],
              ["10.0.75.2"] // @ Hyper-V default IP
            ]).execute()
          )
        // The new additional command needs to be run to make sure the upper
        // one actually works.
          .then(() => new Command("docker", [
              "run", "--rm", "-t", "--privileged",
              "--network=none", "--pid=host",
              "justincormack/nsenter1",
              "bin/sh", "-c", "\"iptables -A FORWARD -j ACCEPT\""
            ]).execute()
          ).catch((err) => {
            throw Error("Failed to expose container IPs to hosts on windows.\n" + err);
          });
      }
    }).then(() => {
      return this.getIp();
    }).then((serviceIps) => {
      let aliases = [];
      // Get the aliases of the services that should be exposed.
      this.env.services.each((service, id) => {
        if (service.ann("aliased")) {
          aliases.push({
            ip: serviceIps[id],
            domain: service.getDomainAlias(),
          });
        }
      });

      // Add aliases to the hosts file.
      return aliasManager.addHosts(aliases).catch((err) => {
        console.warn("Adding host aliases for the service IPs requires admin privileges.");
        console.error(err);
      });
    }).then(() => {return this;});
  }

  /**
   * @inheritDoc
   */
  isStarted() {
    return this.getIp()
      // If we get the IPs we have running containers.
      .then(() => true)
      // If it throws then it couldn't get the IPs because containers are
      // not started.
      .catch(() => false);
  }

  /**
   * @inheritdoc
   */
  stop() {
    this.directoryToPath();

    return new Command("docker-compose", [
      ["-p", this.env.config.env_name],
      "stop"
    ]).execute()
      .then(() => {return this;})
      .catch((error) => {
        throw new Error("Failed to stop environment container:\n" + error);
      });
  }

  /**
   * @inheritdoc
   */
  command(command, execOptions = ["exec"], execInService = "web") {
    this.directoryToPath();

    if (execInService == "web") {
      execInService = this.services.ofGroup("web")[0];
    }

    let cmd = new Command("docker-compose", [
      execOptions, execInService, command,
    ]).inheritStdio();

    return cmd.execute().then(() => this).catch((error) => {
      throw new Error(`Failed to run docker command:\n${cmd.toString()}:\n${error}`);
    });
  }

  /**
   * @inheritdoc
   */
  compose() {
    let composition = {
      version: "2",
      services: {}
    };

    this.env.services.each((Service, id) => {
      composition.services[id] = Service.compose(this.ann("id"));
    });

    // Allow services to post react to composition.
    this.env._fireEvent("composedDocker", composition.services);

    return composition;
  }

  /**
   * @inheritdoc
   */
  writeComposition() {
    return new Promise((resolve, reject) => {
      let composition = this.compose();
      let promises = [];

      // Services may provide custom Docker files that are templates. Compile
      // and save these first.
      for (let [serviceId, compost] of Object.entries(composition.services)) {
        if (compost.hasOwnProperty("build")) {
          promises.push(this._compileDockerfile(serviceId, compost.build));
          compost.build = "./" + DOCKER_FILES_DIRNAME + "/" + serviceId;
        }
      }

      Promise.all(promises)
        .then(() => resolve(composition))
        .catch((err) => reject(err));
    }).then((compost) => {
      return yaml.write(path.join(this.path, this.ann("filename")), compost);
    });
  }

  /**
   * Compiles a docker file template.
   *
   * @param {string} serviceId
   *    Service ID.
   * @param args
   *    Data to send to template engine.
   *
   * @returns {Promise}
   * @private
   */
  _compileDockerfile(serviceId, args) {
    const templatePath = path.join(__dirname, "..", "services", serviceId, "Dockerfile.dot");
    const destPath = path.join(this.path, DOCKER_FILES_DIRNAME, serviceId);

    return fs.ensureDir(destPath)
      .then(() => {
        return Template.from(templatePath).compile(args, destPath);
      })
      .catch((err) => {
        throw new Error(`Failed writing Dockerfile for '${serviceId}' service:\n` + err);
      });
  }

  /**
   * @inheritdoc
   */
  remove() {
    this.directoryToPath();

    let cmd = new Command("docker-compose", [
      "rm", "-vf",
    ]).inheritStdio();

    return this.stop().then(() => {
        return cmd.execute();
      })
      .then(() => {return this;})
      .catch((error) => {
      throw new Error(`Failed to run docker command:\n${cmd.toString()}:\n${error}`);
    });
  }

}

module.exports = DockerContainer;
<commit_msg>Fixes docker commands not specifying env name. See #87.<commit_after>"use strict";

const yaml = require($SRC + "yaml");
const path = require("path");
const fs = require("fs-promise");
const os = require("os");

const aliasManager = require("../../hosts_manager");

const Command = require('../../system/system_command');
const ContainerBase = require('../container_base');
const Template = require('../../template');

const DOCKER_FILES_DIRNAME = ".docker-files";

/**
 * Container handler for Docker.
 *
 * @id docker
 * @filename docker-compose.yml
 */
class DockerContainer extends ContainerBase {

  /**
   * @inheritdoc
   */
  getIp(serviceOrGroupName = "") {
    // Generate the container name for the service or the first from group.
    if (serviceOrGroupName === "") {
      this.env.services.each((service) => {
        serviceOrGroupName += `${this.env.config.env_name}_${service.ann("id")}_1 `;
      });
    }
    else {
      if (!this.env.services.has(serviceOrGroupName)) {
        let group = this.env.services.ofGroup(serviceOrGroupName);

        if (group === false) {
          throw new Error("No services found in the group: " + serviceOrGroupName);
        }

        serviceOrGroupName = group[Object.keys(group)[0]].ann("id");
      }

      serviceOrGroupName = `${this.env.config.env_name}_${serviceOrGroupName}_1`;
    }

    let cmd = new Command("docker", [
      "inspect",
      ["-f", '"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"'],
      serviceOrGroupName,
    ]);

    return cmd.execute().then((output) => {
      if (output.length < 5) {
        throw new Error("IPs could not be determined. Does the service exist and is the container started?\nCommand: " + cmd);
      }

      let ips = output.split("\n");
      ips.pop();

      if (ips.length == 1) {
        return ips[0];
      }

      let serviceIps = {};
      this.env.services.each((service) => {
        serviceIps[service.ann("id")] = ips.shift();
      });

      return serviceIps;
    });
  }

  /**
   * @inheritdoc
   */
  start() {
    this.directoryToPath();

    return new Command("docker-compose", [
      ["-p", this.env.config.env_name],
      ["up", "-d"],
    ]).execute().catch((error) => {
      throw new Error("Failed to start environment container:\n" + error);
    }).then(() => {
      // This provides workaround for windows. By default on linux container
      // IPs get exposed to hosts. On windows tough docker creates a Hyper-V
      // VM in which it puts the containers, and this VM is private. This is
      // the way to route those IPs to host.
      if (os.platform() === "win32") {
        return this.getIp().then((ips) => {
            return ips[Object.keys(ips)[0]].replace(/(\d+.\d+.)\d+.\d+/, "$10.0");
          })
        // Initially this first command was enough to make it work, but in the
        // newer version docker changed things.
          .then((ip) => new Command("route", [
              ["add", ip],
              ["mask", "255.255.0.0"],
              ["10.0.75.2"] // @ Hyper-V default IP
            ]).execute()
          )
        // The new additional command needs to be run to make sure the upper
        // one actually works.
          .then(() => new Command("docker", [
              "run", "--rm", "-t", "--privileged",
              "--network=none", "--pid=host",
              "justincormack/nsenter1",
              "bin/sh", "-c", "\"iptables -A FORWARD -j ACCEPT\""
            ]).execute()
          ).catch((err) => {
            throw Error("Failed to expose container IPs to hosts on windows.\n" + err);
          });
      }
    }).then(() => {
      return this.getIp();
    }).then((serviceIps) => {
      let aliases = [];
      // Get the aliases of the services that should be exposed.
      this.env.services.each((service, id) => {
        if (service.ann("aliased")) {
          aliases.push({
            ip: serviceIps[id],
            domain: service.getDomainAlias(),
          });
        }
      });

      // Add aliases to the hosts file.
      return aliasManager.addHosts(aliases).catch((err) => {
        console.warn("Adding host aliases for the service IPs requires admin privileges.");
        console.error(err);
      });
    }).then(() => {return this;});
  }

  /**
   * @inheritDoc
   */
  isStarted() {
    return this.getIp()
      // If we get the IPs we have running containers.
      .then(() => true)
      // If it throws then it couldn't get the IPs because containers are
      // not started.
      .catch(() => false);
  }

  /**
   * @inheritdoc
   */
  stop() {
    this.directoryToPath();

    return new Command("docker-compose", [
      ["-p", this.env.config.env_name],
      "stop"
    ]).execute()
      .then(() => {return this;})
      .catch((error) => {
        throw new Error("Failed to stop environment container:\n" + error);
      });
  }

  /**
   * @inheritdoc
   */
  command(command, execOptions = ["exec"], execInService = "web") {
    this.directoryToPath();

    if (execInService == "web") {
      execInService = this.services.ofGroup("web")[0];
    }

    // Make sure the right project name is used with compose
    // as otherwise it will use the directory name which can
    // be customized by the user.
    execOptions.push('--name', this.env.config.env_name);

    let cmd = new Command("docker-compose", [
      execOptions, execInService, command,
    ]).inheritStdio();

    return cmd.execute().then(() => this).catch((error) => {
      throw new Error(`Failed to run docker command:\n${cmd.toString()}:\n${error}`);
    });
  }

  /**
   * @inheritdoc
   */
  compose() {
    let composition = {
      version: "2",
      services: {}
    };

    this.env.services.each((Service, id) => {
      composition.services[id] = Service.compose(this.ann("id"));
    });

    // Allow services to post react to composition.
    this.env._fireEvent("composedDocker", composition.services);

    return composition;
  }

  /**
   * @inheritdoc
   */
  writeComposition() {
    return new Promise((resolve, reject) => {
      let composition = this.compose();
      let promises = [];

      // Services may provide custom Docker files that are templates. Compile
      // and save these first.
      for (let [serviceId, compost] of Object.entries(composition.services)) {
        if (compost.hasOwnProperty("build")) {
          promises.push(this._compileDockerfile(serviceId, compost.build));
          compost.build = "./" + DOCKER_FILES_DIRNAME + "/" + serviceId;
        }
      }

      Promise.all(promises)
        .then(() => resolve(composition))
        .catch((err) => reject(err));
    }).then((compost) => {
      return yaml.write(path.join(this.path, this.ann("filename")), compost);
    });
  }

  /**
   * Compiles a docker file template.
   *
   * @param {string} serviceId
   *    Service ID.
   * @param args
   *    Data to send to template engine.
   *
   * @returns {Promise}
   * @private
   */
  _compileDockerfile(serviceId, args) {
    const templatePath = path.join(__dirname, "..", "services", serviceId, "Dockerfile.dot");
    const destPath = path.join(this.path, DOCKER_FILES_DIRNAME, serviceId);

    return fs.ensureDir(destPath)
      .then(() => {
        return Template.from(templatePath).compile(args, destPath);
      })
      .catch((err) => {
        throw new Error(`Failed writing Dockerfile for '${serviceId}' service:\n` + err);
      });
  }

  /**
   * @inheritdoc
   */
  remove() {
    this.directoryToPath();

    let cmd = new Command("docker-compose", [
      "rm", "-vf",
    ]).inheritStdio();

    return this.stop().then(() => {
        return cmd.execute();
      })
      .then(() => {return this;})
      .catch((error) => {
      throw new Error(`Failed to run docker command:\n${cmd.toString()}:\n${error}`);
    });
  }

}

module.exports = DockerContainer;
<|endoftext|>


<commit_before>'use strict'

const _ = require('lodash')

const machinomy = require('../index')

const channels = (command) => {
  let namespace = command.namespace || 'sender'
  let settings = machinomy.configuration.sender()

  let engine = machinomy.storage.engine(settings.databaseFile)
  let channels = machinomy.storage.channels(engine, namespace)
  channels.all().then(found => {
    _.each(found, paymentChannel => {
      let state = machinomy.contract.getState(paymentChannel.channelId)
      if (state < 2) {
        paymentChannel.state = state
        console.log(paymentChannel)
      }
    })
  })
}

module.exports = channels
<commit_msg>Beautification<commit_after>'use strict'

const _ = require('lodash')

const machinomy = require('../index')

const channels = (command) => {
  let namespace = command.namespace || 'sender'
  let settings = machinomy.configuration.sender()

  let engine = machinomy.storage.engine(settings.databaseFile)
  machinomy.storage.channels(engine, namespace).all().then(found => {
    _.each(found, paymentChannel => {
      let state = machinomy.contract.getState(paymentChannel.channelId)
      if (state < 2) {
        paymentChannel.state = state
        console.log(paymentChannel)
      }
    })
  })
}

module.exports = channels
<|endoftext|>


<commit_before>/**
 * @author Sean Griffin / http://twitter.com/sgrif
 * @author Michael Guerrero / http://realitymeltdown.com
 */

THREE.SkeletonHelper = function ( skeleton, jointBoxSize, scaleRatio ) {

  THREE.Object3D.call( this );

  this.scaleRatio = ( scaleRatio !== undefined ) ? scaleRatio : 1;
  this.skeleton = skeleton;

  var jointBoxSize = ( jointBoxSize !== undefined ) ? jointBoxSize : 1;
  var boxSize = jointBoxSize * this.scaleRatio;

  for ( var i = 0; i < skeleton.bones.length; ++i ) {

    var bone = skeleton.bones[ i ];
    var boxGeometry = new THREE.BoxGeometry( boxSize, boxSize, boxSize );
    var boxMaterial = new THREE.MeshBasicMaterial();

    bone.helper = {};
    bone.helper.box = new THREE.Mesh( boxGeometry, boxMaterial );
    bone.helper.axes = new THREE.AxisHelper( jointBoxSize * 3 );

    this.add( bone.helper.box );
    this.add( bone.helper.axes );

    if ( bone.parent instanceof THREE.Bone ) {

      var lineMaterial = new THREE.LineBasicMaterial();
      var lineGeometry = new THREE.Geometry();

      lineMaterial.vertexColors = true;

      lineGeometry.vertices.push( new THREE.Vector3() );
      lineGeometry.vertices.push( new THREE.Vector3() );
      lineGeometry.colors.push( new THREE.Color( 1, 1, 0 ) );
      lineGeometry.colors.push( new THREE.Color( 0, 0, 0 ) );

      bone.helper.line = new THREE.Line( lineGeometry, lineMaterial );
      this.add( bone.helper.line);

    }

  }

  this.update();
};

THREE.SkeletonHelper.prototype = Object.create( THREE.Object3D.prototype );

THREE.SkeletonHelper.prototype.update = function () {

  for ( var i = 0; i < this.skeleton.bones.length; ++i ) {

    var bone = this.skeleton.bones[ i ];

    if ( this.visible && bone.parent instanceof THREE.Bone ) {

      bone.skinMatrix.decompose( bone.helper.box.position, bone.helper.box.quaternion, bone.helper.box.scale );
      bone.helper.box.position.multiplyScalar( this.scaleRatio );

      bone.helper.axes.quaternion = bone.helper.box.quaternion;
      bone.helper.axes.position = bone.helper.box.position;
      bone.helper.axes.scale = bone.helper.box.scale;

      bone.helper.line.geometry.vertices[0].setFromMatrixPosition( bone.skinMatrix );
      bone.helper.line.geometry.vertices[0].multiplyScalar( this.scaleRatio );

      bone.helper.line.geometry.vertices[1].setFromMatrixPosition( bone.parent.skinMatrix );
      bone.helper.line.geometry.vertices[1].multiplyScalar( this.scaleRatio );

      bone.helper.line.geometry.verticesNeedUpdate = true;

    }

  }

};

THREE.SkeletonHelper.prototype.setVisible = function ( shouldBeVisible ) {

  for ( var i = 0; i < this.skeleton.bones.length; ++i ) {

    var bone = this.skeleton.bones[ i ];
    if ( bone.helper ) {

      bone.helper.box.visible = shouldBeVisible;
      bone.helper.axes.visible = shouldBeVisible;

      if ( bone.parent instanceof THREE.Bone ) {

         bone.helper.line.visible = shouldBeVisible;

      }

    }

  }
}
<commit_msg>Fixed compiler warning.<commit_after>/**
 * @author Sean Griffin / http://twitter.com/sgrif
 * @author Michael Guerrero / http://realitymeltdown.com
 */

THREE.SkeletonHelper = function ( skeleton, jointBoxSize, scaleRatio ) {

  THREE.Object3D.call( this );

  this.scaleRatio = ( scaleRatio !== undefined ) ? scaleRatio : 1;
  this.skeleton = skeleton;

  if ( jointBoxSize === undefined ) jointBoxSize = 1;

  var boxSize = jointBoxSize * this.scaleRatio;

  for ( var i = 0; i < skeleton.bones.length; ++i ) {

    var bone = skeleton.bones[ i ];
    var boxGeometry = new THREE.BoxGeometry( boxSize, boxSize, boxSize );
    var boxMaterial = new THREE.MeshBasicMaterial();

    bone.helper = {};
    bone.helper.box = new THREE.Mesh( boxGeometry, boxMaterial );
    bone.helper.axes = new THREE.AxisHelper( jointBoxSize * 3 );

    this.add( bone.helper.box );
    this.add( bone.helper.axes );

    if ( bone.parent instanceof THREE.Bone ) {

      var lineMaterial = new THREE.LineBasicMaterial();
      var lineGeometry = new THREE.Geometry();

      lineMaterial.vertexColors = true;

      lineGeometry.vertices.push( new THREE.Vector3() );
      lineGeometry.vertices.push( new THREE.Vector3() );
      lineGeometry.colors.push( new THREE.Color( 1, 1, 0 ) );
      lineGeometry.colors.push( new THREE.Color( 0, 0, 0 ) );

      bone.helper.line = new THREE.Line( lineGeometry, lineMaterial );
      this.add( bone.helper.line);

    }

  }

  this.update();
};

THREE.SkeletonHelper.prototype = Object.create( THREE.Object3D.prototype );

THREE.SkeletonHelper.prototype.update = function () {

  for ( var i = 0; i < this.skeleton.bones.length; ++i ) {

    var bone = this.skeleton.bones[ i ];

    if ( this.visible && bone.parent instanceof THREE.Bone ) {

      bone.skinMatrix.decompose( bone.helper.box.position, bone.helper.box.quaternion, bone.helper.box.scale );
      bone.helper.box.position.multiplyScalar( this.scaleRatio );

      bone.helper.axes.quaternion = bone.helper.box.quaternion;
      bone.helper.axes.position = bone.helper.box.position;
      bone.helper.axes.scale = bone.helper.box.scale;

      bone.helper.line.geometry.vertices[0].setFromMatrixPosition( bone.skinMatrix );
      bone.helper.line.geometry.vertices[0].multiplyScalar( this.scaleRatio );

      bone.helper.line.geometry.vertices[1].setFromMatrixPosition( bone.parent.skinMatrix );
      bone.helper.line.geometry.vertices[1].multiplyScalar( this.scaleRatio );

      bone.helper.line.geometry.verticesNeedUpdate = true;

    }

  }

};

THREE.SkeletonHelper.prototype.setVisible = function ( shouldBeVisible ) {

  for ( var i = 0; i < this.skeleton.bones.length; ++i ) {

    var bone = this.skeleton.bones[ i ];
    if ( bone.helper ) {

      bone.helper.box.visible = shouldBeVisible;
      bone.helper.axes.visible = shouldBeVisible;

      if ( bone.parent instanceof THREE.Bone ) {

         bone.helper.line.visible = shouldBeVisible;

      }

    }

  }
}
<|endoftext|>