<commit_before>const config = require('./config.json');
const fs = require('fs');
const moment = require('moment');
const blacklist = require('./serverconf/blacklist.json');
var timestamp;

module.exports = {
	"ready": function ready(client, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.green("[POWER]")} ${client.user.username} ready!`);
		client.user.setGame(`try '${config.commandPrefix} help' !`);
	},
	"error": function error(client, error, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.red("[CONNECTION]")} ${client.user.username} encountered a "serious connection error! | ${error.code}`);
	},
	"disconnect": function disconnect(client, error, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.red("[CONNECTION]")} ${client.user.username} was disconnected! | ${error.code}`);
		console.log(`client.status output: ${client.status}`);
		if(error.code == 1000) {
			console.log(`[${timestamp}]${chalk.green("[POWER]")} Automatically restarting...`);
			client.destroy().then(() => client.login(config.token));
			// Restart bot if disconnect code is 1000 (gracefully exited) because it won't reconnect automatically
		};
	},
	"reconnecting": function reconnecting(client, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.green("[CONNECTION]")} ${client.user.username} is reconnecting!`);
	},
	"join": function join(client, guild, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		if(blacklist.indexOf(guild.id) !== -1) return guild.leave();
		// blacklist check
		console.log(`[${timestamp}]${chalk.yellow("[GUILDS]")} ${client.user.username} has joined a new server! ("${guild.name}")`);
		fs.appendFileSync(`${config.logPath}${config.serverLog}`, `\n[${timestamp}][GUILDS] ${client.user.username} joined the '${guild.name}' server!`);
	},
	"leave": function leave(client, guild, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		if(blacklist.indexOf(guild.id) !== -1) return;
		// blacklist check
		console.log(`[${timestamp}]${chalk.yellow("[GUILDS]")} ${client.user.username} has left a server! ("${guild.name}")`);
		fs.appendFileSync(`${config.logPath}${config.serverLog}`, `\n[${timestamp}][GUILDS] ${client.user.username} left the '${guild.name}' server!`);
	}
};<commit_msg>Remove debugging log<commit_after>const config = require('./config.json');
const fs = require('fs');
const moment = require('moment');
const blacklist = require('./serverconf/blacklist.json');
var timestamp;

module.exports = {
	"ready": function ready(client, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.green("[POWER]")} ${client.user.username} ready!`);
		client.user.setGame(`try '${config.commandPrefix} help' !`);
	},
	"error": function error(client, error, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.red("[CONNECTION]")} ${client.user.username} encountered a "serious connection error! | ${error.code}`);
	},
	"disconnect": function disconnect(client, error, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.red("[CONNECTION]")} ${client.user.username} was disconnected! | ${error.code}`);
		if(error.code == 1000) {
			console.log(`[${timestamp}]${chalk.green("[POWER]")} Automatically restarting...`);
			client.destroy().then(() => client.login(config.token));
			// Restart bot if disconnect code is 1000 (gracefully exited) because it won't reconnect automatically
		};
	},
	"reconnecting": function reconnecting(client, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		console.log(`[${timestamp}]${chalk.green("[CONNECTION]")} ${client.user.username} is reconnecting!`);
	},
	"join": function join(client, guild, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		if(blacklist.indexOf(guild.id) !== -1) return guild.leave();
		// blacklist check
		console.log(`[${timestamp}]${chalk.yellow("[GUILDS]")} ${client.user.username} has joined a new server! ("${guild.name}")`);
		fs.appendFileSync(`${config.logPath}${config.serverLog}`, `\n[${timestamp}][GUILDS] ${client.user.username} joined the '${guild.name}' server!`);
	},
	"leave": function leave(client, guild, chalk) {
		timestamp = moment().format('DD/MM/YYYY HH:mm:ss');
		if(blacklist.indexOf(guild.id) !== -1) return;
		// blacklist check
		console.log(`[${timestamp}]${chalk.yellow("[GUILDS]")} ${client.user.username} has left a server! ("${guild.name}")`);
		fs.appendFileSync(`${config.logPath}${config.serverLog}`, `\n[${timestamp}][GUILDS] ${client.user.username} left the '${guild.name}' server!`);
	}
};<|endoftext|>


<commit_before>var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;

EventManager = function(host, port) {
  this.db= new Db('classon', new Server(host, port, {auto_reconnect: true}, {safe:false}));
  this.db.open(function(){});
};

EventManager.prototype.getCollection= function(callback) {
	  this.db.collection('events', function(error, events_collection) {
	    if( error ) callback(error);
	    else callback(null, events_collection);
	  });
	};

	EventManager.prototype.findAll = function(callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        events_collection.find().toArray(function(error, results) {
	          if( error ) callback(error);
	          else callback(null, results);
	        });
	      }
	    });
	};

	EventManager.prototype.findById = function(id, callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        events_collection.findOne({_id: events_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
	          if( error ) callback(error);
	          else callback(null, result);
	        });
	      }
	    });
	};

	EventManager.prototype.save = function(events, callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        if( typeof(events.length)=="undefined")
	          events = [events];

	        for( var i =0;i< events.length;i++ ) {
	          var event = events[i];
	          event.timestamp = new Date();
	        }

	        events_collection.insert(events, function() {
	          callback(null, events);
	        });
	      }
	    });
	};

	exports.EventManager = EventManager;<commit_msg>bug in the db connection sentence<commit_after>var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;

EventManager = function(host, port) {
  this.db= new Db('classon', new Server(host, port, {auto_reconnect: true}), {safe:false});
  this.db.open(function(){});
};

EventManager.prototype.getCollection= function(callback) {
	  this.db.collection('events', function(error, events_collection) {
	    if( error ) callback(error);
	    else callback(null, events_collection);
	  });
	};

	EventManager.prototype.findAll = function(callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        events_collection.find().toArray(function(error, results) {
	          if( error ) callback(error);
	          else callback(null, results);
	        });
	      }
	    });
	};

	EventManager.prototype.findById = function(id, callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        events_collection.findOne({_id: events_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
	          if( error ) callback(error);
	          else callback(null, result);
	        });
	      }
	    });
	};

	EventManager.prototype.save = function(events, callback) {
	    this.getCollection(function(error, events_collection) {
	      if( error ) callback(error);
	      else {
	        if( typeof(events.length)=="undefined")
	          events = [events];

	        for( var i =0;i< events.length;i++ ) {
	          var event = events[i];
	          event.timestamp = new Date();
	        }

	        events_collection.insert(events, function() {
	          callback(null, events);
	        });
	      }
	    });
	};

	exports.EventManager = EventManager;<|endoftext|>


<commit_before>var config = {
    noOuput: true,
    plugins: ['plugins/spectreport-github.plugin.js'],
    pluginOpts: {
        ghOnlyFail:true,
        ghUser:'username',
        ghPass:'ABC123DEF456',
        ghRepo:'username/reponame',
        ghId:7,
        ghReportUrl:'https://jenkins.internal/7/report.html'
    },
    jsonDir: 'test/results'
};
module.exports = config;
<commit_msg>Fix typo in example.conf.js<commit_after>var config = {
    noOutput: true,
    plugins: ['plugins/spectreport-github.plugin.js'],
    pluginOpts: {
        ghOnlyFail:true,
        ghUser:'username',
        ghPass:'ABC123DEF456',
        ghRepo:'username/reponame',
        ghId:7,
        ghReportUrl:'https://jenkins.internal/7/report.html'
    },
    jsonDir: 'test/results'
};
module.exports = config;
<|endoftext|>


<commit_before>// @flow
// @jsx glam

import './index.css';
import glam from 'glam';
import React, { Component } from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';

import {
  Animated,
  Async,
  Experimental,
  Home,
  NoMatch,
  Styled,
  Tests,
} from './pages';

const borderColor = 'hsl(0, 0%, 88%)';
const navWidth = 180;
const appGutter = 20;
const contentGutter = 30;
const smallDevice = '@media (max-width: 769px)';
const largeDevice = '@media (min-width: 770px)';

const AppContainer = props => (
  <div
    css={{
      marginLeft: 'auto',
      marginRight: 'auto',
      maxWidth: 640,
      minHeight: '100vh',
      padding: `0 ${appGutter}px`,
    }}
    {...props}
  />
);
const PageContent = props => (
  <div
    css={{
      paddingBottom: contentGutter,
      paddingTop: contentGutter,

      [smallDevice]: {
        paddingTop: contentGutter * 2,
      },
    }}
    {...props}
  />
);
const AppContent = props => (
  <div
    css={{
      flex: '1 1 auto',
      marginLeft: 'auto',
      marginRight: 'auto',

      [largeDevice]: {
        paddingLeft: navWidth + contentGutter,

        ':before': {
          borderRight: `1px solid ${borderColor}`,
          content: ' ',
          marginLeft: -(navWidth + contentGutter),
          height: '100%',
          position: 'fixed',
          width: navWidth,
        },
      },
    }}
    {...props}
  />
);
const Nav = props => (
  <div
    css={{
      [smallDevice]: {
        backgroundColor: 'rgba(255, 255, 255, 0.96)',
        boxShadow: 'inset 0 -1px 0 rgba(0, 0, 0, 0.1)',
        display: 'flex ',
        fontSize: 13,
        fontWeight: 'bold',
        marginLeft: -appGutter,
        marginRight: -appGutter,
        overflowX: 'auto',
        position: 'fixed',
        top: 0,
        width: '100%',
        '-webkit-overflow-scrolling': 'touch',
      },

      [largeDevice]: {
        display: 'block',
        float: 'left',
        paddingTop: contentGutter,
        position: 'fixed',
        width: navWidth,
        zIndex: 1,
      },
    }}
    {...props}
  />
);
const NavItem = ({ selected, ...props }) => (
  <Link
    css={{
      color: selected ? 'hsl(0, 0%, 0%)' : 'hsl(0, 0%, 40%)',
      display: 'inline-block',
      padding: `15px ${appGutter}px`,
      position: 'relative',
      textDecoration: 'none',
      whiteSpace: 'nowrap',

      ':hover, :active': {
        color: selected ? 'hsl(0, 0%, 10%)' : '#2684FF',
      },

      [smallDevice]: {
        boxShadow: selected ? 'inset 0 -1px 0 black' : null,
      },

      [largeDevice]: {
        backgroundColor: selected ? 'white' : 'transparent',
        borderColor: selected ? borderColor : 'transparent',
        borderStyle: 'solid',
        borderWidth: '1px 0',
        display: 'block',
        padding: '10px 20px 10px 0',
        right: -1,

        ':before': {
          content: ' ',
          // background: 'linear-gradient(90deg, fade(#e9e9e9, 0%) 94%, #e9e9e9)',
        },
      },
    }}
    {...props}
  />
);
const links = [
  { label: 'Home', value: '/' },
  { label: 'Animation', value: '/animated' },
  { label: 'Async Options', value: '/async' },
  { label: 'Custom Styles', value: '/styled' },
  { label: 'Experimental', value: '/experimental' },
];

export default class App extends Component<*> {
  render() {
    return (
      <BrowserRouter>
        <Route>
          <AppContainer>
            <Route
              render={({ location }) => (
                <Nav>
                  {links.map(l => {
                    const selected = location.pathname === l.value;
                    return (
                      <NavItem key={l.value} selected={selected} to={l.value}>
                        {l.label}
                      </NavItem>
                    );
                  })}
                </Nav>
              )}
            />
            <AppContent>
              <PageContent>
                <Switch>
                  <Route exact path="/" component={Home} />
                  <Route exact path="/animated" component={Animated} />
                  <Route exact path="/async" component={Async} />
                  <Route exact path="/styled" component={Styled} />
                  <Route exact path="/experimental" component={Experimental} />
                  <Route exact path="/tests" component={Tests} />
                  <Route component={NoMatch} />
                </Switch>
              </PageContent>
            </AppContent>
          </AppContainer>
        </Route>
      </BrowserRouter>
    );
  }
}
<commit_msg>fix vendor prefix syntax<commit_after>// @flow
// @jsx glam

import './index.css';
import glam from 'glam';
import React, { Component } from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';

import {
  Animated,
  Async,
  Experimental,
  Home,
  NoMatch,
  Styled,
  Tests,
} from './pages';

const borderColor = 'hsl(0, 0%, 88%)';
const navWidth = 180;
const appGutter = 20;
const contentGutter = 30;
const smallDevice = '@media (max-width: 769px)';
const largeDevice = '@media (min-width: 770px)';

const AppContainer = props => (
  <div
    css={{
      marginLeft: 'auto',
      marginRight: 'auto',
      maxWidth: 640,
      minHeight: '100vh',
      padding: `0 ${appGutter}px`,
    }}
    {...props}
  />
);
const PageContent = props => (
  <div
    css={{
      paddingBottom: contentGutter,
      paddingTop: contentGutter,

      [smallDevice]: {
        paddingTop: contentGutter * 2,
      },
    }}
    {...props}
  />
);
const AppContent = props => (
  <div
    css={{
      flex: '1 1 auto',
      marginLeft: 'auto',
      marginRight: 'auto',

      [largeDevice]: {
        paddingLeft: navWidth + contentGutter,

        ':before': {
          borderRight: `1px solid ${borderColor}`,
          content: ' ',
          marginLeft: -(navWidth + contentGutter),
          height: '100%',
          position: 'fixed',
          width: navWidth,
        },
      },
    }}
    {...props}
  />
);
const Nav = props => (
  <div
    css={{
      [smallDevice]: {
        backgroundColor: 'rgba(255, 255, 255, 0.96)',
        boxShadow: 'inset 0 -1px 0 rgba(0, 0, 0, 0.1)',
        display: 'flex ',
        fontSize: 13,
        fontWeight: 'bold',
        marginLeft: -appGutter,
        marginRight: -appGutter,
        overflowX: 'auto',
        position: 'fixed',
        top: 0,
        width: '100%',
        WebkitOverflowScrolling: 'touch',
      },

      [largeDevice]: {
        display: 'block',
        float: 'left',
        paddingTop: contentGutter,
        position: 'fixed',
        width: navWidth,
        zIndex: 1,
      },
    }}
    {...props}
  />
);
const NavItem = ({ selected, ...props }) => (
  <Link
    css={{
      color: selected ? 'hsl(0, 0%, 0%)' : 'hsl(0, 0%, 40%)',
      display: 'inline-block',
      padding: `15px ${appGutter}px`,
      position: 'relative',
      textDecoration: 'none',
      whiteSpace: 'nowrap',

      ':hover, :active': {
        color: selected ? 'hsl(0, 0%, 10%)' : '#2684FF',
      },

      [smallDevice]: {
        boxShadow: selected ? 'inset 0 -1px 0 black' : null,
      },

      [largeDevice]: {
        backgroundColor: selected ? 'white' : 'transparent',
        borderColor: selected ? borderColor : 'transparent',
        borderStyle: 'solid',
        borderWidth: '1px 0',
        display: 'block',
        padding: '10px 20px 10px 0',
        right: -1,

        ':before': {
          content: ' ',
          // background: 'linear-gradient(90deg, fade(#e9e9e9, 0%) 94%, #e9e9e9)',
        },
      },
    }}
    {...props}
  />
);
const links = [
  { label: 'Home', value: '/' },
  { label: 'Animation', value: '/animated' },
  { label: 'Async Options', value: '/async' },
  { label: 'Custom Styles', value: '/styled' },
  { label: 'Experimental', value: '/experimental' },
];

export default class App extends Component<*> {
  render() {
    return (
      <BrowserRouter>
        <Route>
          <AppContainer>
            <Route
              render={({ location }) => (
                <Nav>
                  {links.map(l => {
                    const selected = location.pathname === l.value;
                    return (
                      <NavItem key={l.value} selected={selected} to={l.value}>
                        {l.label}
                      </NavItem>
                    );
                  })}
                </Nav>
              )}
            />
            <AppContent>
              <PageContent>
                <Switch>
                  <Route exact path="/" component={Home} />
                  <Route exact path="/animated" component={Animated} />
                  <Route exact path="/async" component={Async} />
                  <Route exact path="/styled" component={Styled} />
                  <Route exact path="/experimental" component={Experimental} />
                  <Route exact path="/tests" component={Tests} />
                  <Route component={NoMatch} />
                </Switch>
              </PageContent>
            </AppContent>
          </AppContainer>
        </Route>
      </BrowserRouter>
    );
  }
}
<|endoftext|>


<commit_before>import './bootstrap'

import Vue from 'vue'
import VueUIkit from '../src/index'

import Index from './Index.vue'

Vue.use(VueUIkit)

/* eslint-disable no-new */
new Vue({
    el: '#examples',
    render: h => h(Index)
})
<commit_msg>Add router<commit_after>import './bootstrap'

import Vue from 'vue'
import router from './router'
import VueUIkit from '../src/index'

import Index from './Index.vue'

Vue.use(VueUIkit)

/* eslint-disable no-new */
new Vue({
    el: '#examples',
    router,
    render: h => h(Index)
})
<|endoftext|>


<commit_before>// simple example of making the drone fly

var arDrone = require('ar-drone');

var client = arDrone.createClient();
// make sure the client always calls disableEmergency() before taking off
var takeoff = client.takeoff;
client.takeoff = function (value) {
  this.disableEmergency();
  takeoff.call(this, value);
};

// repl for emergency...
client.createRepl();

var cmds = [
  'stop'
, 'takeoff'
, 'land'
, 'up'
, 'down'
, 'clockwise'
, 'counterClockwise'
, 'front'
, 'back'
, 'left'
, 'right'
, 'animate'
, 'animateLeds'
];

// basic example. Drone can hook in here (event triggers command)
var controller = require('../leap-remote');

  // iterate over all the commands and bind them to the event listeners
cmds.forEach(function (cmd) {
  controller.on(cmd, function (value) {
    console.log(cmd, value);
    client[cmd](value);
  });
});

controller.registerClient(client);

// once everything is ready, start the controller
controller.start();
<commit_msg>give low battery warning and display battery information at the start<commit_after>// simple example of making the drone fly

var arDrone = require('ar-drone');

var client = arDrone.createClient();
// make sure the client always calls disableEmergency() before taking off
var takeoff = client.takeoff;
client.takeoff = function (value) {
  this.disableEmergency();
  takeoff.call(this, value);
};

// repl for emergency...
//client.createRepl();
client.config('general:navdata_demo', 'FALSE');

var cmds = [
  'stop'
, 'takeoff'
, 'land'
, 'up'
, 'down'
, 'clockwise'
, 'counterClockwise'
, 'front'
, 'back'
, 'left'
, 'right'
, 'animate'
, 'animateLeds'
];

// basic example. Drone can hook in here (event triggers command)
var controller = require('../leap-remote');

  // iterate over all the commands and bind them to the event listeners
cmds.forEach(function (cmd) {
  controller.on(cmd, function (value) {
    console.log(cmd, value);
    client[cmd](value);
  });
});

client.once('navdata', function (navdata) {
  if (!navdata.droneState.lowBattery) {
    // once everything is ready, start the controller
    console.log('START', navdata.demo && navdata.demo.batteryPercentage, '%');
    controller.registerClient(client);
    controller.start();
  } else {
    console.log('LOW BATTERY', navdata.demo.batteryPercentage, '%');
  }
});

client.on('navdata', function (navdata) {
  if (navdata.droneState.lowBattery) {
    client.land();
  }
});
<|endoftext|>


<commit_before>var BOSH_SERVICE = '/http-bind',
    DOMAIN = window.location.hostname;
    CONFERENCEDOMAIN = 'conference.' + DOMAIN,
    ice_config = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]},
    RTC = null,
    RTCPeerConnection = null,
    AUTOACCEPT = true,
    PRANSWER = false, // use either pranswer or autoaccept
    RAWLOGGING = true,
    MULTIPARTY = true,
    localStream = null,
    connection = null,
    myroomjid = null,
    roomjid = null,
    list_members = [];

function setStatus(txt) {
    console.log('status', txt);
    $('#status').text(txt);
}

function onConnect(status) {
    if (status == Strophe.Status.CONNECTING) {
        setStatus('Connecting.');
    } else if (status == Strophe.Status.CONNFAIL) {
        setStatus('Connecting failed.');
    } else if (status == Strophe.Status.DISCONNECTING) {
        setStatus('Disconnecting.');
    } else if (status == Strophe.Status.DISCONNECTED) {
        setStatus('Disconnected.');
        if (localStream) {
            localStream.stop();
            localStream = null;
        }
    } else if (status == Strophe.Status.CONNECTED) {
        setStatus('Connected.');
        connection.jingle.getStunAndTurnCredentials();

        // disco stuff
        if (connection.disco) {
            connection.disco.addIdentity('client', 'web');
            connection.disco.addFeature(Strophe.NS.DISCO_INFO);
        }
        $(document).trigger('connected');
    }
}

function onConnected(event) {
    doJoin();
    setTimeout(function() {
           $(window).bind('hashchange', onHashChange);
    }, 500);
}

function doJoin() {
    var roomnode = null,
        pres;
    if (location.hash.length > 1) {
        roomnode = location.hash.substr(1).toLowerCase();
        if (roomnode.indexOf('/') != -1) {
            setStatus('invalid location, must not contain "/"');
            connection.disconnect();
            return;
        }
        if (roomnode.indexOf('@') != -1) { // allow #room@host
            roomjid = roomnode;
        }
    } else {
        roomnode = Math.random().toString(36).substr(2, 8);
        location.hash = roomnode;
    }
    if (roomjid == null) {
        roomjid = roomnode + '@' + CONFERENCEDOMAIN;
    }
    setStatus('Joining ' + location.hash);
    myroomjid = roomjid + '/' + Strophe.getNodeFromJid(connection.jid);
    list_members = new Array();
    console.log('joining', roomjid);

    // muc stuff
    connection.addHandler(onPresence, null, 'presence', null, null, roomjid, {matchBare: true});
    connection.addHandler(onPresenceUnavailable, null, 'presence', 'unavailable', null, roomjid, {matchBare: true});
    connection.addHandler(onPresenceError, null, 'presence', 'error', null, roomjid, {matchBare: true});

    pres = $pres({to: myroomjid })
            .c('x', {xmlns: 'http://jabber.org/protocol/muc'});
    connection.send(pres);
}

function onHashChange() {
    setStatus('hashChange: ' + window.location.hash);
    if (Object.keys(connection.jingle.sessions).length == 0) {
        window.location.reload();
    }
}

function onPresence(pres) {
    var from = pres.getAttribute('from'),
        type = pres.getAttribute('type');
    if (type != null) {
        return true;
    }
    if (from == myroomjid) {
        onJoinComplete();
    } else { // TODO: prevent duplicates
        list_members.push(from);
    }
    return true;
}

function onPresenceUnavailable(pres) {
    connection.jingle.terminateByJid($(pres).attr('from'));
    if (Object.keys(connection.jingle.sessions).length == 0) {
        setStatus('everyone left');
    }
    for (var i = 0; i < list_members.length; i++) {
        if (list_members[i] == $(pres).attr('from')) {
            list_members.splice(i, 1);
            break;
        }
    }
    return true;
}

function onPresenceError(pres) {
    setStatus('onPresError ' + pres);
    return true;
}

function onJoinComplete() {
    setStatus('onJoinComplete');
    if (list_members.length < 1) {
        setStatus('waiting for peer');
        return;
    }

    setStatus('initiating call');
    var i, sess, num;
    num = MULTIPARTY ? list_members.length : 1;
    for (i = 0; i < num; i++) {
        connection.jingle.initiate(list_members[i], myroomjid);
    }
}

function onMediaReady(event, stream) {
    localStream = stream;
    connection.jingle.localStream = stream;
    for (i = 0; i < localStream.getAudioTracks().length; i++) {
        setStatus('using audio device "' + localStream.getAudioTracks()[i].label + '"');
    }
    for (i = 0; i < localStream.getVideoTracks().length; i++) {
        setStatus('using video device "' + localStream.getVideoTracks()[i].label + '"');
    }
    // mute video on firefox and recent canary
    $('#minivideo')[0].muted = true;
    $('#minivideo')[0].volume = 0;

    RTC.attachMediaStream($('#minivideo'), localStream);

    doConnect();
}

function onMediaFailure() {
    setStatus('media failure');
}

function onCallIncoming(event, sid) {
    setStatus('incoming call' + sid);
}

function onCallActive(event, videoelem, sid) {
    setStatus('call active ' + sid);
    $(videoelem).appendTo('#largevideocontainer');
    arrangeVideos('#largevideocontainer >');
}

function onCallTerminated(event, sid, reason) {
    setStatus('call terminated ' + sid + (reason ? (': ' + reason) : ''));
    if (Object.keys(connection.jingle.sessions).length == 0) {
        setStatus('all calls terminated');
    }
    $('#largevideocontainer #largevideo_' + sid).remove();
    arrangeVideos('#largevideocontainer >');
}

function onRemoteStreamAdded(event, data, sid) {
    setStatus('Remote stream for session ' + sid + ' added.');
    if ($('#largevideo_' + sid).length != 0) {
        console.log('ignoring duplicate onRemoteStreamAdded...'); // FF 20
        return;
    }
    // after remote stream has been added, wait for ice to become connected
    // old code for compat with FF22 beta
    var el = $("<video autoplay='autoplay' style='display:none'/>").attr('id', 'largevideo_' + sid);
    RTC.attachMediaStream(el, data.stream);
    waitForRemoteVideo(el, sid);
}

function waitForRemoteVideo(selector, sid) {
    sess = connection.jingle.sessions[sid];
    videoTracks = sess.remoteStream.getVideoTracks();
    if (videoTracks.length === 0 || selector[0].currentTime > 0) {
        $(document).trigger('callactive', [selector, sid]);
        RTC.attachMediaStream(selector, sess.remoteStream); // FIXME: why do i have to do this for FF?
        console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
    } else {
        setTimeout(function() { waitForRemoteVideo(selector, sid); }, 100);
    }
}

function onRemoteStreamRemoved(event, data, sid) {
    setStatus('Remote stream for session ' + sid + ' removed.');
}

function onIceConnectionStateChanged(event, sid, sess) {
    console.log('ice state for', sid, sess.peerconnection.iceConnectionState);
    console.log('sig state for', sid, sess.peerconnection.signalingState);
    // works like charm, unfortunately only in chrome and FF nightly, not FF22 beta
    /*
    if (sess.peerconnection.signalingState == 'stable' && sess.peerconnection.iceConnectionState == 'connected') {
        var el = $("<video autoplay='autoplay' style='display:none'/>").attr('id', 'largevideo_' + sid);
        $(document).trigger('callactive', [el, sid]);
        RTC.attachMediaStream(el, sess.remoteStream); // moving this before the trigger doesn't work in FF?!
    }
    */
}

function arrangeVideos(selector) {
    var floor = Math.floor,
        elements = $(selector),
        howMany = elements.length,
        availableWidth = $(selector).parent().innerWidth(),
        availableHeight = $(selector).parent().innerHeight(),
        usedWidth = 0;
        aspectRatio = 4 / 3;
    if (availableHeight < availableWidth / aspectRatio) {
        availableWidth = availableHeight * aspectRatio;
    }
    elements.height(availableHeight);

    elements.each(function(index) {
        $(elements[index]).removeAttr('style');
    });

    // hardcoded layout for up to four videos
    switch (howMany) {
    case 1:
        usedWidth = availableWidth;
        $(elements[0]).css('top', 0);
        $(elements[0]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        break;
    case 2:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[1]).css({ right: '0px', bottom: '0px'});
        break;
    case 3:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[1]).css({ right: '0px', top: '0px'});
        $(elements[2]).css({ left: ($(selector).parent().innerWidth() - availableWidth + usedWidth) / 2, bottom: '0px' });
        break;
    case 4:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[0]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[1]).css({ right: '0px', top: '0px'});
        $(elements[1]).css('right', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[2]).css({ left: '0px', bottom: '0px'});
        $(elements[2]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[3]).css({ right: '0px', bottom: '0px'});
        $(elements[3]).css('right', ($(selector).parent().innerWidth() - availableWidth) / 2);
        break;
    }
    elements.each(function(index) {
        $(elements[index]).css({
            position: 'absolute',
            width: usedWidth,
            height: usedWidth / aspectRatio
        });
        $(elements[index]).show();
    });
}

function noStunCandidates(event) {
    setStatus('webrtc did not encounter stun candidates, NAT traversal will not work');
    console.warn('webrtc did not encounter stun candidates, NAT traversal will not work');
}

$(window).bind('beforeunload', function() {
    if (connection && connection.connected) {
        // ensure signout
        $.ajax({
                type: 'POST',
                url: '/http-bind',
                async: false,
                cache: false,
                contentType: 'application/xml',
                data: "<body rid='" + connection.rid + "' xmlns='http://jabber.org/protocol/httpbind' sid='" + connection.sid + "' type='terminate'><presence xmlns='jabber:client' type='unavailable'/></body>",
                success: function(data) {
                console.log('signed out');
                console.log(data);
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.log('signout error', textStatus + ' (' + errorThrown + ')');
            }
        });
    }
});

$(document).ready(function() {
    RTC = setupRTC();
    connection = new Strophe.Connection(BOSH_SERVICE);
    if (RAWLOGGING) {
        connection.rawInput = function(data) { console.log('RECV: ' + data); };
        connection.rawOutput = function(data) { console.log('SEND: ' + data); };
    }
    connection.jingle.PRANSWER = PRANSWER;
    connection.jingle.AUTOACCEPT = AUTOACCEPT;
    connection.jingle.ice_config = ice_config;
    connection.jingle.MULTIPARTY = MULTIPARTY;
    connection.jingle.pc_constraints = RTC.pc_constraints;

    $(document).bind('connected', onConnected);
    $(document).bind('mediaready', onMediaReady);
    $(document).bind('mediafailure', onMediaFailure);
    $(document).bind('callincoming', onCallIncoming);
    $(document).bind('callactive', onCallActive);
    $(document).bind('callterminated', onCallTerminated);

    $(document).bind('remotestreamadded', onRemoteStreamAdded);
    $(document).bind('remotestreamremoved', onRemoteStreamRemoved);
    $(document).bind('iceconnectionstatechange', onIceConnectionStateChanged);
    $(document).bind('nostuncandidates', noStunCandidates);
    if (RTC != null) {
        RTCPeerconnection = RTC.peerconnection;
        if (RTC.browser == 'firefox') {
            connection.jingle.media_constraints.mandatory['MozDontOfferDataChannel'] = true;
        }
        //setStatus('please allow access to microphone and camera');
        //getUserMediaWithConstraints();
    } else {
        setStatus('webrtc capable browser required');
    }
});

<commit_msg>instant room creation, thanks kev<commit_after>var BOSH_SERVICE = '/http-bind',
    DOMAIN = window.location.hostname;
    CONFERENCEDOMAIN = 'conference.' + DOMAIN,
    ice_config = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]},
    RTC = null,
    RTCPeerConnection = null,
    AUTOACCEPT = true,
    PRANSWER = false, // use either pranswer or autoaccept
    RAWLOGGING = true,
    MULTIPARTY = true,
    localStream = null,
    connection = null,
    myroomjid = null,
    roomjid = null,
    list_members = [];

function setStatus(txt) {
    console.log('status', txt);
    $('#status').text(txt);
}

function onConnect(status) {
    if (status == Strophe.Status.CONNECTING) {
        setStatus('Connecting.');
    } else if (status == Strophe.Status.CONNFAIL) {
        setStatus('Connecting failed.');
    } else if (status == Strophe.Status.DISCONNECTING) {
        setStatus('Disconnecting.');
    } else if (status == Strophe.Status.DISCONNECTED) {
        setStatus('Disconnected.');
        if (localStream) {
            localStream.stop();
            localStream = null;
        }
    } else if (status == Strophe.Status.CONNECTED) {
        setStatus('Connected.');
        connection.jingle.getStunAndTurnCredentials();

        // disco stuff
        if (connection.disco) {
            connection.disco.addIdentity('client', 'web');
            connection.disco.addFeature(Strophe.NS.DISCO_INFO);
        }
        $(document).trigger('connected');
    }
}

function onConnected(event) {
    doJoin();
    setTimeout(function() {
           $(window).bind('hashchange', onHashChange);
    }, 500);
}

function doJoin() {
    var roomnode = null,
        pres;
    if (location.hash.length > 1) {
        roomnode = location.hash.substr(1).toLowerCase();
        if (roomnode.indexOf('/') != -1) {
            setStatus('invalid location, must not contain "/"');
            connection.disconnect();
            return;
        }
        if (roomnode.indexOf('@') != -1) { // allow #room@host
            roomjid = roomnode;
        }
    } else {
        roomnode = Math.random().toString(36).substr(2, 8);
        location.hash = roomnode;
    }
    if (roomjid == null) {
        roomjid = roomnode + '@' + CONFERENCEDOMAIN;
    }
    setStatus('Joining ' + location.hash);
    myroomjid = roomjid + '/' + Strophe.getNodeFromJid(connection.jid);
    list_members = new Array();
    console.log('joining', roomjid);

    // muc stuff
    connection.addHandler(onPresence, null, 'presence', null, null, roomjid, {matchBare: true});
    connection.addHandler(onPresenceUnavailable, null, 'presence', 'unavailable', null, roomjid, {matchBare: true});
    connection.addHandler(onPresenceError, null, 'presence', 'error', null, roomjid, {matchBare: true});

    pres = $pres({to: myroomjid })
            .c('x', {xmlns: 'http://jabber.org/protocol/muc'});
    connection.send(pres);
}

function onHashChange() {
    setStatus('hashChange: ' + window.location.hash);
    if (Object.keys(connection.jingle.sessions).length == 0) {
        window.location.reload();
    }
}

function onPresence(pres) {
    var from = pres.getAttribute('from'),
        type = pres.getAttribute('type');
    if (type != null) {
        return true;
    }
    if ($(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="201"]').length) {
        // http://xmpp.org/extensions/xep-0045.html#createroom-instant
        var create = $iq({type: 'set', to:roomjid})
                .c('query', {xmlns: 'http://jabber.org/protocol/muc#owner'})
                .c('x', {xmlns: 'jabber:x:data', type: 'submit'});
        connection.send(create); // fire away
    }
    if (from == myroomjid) {
        onJoinComplete();
    } else { // TODO: prevent duplicates
        list_members.push(from);
    }
    return true;
}

function onPresenceUnavailable(pres) {
    connection.jingle.terminateByJid($(pres).attr('from'));
    if (Object.keys(connection.jingle.sessions).length == 0) {
        setStatus('everyone left');
    }
    for (var i = 0; i < list_members.length; i++) {
        if (list_members[i] == $(pres).attr('from')) {
            list_members.splice(i, 1);
            break;
        }
    }
    return true;
}

function onPresenceError(pres) {
    setStatus('onPresError ' + pres);
    return true;
}

function onJoinComplete() {
    setStatus('onJoinComplete');
    if (list_members.length < 1) {
        setStatus('waiting for peer');
        return;
    }

    setStatus('initiating call');
    var i, sess, num;
    num = MULTIPARTY ? list_members.length : 1;
    for (i = 0; i < num; i++) {
        connection.jingle.initiate(list_members[i], myroomjid);
    }
}

function onMediaReady(event, stream) {
    localStream = stream;
    connection.jingle.localStream = stream;
    for (i = 0; i < localStream.getAudioTracks().length; i++) {
        setStatus('using audio device "' + localStream.getAudioTracks()[i].label + '"');
    }
    for (i = 0; i < localStream.getVideoTracks().length; i++) {
        setStatus('using video device "' + localStream.getVideoTracks()[i].label + '"');
    }
    // mute video on firefox and recent canary
    $('#minivideo')[0].muted = true;
    $('#minivideo')[0].volume = 0;

    RTC.attachMediaStream($('#minivideo'), localStream);

    doConnect();
}

function onMediaFailure() {
    setStatus('media failure');
}

function onCallIncoming(event, sid) {
    setStatus('incoming call' + sid);
}

function onCallActive(event, videoelem, sid) {
    setStatus('call active ' + sid);
    $(videoelem).appendTo('#largevideocontainer');
    arrangeVideos('#largevideocontainer >');
}

function onCallTerminated(event, sid, reason) {
    setStatus('call terminated ' + sid + (reason ? (': ' + reason) : ''));
    if (Object.keys(connection.jingle.sessions).length == 0) {
        setStatus('all calls terminated');
    }
    $('#largevideocontainer #largevideo_' + sid).remove();
    arrangeVideos('#largevideocontainer >');
}

function onRemoteStreamAdded(event, data, sid) {
    setStatus('Remote stream for session ' + sid + ' added.');
    if ($('#largevideo_' + sid).length != 0) {
        console.log('ignoring duplicate onRemoteStreamAdded...'); // FF 20
        return;
    }
    // after remote stream has been added, wait for ice to become connected
    // old code for compat with FF22 beta
    var el = $("<video autoplay='autoplay' style='display:none'/>").attr('id', 'largevideo_' + sid);
    RTC.attachMediaStream(el, data.stream);
    waitForRemoteVideo(el, sid);
}

function waitForRemoteVideo(selector, sid) {
    sess = connection.jingle.sessions[sid];
    videoTracks = sess.remoteStream.getVideoTracks();
    if (videoTracks.length === 0 || selector[0].currentTime > 0) {
        $(document).trigger('callactive', [selector, sid]);
        RTC.attachMediaStream(selector, sess.remoteStream); // FIXME: why do i have to do this for FF?
        console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
    } else {
        setTimeout(function() { waitForRemoteVideo(selector, sid); }, 100);
    }
}

function onRemoteStreamRemoved(event, data, sid) {
    setStatus('Remote stream for session ' + sid + ' removed.');
}

function onIceConnectionStateChanged(event, sid, sess) {
    console.log('ice state for', sid, sess.peerconnection.iceConnectionState);
    console.log('sig state for', sid, sess.peerconnection.signalingState);
    // works like charm, unfortunately only in chrome and FF nightly, not FF22 beta
    /*
    if (sess.peerconnection.signalingState == 'stable' && sess.peerconnection.iceConnectionState == 'connected') {
        var el = $("<video autoplay='autoplay' style='display:none'/>").attr('id', 'largevideo_' + sid);
        $(document).trigger('callactive', [el, sid]);
        RTC.attachMediaStream(el, sess.remoteStream); // moving this before the trigger doesn't work in FF?!
    }
    */
}

function arrangeVideos(selector) {
    var floor = Math.floor,
        elements = $(selector),
        howMany = elements.length,
        availableWidth = $(selector).parent().innerWidth(),
        availableHeight = $(selector).parent().innerHeight(),
        usedWidth = 0;
        aspectRatio = 4 / 3;
    if (availableHeight < availableWidth / aspectRatio) {
        availableWidth = availableHeight * aspectRatio;
    }
    elements.height(availableHeight);

    elements.each(function(index) {
        $(elements[index]).removeAttr('style');
    });

    // hardcoded layout for up to four videos
    switch (howMany) {
    case 1:
        usedWidth = availableWidth;
        $(elements[0]).css('top', 0);
        $(elements[0]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        break;
    case 2:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[1]).css({ right: '0px', bottom: '0px'});
        break;
    case 3:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[1]).css({ right: '0px', top: '0px'});
        $(elements[2]).css({ left: ($(selector).parent().innerWidth() - availableWidth + usedWidth) / 2, bottom: '0px' });
        break;
    case 4:
        usedWidth = availableWidth / 2;
        $(elements[0]).css({ left: '0px', top: '0px'});
        $(elements[0]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[1]).css({ right: '0px', top: '0px'});
        $(elements[1]).css('right', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[2]).css({ left: '0px', bottom: '0px'});
        $(elements[2]).css('left', ($(selector).parent().innerWidth() - availableWidth) / 2);
        $(elements[3]).css({ right: '0px', bottom: '0px'});
        $(elements[3]).css('right', ($(selector).parent().innerWidth() - availableWidth) / 2);
        break;
    }
    elements.each(function(index) {
        $(elements[index]).css({
            position: 'absolute',
            width: usedWidth,
            height: usedWidth / aspectRatio
        });
        $(elements[index]).show();
    });
}

function noStunCandidates(event) {
    setStatus('webrtc did not encounter stun candidates, NAT traversal will not work');
    console.warn('webrtc did not encounter stun candidates, NAT traversal will not work');
}

$(window).bind('beforeunload', function() {
    if (connection && connection.connected) {
        // ensure signout
        $.ajax({
                type: 'POST',
                url: '/http-bind',
                async: false,
                cache: false,
                contentType: 'application/xml',
                data: "<body rid='" + connection.rid + "' xmlns='http://jabber.org/protocol/httpbind' sid='" + connection.sid + "' type='terminate'><presence xmlns='jabber:client' type='unavailable'/></body>",
                success: function(data) {
                console.log('signed out');
                console.log(data);
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.log('signout error', textStatus + ' (' + errorThrown + ')');
            }
        });
    }
});

$(document).ready(function() {
    RTC = setupRTC();
    connection = new Strophe.Connection(BOSH_SERVICE);
    if (RAWLOGGING) {
        connection.rawInput = function(data) { console.log('RECV: ' + data); };
        connection.rawOutput = function(data) { console.log('SEND: ' + data); };
    }
    connection.jingle.PRANSWER = PRANSWER;
    connection.jingle.AUTOACCEPT = AUTOACCEPT;
    connection.jingle.ice_config = ice_config;
    connection.jingle.MULTIPARTY = MULTIPARTY;
    connection.jingle.pc_constraints = RTC.pc_constraints;

    $(document).bind('connected', onConnected);
    $(document).bind('mediaready', onMediaReady);
    $(document).bind('mediafailure', onMediaFailure);
    $(document).bind('callincoming', onCallIncoming);
    $(document).bind('callactive', onCallActive);
    $(document).bind('callterminated', onCallTerminated);

    $(document).bind('remotestreamadded', onRemoteStreamAdded);
    $(document).bind('remotestreamremoved', onRemoteStreamRemoved);
    $(document).bind('iceconnectionstatechange', onIceConnectionStateChanged);
    $(document).bind('nostuncandidates', noStunCandidates);
    if (RTC != null) {
        RTCPeerconnection = RTC.peerconnection;
        if (RTC.browser == 'firefox') {
            connection.jingle.media_constraints.mandatory['MozDontOfferDataChannel'] = true;
        }
        //setStatus('please allow access to microphone and camera');
        //getUserMediaWithConstraints();
    } else {
        setStatus('webrtc capable browser required');
    }
});

<|endoftext|>


<commit_before>/*jshint esversion: 6 */

import Dispatcher from '../dispatcher';
import Constants from './single-map-constants';

const ACTION_TYPES = Constants.ACTION_TYPES;
var SingleMapActions = {

    openEditMapDialog: function() {
        Dispatcher.dispatch({
            actionType: ACTION_TYPES.OPEN_EDIT_MAP_DIALOG
        });
    },

    closeEditMapDialog: function() {
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_MAP_DIALOG
      });
    },

    submitEditMapDialog: function(data) {
      if(!data){
        console.error('No map data, aborting...');
        return;
      }
      if(  !data.mapID || !data.responsiblePerson ||
        !((data.user && data.purpose) || data.name)){
        console.log('Incomplete map data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_EDIT_MAP_DIALOG,
          data : data
      });
    },

    openAddNodeDialog : function(coords, type){
      if(!coords || !type){
        console.error('No new node data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_NEW_NODE_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddNodeDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_NEW_NODE_DIALOG
      });
    },

    submitAddNodeDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords || !data.type){
        console.error('incomplete data, aborting', data);
        return;
      }
      if(!data.name || !data.responsiblePerson || !data.inertia || !data.description){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_NEW_NODE_DIALOG,
          data : data
      });
    },

    openAddCommentDialog(coords, type){
      if(!coords || !type){
        console.error('No new node data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_ADD_COMMENT_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddCommentDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_ADD_COMMENT_DIALOG
      });
    },

    submitAddCommentDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords){
        console.error('incomplete data, aborting', data);
        return;
      }
      if(!data.comment){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_COMMENT_DIALOG,
          data : data
      });
    },

    openAddSubmapDialog(coords, type){
      if(!coords || !type){
        console.error('No new submap data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_ADD_SUBMAP_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddSubmapDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_ADD_SUBMAP_DIALOG
      });
    },

    submitAddSubmapDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords || !data.name || !data.responsiblePerson){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_SUBMAP_DIALOG,
          data : data
      });
    },

    // a reference to existing submap is added
    createReferencedSubmap : function(refID, coords){
      if(!refID || !coords){
        console.error('missing data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_REFERENCED_SUBMAP,
          refID : refID,
          coords : coords
      });
    },

    openCreateSubmapDialog: function(data) {
      if (!data.mapID || !data.nodes || !data.comments) {
        console.error('not enough of data to create a submap', data.mapId, data.nodes, data.comments);
        return;
      }
      Dispatcher.dispatch({
        actionType: ACTION_TYPES.OPEN_CREATE_SUBMAP_FROM_SELECTED_NODES_DIALOG,
        data: data
      });
    },

    openEditCommentDialog: function(workspaceID, mapID, id, text){
      if(!workspaceID || !mapID || !id || !text){
        console.error('missing data', workspaceID, mapID, id, text);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_COMMENT_DIALOG,
          workspaceID : workspaceID,
          mapID : mapID,
          id : id,
          text : text
      });
    },

    closeEditCommentDialog: function(data){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_COMMENT_DIALOG
      });
    },

    submitEditGenericCommentDialog : function(data){
      if(!data || !data.id){
        console.error('missing id');
        return;
      }
      if(!data.text){
        console.error('missing data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_EDIT_COMMENT_DIALOG,
          data : data
      });
    },

    deleteComment: function(workspaceID, mapID, id){
      if(!workspaceID || !mapID || !id){
        console.error('missing data', workspaceID, mapID, id);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_COMMENT,
          workspaceID : workspaceID,
          mapID : mapID,
          id : id,
      });
    },

    updateComment: function(workspaceID, mapID, id, pos /*{pos:[x,y]}*/){
      if(!workspaceID || !mapID || !id || !pos || !pos.x || !pos.y){
        console.error('missing data', workspaceID, mapID, id, pos);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.MOVE_COMMENT,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            id: id,
            pos: pos
          }
      });
    },

    recordAction : function(workspaceID, mapID, sourceId, pos /*{pos: [x, y]} */){
      if(!sourceId || !pos){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.RECORD_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceId,
            pos: pos.pos
          }
      });
    },

    openEditActionDialog: function(workspaceID, mapID, sourceId, actionId, shortSummary, description){
      if(!sourceId || !actionId){
        console.error('no data to open the dialog');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_ACTION_DIALOG,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceId,
            actionId: actionId,
            shortSummary:shortSummary,
            description:description
          }
      });
    },

    closeEditActionDialog: function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_ACTION_DIALOG,
      });
    },

    updateAction: function(workspaceID, mapID, sourceID, actionID, pos, shortSummary, description) {
      if(!actionID){
        console.error('missing action id');
        return;
      }
      if(!(pos || shortSummary || description)){
        console.error('missing action data', pos, shortSummary, description);
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.UPDATE_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            pos : pos ? pos.pos : null,
            sourceId: sourceID,
            actionId: actionID,
            shortSummary:shortSummary,
            description:description
          }
      });
    },

    deleteAction: function(workspaceID, mapID, sourceID, actionID){
      if(!sourceID || !actionID){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceID,
            actionId: actionID
          }
      });
    },

    deleteNode: function(workspaceId, mapId, nodeId){
      if(!mapId || !nodeId){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_NODE,
          data: {
            workspaceId: workspaceId,
            mapId: mapId,
            nodeId: nodeId
          }
      });
    },

    updateNode: function(workspaceId, mapId, nodeId, pos,
      name, type, person, inertia, description){
      if(!nodeId){
        console.error('missing node id');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.UPDATE_NODE,
          data: {
            workspaceId: workspaceId,
            mapId: mapId,
            nodeId :nodeId,
            pos : pos ? pos : null,
            name,
            type,
            person,
            inertia,
            description
          }
      });
    },

    openEditNodeDialog: function(mapID, nodeID){
      if(!mapID || !nodeID){
        console.error('unspecified node');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_NODE_DIALOG,
          data : {
            nodeID : nodeID,
            mapID : mapID
          }
      });
    },

    recordConnection : function(workspaceId, mapId, sourceId, targetId){
      if(!workspaceId || !mapId || !sourceId || !targetId){
        console.error('not enough of data to create connection');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.RECORD_CONNECTION,
          data : {
            workspaceId : workspaceId,
            mapId : mapId,
            sourceId:sourceId,
            targetId:targetId
          }
      });
    },

    deleteConnection : function(workspaceId, mapId, sourceId, targetId){
      if(!workspaceId || !mapId || !sourceId || !targetId){
        console.error('not enough of data to create connection');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_CONNECTION,
          data : {
            workspaceId : workspaceId,
            mapId : mapId,
            sourceId:sourceId,
            targetId:targetId
          }
      });
    },

    openSubmapReferencesDialog: function(currentName, mapID, submapID, node, workspaceID){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SHOW_SUBMAP_REFERENCES,
          data : {
            currentName: currentName,
            mapID:mapID,
            submapID:submapID,
            node :node,
            workspaceID:workspaceID
          }
      });
    },

    closeSubmapReferencesDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_SUBMAP_REFERENCES,
      });
    },

    openReferencesDialog: function(currentName, node, workspaceID){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SHOW_REFERENCES,
          data : {
            currentName: currentName,
            node:node,
            workspaceID:workspaceID
          }
      });
    },

    closeReferencesDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_REFERENCES,
      });
    }

};

module.exports = SingleMapActions;
<commit_msg>Issue 84: Fix node edit dialog cancel<commit_after>/*jshint esversion: 6 */

import Dispatcher from '../dispatcher';
import Constants from './single-map-constants';

const ACTION_TYPES = Constants.ACTION_TYPES;
var SingleMapActions = {

    openEditMapDialog: function() {
        Dispatcher.dispatch({
            actionType: ACTION_TYPES.OPEN_EDIT_MAP_DIALOG
        });
    },

    closeEditMapDialog: function() {
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_MAP_DIALOG
      });
    },

    submitEditMapDialog: function(data) {
      if(!data){
        console.error('No map data, aborting...');
        return;
      }
      if(  !data.mapID || !data.responsiblePerson ||
        !((data.user && data.purpose) || data.name)){
        console.log('Incomplete map data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_EDIT_MAP_DIALOG,
          data : data
      });
    },

    openAddNodeDialog : function(coords, type){
      if(!coords || !type){
        console.error('No new node data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_NEW_NODE_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddNodeDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_NEW_NODE_DIALOG
      });
    },

    submitAddNodeDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords || !data.type){
        console.error('incomplete data, aborting', data);
        return;
      }
      if(!data.name || !data.responsiblePerson || !data.inertia || !data.description){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_NEW_NODE_DIALOG,
          data : data
      });
    },

    openAddCommentDialog(coords, type){
      if(!coords || !type){
        console.error('No new node data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_ADD_COMMENT_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddCommentDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_ADD_COMMENT_DIALOG
      });
    },

    submitAddCommentDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords){
        console.error('incomplete data, aborting', data);
        return;
      }
      if(!data.comment){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_COMMENT_DIALOG,
          data : data
      });
    },

    openAddSubmapDialog(coords, type){
      if(!coords || !type){
        console.error('No new submap data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_ADD_SUBMAP_DIALOG,
          coords : coords,
          type : type
      });
    },

    closeAddSubmapDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_ADD_SUBMAP_DIALOG
      });
    },

    submitAddSubmapDialog : function(data){
      if(!data){
        console.error('missing data, aborting...');
        return;
      }
      if(!data.coords || !data.name || !data.responsiblePerson){
        console.error('incomplete data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_SUBMAP_DIALOG,
          data : data
      });
    },

    // a reference to existing submap is added
    createReferencedSubmap : function(refID, coords){
      if(!refID || !coords){
        console.error('missing data, aborting...');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_ADD_REFERENCED_SUBMAP,
          refID : refID,
          coords : coords
      });
    },

    openCreateSubmapDialog: function(data) {
      if (!data.mapID || !data.nodes || !data.comments) {
        console.error('not enough of data to create a submap', data.mapId, data.nodes, data.comments);
        return;
      }
      Dispatcher.dispatch({
        actionType: ACTION_TYPES.OPEN_CREATE_SUBMAP_FROM_SELECTED_NODES_DIALOG,
        data: data
      });
    },

    openEditCommentDialog: function(workspaceID, mapID, id, text){
      if(!workspaceID || !mapID || !id || !text){
        console.error('missing data', workspaceID, mapID, id, text);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_COMMENT_DIALOG,
          workspaceID : workspaceID,
          mapID : mapID,
          id : id,
          text : text
      });
    },

    closeEditCommentDialog: function(data){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_COMMENT_DIALOG
      });
    },

    submitEditGenericCommentDialog : function(data){
      if(!data || !data.id){
        console.error('missing id');
        return;
      }
      if(!data.text){
        console.error('missing data', data);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SUBMIT_EDIT_COMMENT_DIALOG,
          data : data
      });
    },

    deleteComment: function(workspaceID, mapID, id){
      if(!workspaceID || !mapID || !id){
        console.error('missing data', workspaceID, mapID, id);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_COMMENT,
          workspaceID : workspaceID,
          mapID : mapID,
          id : id,
      });
    },

    updateComment: function(workspaceID, mapID, id, pos /*{pos:[x,y]}*/){
      if(!workspaceID || !mapID || !id || !pos || !pos.x || !pos.y){
        console.error('missing data', workspaceID, mapID, id, pos);
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.MOVE_COMMENT,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            id: id,
            pos: pos
          }
      });
    },

    recordAction : function(workspaceID, mapID, sourceId, pos /*{pos: [x, y]} */){
      if(!sourceId || !pos){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.RECORD_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceId,
            pos: pos.pos
          }
      });
    },

    openEditActionDialog: function(workspaceID, mapID, sourceId, actionId, shortSummary, description){
      if(!sourceId || !actionId){
        console.error('no data to open the dialog');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_ACTION_DIALOG,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceId,
            actionId: actionId,
            shortSummary:shortSummary,
            description:description
          }
      });
    },

    closeEditActionDialog: function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_ACTION_DIALOG,
      });
    },

    updateAction: function(workspaceID, mapID, sourceID, actionID, pos, shortSummary, description) {
      if(!actionID){
        console.error('missing action id');
        return;
      }
      if(!(pos || shortSummary || description)){
        console.error('missing action data', pos, shortSummary, description);
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.UPDATE_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            pos : pos ? pos.pos : null,
            sourceId: sourceID,
            actionId: actionID,
            shortSummary:shortSummary,
            description:description
          }
      });
    },

    deleteAction: function(workspaceID, mapID, sourceID, actionID){
      if(!sourceID || !actionID){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_ACTION,
          data: {
            workspaceID: workspaceID,
            mapID: mapID,
            sourceId: sourceID,
            actionId: actionID
          }
      });
    },

    deleteNode: function(workspaceId, mapId, nodeId){
      if(!mapId || !nodeId){
        console.error('missing data, aborting');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_NODE,
          data: {
            workspaceId: workspaceId,
            mapId: mapId,
            nodeId: nodeId
          }
      });
    },

    updateNode: function(workspaceId, mapId, nodeId, pos,
      name, type, person, inertia, description){
      if(!nodeId){
        console.error('missing node id');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.UPDATE_NODE,
          data: {
            workspaceId: workspaceId,
            mapId: mapId,
            nodeId :nodeId,
            pos : pos ? pos : null,
            name,
            type,
            person,
            inertia,
            description
          }
      });
    },

    openEditNodeDialog: function(mapID, nodeID){
      if(!mapID || !nodeID){
        console.error('unspecified node');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.OPEN_EDIT_NODE_DIALOG,
          data : {
            nodeID : nodeID,
            mapID : mapID
          }
      });
    },

    closeEditNodeDialog:  function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_EDIT_NODE_DIALOG
      });
    },

    recordConnection : function(workspaceId, mapId, sourceId, targetId){
      if(!workspaceId || !mapId || !sourceId || !targetId){
        console.error('not enough of data to create connection');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.RECORD_CONNECTION,
          data : {
            workspaceId : workspaceId,
            mapId : mapId,
            sourceId:sourceId,
            targetId:targetId
          }
      });
    },

    deleteConnection : function(workspaceId, mapId, sourceId, targetId){
      if(!workspaceId || !mapId || !sourceId || !targetId){
        console.error('not enough of data to create connection');
        return;
      }
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.DELETE_CONNECTION,
          data : {
            workspaceId : workspaceId,
            mapId : mapId,
            sourceId:sourceId,
            targetId:targetId
          }
      });
    },

    openSubmapReferencesDialog: function(currentName, mapID, submapID, node, workspaceID){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SHOW_SUBMAP_REFERENCES,
          data : {
            currentName: currentName,
            mapID:mapID,
            submapID:submapID,
            node :node,
            workspaceID:workspaceID
          }
      });
    },

    closeSubmapReferencesDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_SUBMAP_REFERENCES,
      });
    },

    openReferencesDialog: function(currentName, node, workspaceID){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.SHOW_REFERENCES,
          data : {
            currentName: currentName,
            node:node,
            workspaceID:workspaceID
          }
      });
    },

    closeReferencesDialog : function(){
      Dispatcher.dispatch({
          actionType: ACTION_TYPES.CLOSE_REFERENCES,
      });
    }

};

module.exports = SingleMapActions;
<|endoftext|>


<commit_before>var pcm_readouts = (function() {
    var readouts = [];

    var WIDTH = 115;
    var HEIGHT = 55;
    var SQ_SIZE = 25;
    var SQ_PAD = 5;
    var FONT = "12px sans-serif";

    $(window).on('load', function() {
        var parent = document.getElementById("pcm_readout_table");
        for (var i = 0; i < 2; i++) {
            var p = {
                can_id: -1,
                solenoids: [-2, -2, -2, -2, -2, -2, -2, -2],
                compr_current: -1
            };

            var tr = document.createElement("tr");
            tr.style.height = "55px";
            var td_port = document.createElement("td");
            td_port.innerHTML = "---";
            tr.appendChild(td_port);
            var td_comp_curr = document.createElement("td");
            td_port.innerHTML = "---";
            tr.appendChild(td_comp_curr);
            var td_solenoids = document.createElement("td");
            tr.appendChild(td_solenoids);

            var canvas = document.createElement("canvas");
            canvas.setAttribute("width", WIDTH);
            canvas.setAttribute("height", HEIGHT);
            td_solenoids.appendChild(canvas);
            parent.appendChild(tr);

            p._tr = tr;
            p._td_port = td_port;
            p._td_comp_curr = td_comp_curr;
            p._td_solenoids = td_solenoids;
            p.canvas = canvas;
            p.ctx = canvas.getContext("2d");

            p.setport = function(can_id) {
                this.can_id = can_id;
                this._td_port.innerHTML = can_id;
            };

            p.setcompressor = function(comp_current) {
                this.compr_current = comp_current;
                this._td_comp_curr.innerHTML = comp_current.toFixed(2) + "A";
            };

            p.set = function(id, solenoid, solenoid_black) {
                if (solenoid_black) {
                    this.solenoids[id] = -1;
                } else {
                    this.solenoids[id] = (solenoid ? 1 : 0);
                }
            };

            p.update = function(id, solenoid, solenoid_black) {
                this.set(id, solenoid, solenoid_black);
                this.draw();
            };

            p.draw = function() { draw(this); }
            p.draw();
            readouts[i] = p;
        }
    });

    function draw(obj) {
        obj.ctx.clearRect(0, 0, WIDTH, HEIGHT);

        var i = 0;
        for (var r = 0; r < 4; r++) {
            for (var c = 0; c < 2; c++) {
                var x = (r * SQ_SIZE + r * SQ_PAD);
                var y = (c * SQ_SIZE + c * SQ_PAD);
                var sol = obj.solenoids[i];

                if (sol == -2) {            // Not Registered
                    obj.ctx.fillStyle = COMMON.COL_GRY_10;
                } else if (sol == -1) {     // Blacklist
                    obj.ctx.fillStyle = COMMON.COL_GRY_80;
                } else if (sol == 0) {      // Off
                    obj.ctx.fillStyle = COMMON.COL_RED;
                } else if (sol == 1) {      // On
                    obj.ctx.fillStyle = COMMON.COL_GRN;
                }

                obj.ctx.fillRect(x, y, SQ_SIZE, SQ_SIZE);

                obj.ctx.font = FONT;
                if (sol == -2) {
                    obj.ctx.fillStyle = COMMON.COL_GRY_50;
                } else {
                    obj.ctx.fillStyle = "#FFF";
                }
                obj.ctx.textAlign = "center";
                obj.ctx.textBaseline = "middle";
                obj.ctx.fillText(i, x + SQ_SIZE / 2, y + SQ_SIZE / 2);
                i++;
            }
        }
    }

    return readouts;
})();<commit_msg>PCM Readout Order<commit_after>var pcm_readouts = (function() {
    var readouts = [];

    var WIDTH = 115;
    var HEIGHT = 55;
    var SQ_SIZE = 25;
    var SQ_PAD = 5;
    var FONT = "12px sans-serif";

    $(window).on('load', function() {
        var parent = document.getElementById("pcm_readout_table");
        for (var i = 0; i < 2; i++) {
            var p = {
                can_id: -1,
                solenoids: [-2, -2, -2, -2, -2, -2, -2, -2],
                compr_current: -1
            };

            var tr = document.createElement("tr");
            tr.style.height = "55px";
            var td_port = document.createElement("td");
            td_port.innerHTML = "---";
            tr.appendChild(td_port);
            var td_comp_curr = document.createElement("td");
            td_port.innerHTML = "---";
            tr.appendChild(td_comp_curr);
            var td_solenoids = document.createElement("td");
            tr.appendChild(td_solenoids);

            var canvas = document.createElement("canvas");
            canvas.setAttribute("width", WIDTH);
            canvas.setAttribute("height", HEIGHT);
            td_solenoids.appendChild(canvas);
            parent.appendChild(tr);

            p._tr = tr;
            p._td_port = td_port;
            p._td_comp_curr = td_comp_curr;
            p._td_solenoids = td_solenoids;
            p.canvas = canvas;
            p.ctx = canvas.getContext("2d");

            p.setport = function(can_id) {
                this.can_id = can_id;
                this._td_port.innerHTML = can_id;
            };

            p.setcompressor = function(comp_current) {
                this.compr_current = comp_current;
                this._td_comp_curr.innerHTML = comp_current.toFixed(2) + "A";
            };

            p.set = function(id, solenoid, solenoid_black) {
                if (solenoid_black) {
                    this.solenoids[id] = -1;
                } else {
                    this.solenoids[id] = (solenoid ? 1 : 0);
                }
            };

            p.update = function(id, solenoid, solenoid_black) {
                this.set(id, solenoid, solenoid_black);
                this.draw();
            };

            p.draw = function() { draw(this); }
            p.draw();
            readouts[i] = p;
        }
    });

    function draw(obj) {
        obj.ctx.clearRect(0, 0, WIDTH, HEIGHT);

        var i = 0;
        for (var c = 0; c < 2; c++) {
            for (var r = 0; r < 4; r++) {
                var x = (r * SQ_SIZE + r * SQ_PAD);
                var y = (c * SQ_SIZE + c * SQ_PAD);
                var sol = obj.solenoids[i];

                if (sol == -2) {            // Not Registered
                    obj.ctx.fillStyle = COMMON.COL_GRY_10;
                } else if (sol == -1) {     // Blacklist
                    obj.ctx.fillStyle = COMMON.COL_GRY_80;
                } else if (sol == 0) {      // Off
                    obj.ctx.fillStyle = COMMON.COL_RED;
                } else if (sol == 1) {      // On
                    obj.ctx.fillStyle = COMMON.COL_GRN;
                }

                obj.ctx.fillRect(x, y, SQ_SIZE, SQ_SIZE);

                obj.ctx.font = FONT;
                if (sol == -2) {
                    obj.ctx.fillStyle = COMMON.COL_GRY_50;
                } else {
                    obj.ctx.fillStyle = "#FFF";
                }
                obj.ctx.textAlign = "center";
                obj.ctx.textBaseline = "middle";
                obj.ctx.fillText(i, x + SQ_SIZE / 2, y + SQ_SIZE / 2);
                i++;
            }
        }
    }

    return readouts;
})();<|endoftext|>


<commit_before>import React from 'react';

import { emallson } from 'CONTRIBUTORS';
import ITEMS from 'common/ITEMS';
import ItemLink from 'common/ItemLink';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';

export default [
  {
    date: new Date('2018-09-13'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.ELUSIVE_FOOTWORK.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-08-11'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.STAGGERING_STRIKES.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-22'),
    changes: <React.Fragment>Updated support for <ItemLink id={ITEMS.SOUL_OF_THE_GRANDMASTER.id} /> and temporarily disabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module pending new formula coefficients.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-18'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.LIGHT_BREWING_TALENT.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-15'),
    changes: <React.Fragment>Added <SpellLink id={SPELLS.TRAINING_OF_NIUZAO.id} /> support.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-06-16'),
    changes: <React.Fragment>Updated <SpellLink id={SPELLS.IRONSKIN_BREW.id} /> cooldown and duration and added <SpellLink id={SPELLS.GUARD_TALENT.id} />, along with other changes in beta build 26812.</React.Fragment>,
    contributors: [emallson],
  },
];
<commit_msg>added changelog entry for FtB<commit_after>import React from 'react';

import { emallson } from 'CONTRIBUTORS';
import ITEMS from 'common/ITEMS';
import ItemLink from 'common/ItemLink';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';

export default [
  {
    date: new Date('2018-09-22'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.FIT_TO_BURST.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-09-13'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.ELUSIVE_FOOTWORK.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-08-11'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.STAGGERING_STRIKES.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-22'),
    changes: <React.Fragment>Updated support for <ItemLink id={ITEMS.SOUL_OF_THE_GRANDMASTER.id} /> and temporarily disabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module pending new formula coefficients.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-18'),
    changes: <React.Fragment>Added support for <SpellLink id={SPELLS.LIGHT_BREWING_TALENT.id} />.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-07-15'),
    changes: <React.Fragment>Added <SpellLink id={SPELLS.TRAINING_OF_NIUZAO.id} /> support.</React.Fragment>,
    contributors: [emallson],
  },
  {
    date: new Date('2018-06-16'),
    changes: <React.Fragment>Updated <SpellLink id={SPELLS.IRONSKIN_BREW.id} /> cooldown and duration and added <SpellLink id={SPELLS.GUARD_TALENT.id} />, along with other changes in beta build 26812.</React.Fragment>,
    contributors: [emallson],
  },
];
<|endoftext|>


<commit_before>import chai from "chai";// eslint-disable-line import/no-extraneous-dependencies
import SideMenuItem from "sidemenu/SideMenuItem";// eslint-disable-line import/no-extraneous-dependencies,import/no-unresolved
import TestUtils from "../TestUtils";

describe("sidemenu/SideMenuItem", () => {
    const props = {
        item: {
            text: "Manager",
            path: "app/modules/Manager",
            module: "Manager",
            icon: "fa-cogs",
            items: [
                {
                    text: "Parameters",
                    path: "app/modules/Parameters",
                    module: "Parameters",
                    icon: "fa-tachometer"
                }, {
                    text: "Parameters2",
                    path: "app/modules/Parameters2",
                    module: "Parameters2",
                    icon: "fa-tachometer"
                }]
        },
        onChange: () => { }
    };
    const item = TestUtils.mount(props, SideMenuItem, props);

    it("render", () => {
        let li = item.find(".SideMenu-item");
        chai.assert.isTrue(li.hasClass("SideMenu-item"), "initial class must be SideMenu-item");
        chai.assert.isTrue(li.find("i").hasClass(props.item.icon),
            "fa icon class must be same with the 'props.item.icon'.");

        chai.assert.equal(li.text(), props.item.text, "li text must be same with the 'props.item.text'");

        let ul = item.find(".out");

        chai.assert.equal(ul.find(".SideMenu-subitem").length, props.item.items.length,
            "It must be same child count with 'props.item.items.length'");
    });

    it("onClick", () => {
        let li = item.find(".SideMenu-item");
        chai.assert.isTrue(li.hasClass("SideMenu-item"), "initial class must be SideMenu-item");
        chai.assert.isDefined(item.find(".out").node, "Pre-click out must be defined");

        li.simulate("click");
        chai.assert.isTrue(li.hasClass("SideMenu-item-active"),
            "Post-click class must be SideMenu-item-active");
        chai.assert.isUndefined(item.find(".out").node, "Post-click out must be undefined");
        chai.assert.isDefined(item.find(".in").node, "Post-click in must be defined");

        let ul = item.find(".in");
        chai.assert.equal(ul.find(".SideMenu-subitem").length, props.item.items.length,
            "It must be same child count with 'props.item.items.length'");
    });

    it("componentDidMount", () => {
        props.selectedItem = props.item.path;
        const itemSelected = TestUtils.mount(props, SideMenuItem, props);

        chai.assert.isTrue(itemSelected.find(".SideMenu-item").hasClass("SideMenu-item-active"),
            "If 'props.selectedItem' is ending with 'props.item.module' class must be SideMenu-item-active");
        itemSelected.find(".SideMenu-item").simulate("click");
        chai.assert.isTrue(itemSelected.find(".SideMenu-item").hasClass("SideMenu-item-active"),
            "After Second click class must be SideMenu-item-active");
    });

    it("onChange", () => {
        props.selectedItem = props.item.path;
        const itemSelected = TestUtils.mount(props, SideMenuItem, props);

        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length);
        itemSelected.find(".SideMenu-item").simulate("click");
        itemSelected.find(".SideMenu-subitem").first().find("div").simulate("click");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length - 1, "Post-Click Non active Subitem lengthmust be 1 less than 'props.item.items.length'");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").length, 1);
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").find("div").text(), "Parameters");

        itemSelected.find(".SideMenu-subitem").last().find("div").simulate("click");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length - 1, "Post-Click Non active Subitem lengthmust be 1 less than 'props.item.items.length'");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").length, 1);
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").find("div").text(), "Parameters2");
    });
});
<commit_msg>SideMenu Test fixed.<commit_after>import chai from "chai";// eslint-disable-line import/no-extraneous-dependencies
import SideMenuItem from "sidemenu/SideMenuItem";// eslint-disable-line import/no-extraneous-dependencies,import/no-unresolved
import TestUtils from "../TestUtils";
import {
    Collapse
} from "react-bootstrap";

describe("sidemenu/SideMenuItem", () => {
    const props = {
        item: {
            text: "Manager",
            path: "app/modules/Manager",
            module: "Manager",
            icon: "fa-cogs",
            items: [
                {
                    text: "Parameters",
                    path: "app/modules/Parameters",
                    module: "Parameters",
                    icon: "fa-tachometer"
                }, {
                    text: "Parameters2",
                    path: "app/modules/Parameters2",
                    module: "Parameters2",
                    icon: "fa-tachometer"
                }]
        },
        onChange: () => { }
    };
    const item = TestUtils.mount(props, SideMenuItem, props);

    it("render", () => {
        let li = item.find(".SideMenu-item");
        chai.assert.isTrue(li.hasClass("SideMenu-item"), "initial class must be SideMenu-item");
        chai.assert.isTrue(li.find("i").hasClass(props.item.icon),
            "fa icon class must be same with the 'props.item.icon'.");
        chai.assert.equal(li.text(), props.item.text, "li text must be same with the 'props.item.text'");
        let ul = item.find("ul");
        chai.assert.equal(ul.find("li").length, props.item.items.length,
            "It must be same child count with 'props.item.items.length'");
    });

    it("onClick", () => {
        let li = item.find(".SideMenu-item");
        chai.assert.isTrue(li.hasClass("SideMenu-item"), "initial class must be SideMenu-item");
        chai.assert.isFalse(item.find(Collapse).prop("in"), "Pre-Click must be collapsed");
        li.simulate("click");
        chai.assert.isTrue(li.hasClass("SideMenu-item-active"),
            "Post-click class must be SideMenu-item-active");
        chai.assert.isTrue(item.find(Collapse).prop("in"), "Post-Click must be expanded");
        let ul = item.find(Collapse);
        chai.assert.equal(ul.find("li").length, props.item.items.length,
            "It must be same child count with 'props.item.items.length'");
    });

    it("componentDidMount", () => {
        props.selectedItem = props.item.path;
        const itemSelected = TestUtils.mount(props, SideMenuItem, props);

        chai.assert.isTrue(itemSelected.find(".SideMenu-item").hasClass("SideMenu-item-active"),
            "If 'props.selectedItem' is ending with 'props.item.module' class must be SideMenu-item-active");
        itemSelected.find(".SideMenu-item").simulate("click");
        chai.assert.isTrue(itemSelected.find(".SideMenu-item").hasClass("SideMenu-item-active"),
            "After Second click class must be SideMenu-item-active");
    });

    it("onChange", () => {
        props.selectedItem = props.item.path;
        const itemSelected = TestUtils.mount(props, SideMenuItem, props);

        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length);
        itemSelected.find(".SideMenu-item").simulate("click");
        itemSelected.find(".SideMenu-subitem").first().find("div").simulate("click");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length - 1, "Post-Click Non active Subitem lengthmust be 1 less than 'props.item.items.length'");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").length, 1);
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").find("div").text(), "Parameters");

        itemSelected.find(".SideMenu-subitem").last().find("div").simulate("click");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem").length, props.item.items.length - 1, "Post-Click Non active Subitem lengthmust be 1 less than 'props.item.items.length'");
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").length, 1);
        chai.assert.equal(itemSelected.find(".SideMenu-subitem-active").find("div").text(), "Parameters2");
    });
});
<|endoftext|>