mirror of
https://github.com/ENSL/ensl_gathers.git
synced 2024-11-22 12:41:11 +00:00
A lot of changes.....
This commit is contained in:
parent
cf2b9643fb
commit
9515c8c6f7
19 changed files with 2512 additions and 961 deletions
21
gulpfile.js
Normal file
21
gulpfile.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
"use strict";
|
||||
|
||||
var gulp = require("gulp");
|
||||
var react = require("gulp-react");
|
||||
var concat = require("gulp-concat");
|
||||
var watch = require("gulp-watch");
|
||||
var plumber = require("gulp-plumber");
|
||||
|
||||
gulp.task('default', ['compile']);
|
||||
|
||||
gulp.task('compile', function () {
|
||||
return gulp.src('lib/react/**')
|
||||
.pipe(plumber())
|
||||
.pipe(concat('app.js'))
|
||||
.pipe(react())
|
||||
.pipe(gulp.dest('public/js/'));
|
||||
});
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch('lib/react/**', ['compile']);
|
||||
});
|
|
@ -53,7 +53,11 @@ async.parallel(instructions, function (error) {
|
|||
console.log("Error while adding gatherers", error);
|
||||
} else {
|
||||
console.log("Loaded gatherers");
|
||||
|
||||
gather.gatherers.forEach(function (gatherer, index, array) {
|
||||
var candidate = Math.floor(Math.random() * array.length);
|
||||
array[index].leaderVote = array[candidate].id;
|
||||
});
|
||||
console.log("Assigned vote for each gatherer");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -65,7 +69,7 @@ module.exports = function (namespace) {
|
|||
namespace.sockets.forEach(function (socket) {
|
||||
socket.emit("gather:refresh", {
|
||||
gather: gather.toJson(),
|
||||
currentUser: socket._user
|
||||
currentGatherer: gather.getGatherer(socket._user)
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -164,6 +164,14 @@ Gather.prototype.voteForLeader = function (voter, candidate) {
|
|||
});
|
||||
};
|
||||
|
||||
Gather.prototype.getGatherer = function (user) {
|
||||
var matchingGatherer = null;
|
||||
this.gatherers.forEach(function (gatherer) {
|
||||
if (gatherer.id === user.id) matchingGatherer = gatherer;
|
||||
});
|
||||
return matchingGatherer;
|
||||
};
|
||||
|
||||
// Gather States
|
||||
// - Gathering
|
||||
// - Election
|
||||
|
|
|
@ -1,573 +0,0 @@
|
|||
$(function () {
|
||||
|
||||
"use strict";
|
||||
|
||||
var UserCounter = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<li>
|
||||
<a href="#">
|
||||
<i className="fa fa-users fa-fw"></i> Online
|
||||
<span className="badge add-left"> {this.props.count} </span>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var UserLogin = React.createClass({
|
||||
authorizeId: function (id) {
|
||||
id = parseInt(id, 10);
|
||||
socket.emit("users:authorize", {
|
||||
id: id
|
||||
});
|
||||
},
|
||||
handleSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
var id = React.findDOMNode(this.refs.authorize_id).value.trim();
|
||||
if (!id) return;
|
||||
React.findDOMNode(this.refs.authorize_id).value = '';
|
||||
this.authorizeId(id);
|
||||
return;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit} >
|
||||
<div className="input-group signin">
|
||||
<input
|
||||
id="btn-input"
|
||||
type="text"
|
||||
className="form-control"
|
||||
ref="authorize_id"
|
||||
placeholder="Choose an ID..." />
|
||||
<span className="input-group-btn">
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary"
|
||||
id="btn-chat"
|
||||
value="Login" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="signin">
|
||||
<p className="text-center"><small>Just a temporary measure until genuine authentication is implemented</small></p>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
var UserMenu = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
count: 0,
|
||||
users: []
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
socket.on('users:update', this.updateUsers);
|
||||
},
|
||||
updateUsers: function (data) {
|
||||
this.setProps({
|
||||
count: data.count,
|
||||
users: data.users
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var users = this.props.users.map(function (user) {
|
||||
return (
|
||||
<li key={user.id}><a href="#">{user.username}</a></li>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<ul className="nav" id="side-menu">
|
||||
<UserCounter {...this.props} />
|
||||
{users}
|
||||
<li><br /><UserLogin /><br /></li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Chatroom = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
history: []
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
var TIMER_INTERVAL = 60000; // Every minute
|
||||
|
||||
socket.on("message:new", function (data) {
|
||||
var history = self.props.history;
|
||||
history.push(data);
|
||||
self.setProps({
|
||||
history: history
|
||||
});
|
||||
self.scrollToBottom();
|
||||
});
|
||||
|
||||
// Message History Retrieved
|
||||
socket.on("message:refresh", function (data) {
|
||||
self.setProps({
|
||||
history: data.chatHistory
|
||||
});
|
||||
self.scrollToBottom();
|
||||
});
|
||||
|
||||
socket.emit("message:refresh", {});
|
||||
|
||||
self.timer = setInterval(function () {
|
||||
if (self.refs.messages) self.refs.messages.refreshTime();
|
||||
}, TIMER_INTERVAL);
|
||||
},
|
||||
|
||||
componentDidUnmount: function () {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
sendMessage: function (message) {
|
||||
socket.emit("newMessage", {message: message});
|
||||
},
|
||||
scrollToBottom: function () {
|
||||
var node = React.findDOMNode(this.refs.messageContainer);
|
||||
node.scrollTop = node.scrollHeight;
|
||||
},
|
||||
render: function () {
|
||||
var messages = this.props.history.map(function (message) {
|
||||
return (
|
||||
<ChatMessage
|
||||
avatar={message.author.avatar}
|
||||
username={message.author.username}
|
||||
content={message.content}
|
||||
ref="messages"
|
||||
createdAt={message.createdAt} />
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">Gather Chat</div>
|
||||
<div className="panel-body">
|
||||
<ul className="chat" id="chatmessages" ref="messageContainer">
|
||||
{messages}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="panel-footer">
|
||||
<MessageBar />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ChatMessage = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
timeAgo: $.timeago(this.props.createdAt)
|
||||
}
|
||||
},
|
||||
refreshTime: function () {
|
||||
var self = this;
|
||||
self.setState({
|
||||
timeAgo: $.timeago(self.props.createdAt)
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<li className="left clearfix">
|
||||
<span className="chat-img pull-left">
|
||||
<img
|
||||
src={this.props.avatar}
|
||||
alt="User Avatar"
|
||||
height="40"
|
||||
width="40"
|
||||
className="img-circle" />
|
||||
</span>
|
||||
<div className="chat-body clearfix">
|
||||
<div className="header">
|
||||
<strong className="primary-font">{this.props.username}</strong>
|
||||
<small className="pull-right text-muted">
|
||||
<i className="fa fa-clock-o fa-fw"></i> {this.state.timeAgo}
|
||||
</small>
|
||||
</div>
|
||||
<p>{this.props.content}</p>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CurrentUser = React.createClass({
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
socket.on("users:update", function (data) {
|
||||
self.setProps({
|
||||
user: data.currentUser
|
||||
});
|
||||
});
|
||||
socket.emit("users:refresh", {});
|
||||
},
|
||||
render: function () {
|
||||
if (this.props.user) {
|
||||
return (
|
||||
<a href="#">{this.props.user.username} <img src={this.props.user.avatar}
|
||||
alt="User Avatar"
|
||||
height="20"
|
||||
width="20" /></a>
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var VoteButton = React.createClass({
|
||||
cancelVote: function (e) {
|
||||
socket.emit("gather:vote", {
|
||||
leader: {
|
||||
candidate: null
|
||||
}
|
||||
});
|
||||
},
|
||||
vote: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:vote", {
|
||||
leader: {
|
||||
candidate: parseInt(e.target.value, 10)
|
||||
}
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
if (this.props.currentGatherer === null) {
|
||||
return false;
|
||||
}
|
||||
if (this.props.currentGatherer.leaderVote === this.props.candidate.id) {
|
||||
return (
|
||||
<button
|
||||
onClick={this.cancelVote}
|
||||
className="btn btn-xs btn-success">Voted
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button
|
||||
onClick={this.vote}
|
||||
className="btn btn-xs btn-default"
|
||||
value={this.props.candidate.id}>Vote
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var MessageBar = React.createClass({
|
||||
sendMessage: function (content) {
|
||||
socket.emit("message:new", {
|
||||
content: content
|
||||
});
|
||||
},
|
||||
handleSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
var content = React.findDOMNode(this.refs.content).value.trim();
|
||||
if (!content) return;
|
||||
React.findDOMNode(this.refs.content).value = '';
|
||||
this.sendMessage(content);
|
||||
return;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit} >
|
||||
<div className="input-group">
|
||||
<input
|
||||
id="btn-input"
|
||||
type="text"
|
||||
className="form-control"
|
||||
ref="content"
|
||||
placeholder="Be polite please..." />
|
||||
<span className="input-group-btn">
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary"
|
||||
id="btn-chat"
|
||||
value="Send" />
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var JoinGatherButton = React.createClass({
|
||||
joinGather: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:join", {});
|
||||
},
|
||||
render: function () {
|
||||
var message = this.props.buttonName || "Join Gather";
|
||||
var buttonClass = "btn btn-primary";
|
||||
if (this.props.buttonClass) {
|
||||
buttonClass += " " + this.props.buttonClass;
|
||||
}
|
||||
return (<button
|
||||
onClick={this.joinGather}
|
||||
className={buttonClass}>{message}</button>)
|
||||
}
|
||||
});
|
||||
|
||||
var GatherProgress = React.createClass({
|
||||
gatheringProgress: function () {
|
||||
var num = this.props.gather.gatherers.length;
|
||||
var den = 12;
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: num + " / " + den
|
||||
};
|
||||
},
|
||||
electionProgress: function () {
|
||||
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
|
||||
if (gatherer.leaderVote) acc++;
|
||||
return acc;
|
||||
}, 0);
|
||||
var den = 12;
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: den - num + " more votes required"
|
||||
};
|
||||
},
|
||||
selectionProgress: function () {
|
||||
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
|
||||
if (gatherer.team !== "lobby") acc++;
|
||||
return acc;
|
||||
}, 0);
|
||||
var den = 12;
|
||||
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: num + " out of " + den + " players assigned"
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var progress;
|
||||
var gatherState = this.props.gather.state;
|
||||
if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
|
||||
progress = this.gatheringProgress();
|
||||
} else if (gatherState === 'election') {
|
||||
progress = this.electionProgress();
|
||||
} else if (gatherState === 'selection') {
|
||||
progress = this.selectionProgress();
|
||||
}
|
||||
if (progress) {
|
||||
var style = {
|
||||
width: Math.round((progress.num / progress.den * 100)) + "%"
|
||||
};
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<p>Gather Progress</p>
|
||||
<div className="progress">
|
||||
<div className="progress-bar progress-bar-striped active"
|
||||
data-role="progressbar"
|
||||
data-aria-valuenow={progress.num}
|
||||
data-aria-valuemin="0"
|
||||
data-aria-valuemax={progress.den}
|
||||
style={style}>
|
||||
{progress.message}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var Gather = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
gather: {
|
||||
gatherers: []
|
||||
}
|
||||
}
|
||||
},
|
||||
joinedGather: function () {
|
||||
var self = this;
|
||||
return this.props.gather.gatherers.some(function (gatherer) {
|
||||
return gatherer.user.id === self.props.currentUser.id;
|
||||
});
|
||||
},
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
socket.on("gather:refresh", function (data) {
|
||||
self.setProps({
|
||||
gather: data.gather,
|
||||
currentUser: data.currentUser
|
||||
});
|
||||
});
|
||||
},
|
||||
stateDescription: function () {
|
||||
switch(this.props.gather.state) {
|
||||
case "gathering":
|
||||
return "Waiting for more gatherers";
|
||||
case "election":
|
||||
return "Currently voting for team leaders";
|
||||
case "selection":
|
||||
return "Waiting for leaders to picking teams";
|
||||
case "done":
|
||||
return "Gather completed";
|
||||
default:
|
||||
return "Initialising gather";
|
||||
}
|
||||
},
|
||||
leaveGather: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:leave", {});
|
||||
},
|
||||
inviteToGather: function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
currentGatherer: function () {
|
||||
var current = null;
|
||||
var self = this;
|
||||
this.props.gather.gatherers.forEach(function (gatherer) {
|
||||
if (gatherer.id === self.props.currentUser.id) current = gatherer;
|
||||
});
|
||||
return current;
|
||||
},
|
||||
render: function () {
|
||||
var joinButton;
|
||||
if (this.joinedGather()) {
|
||||
joinButton = (<li><button
|
||||
onClick={this.leaveGather}
|
||||
className="btn btn-danger">Leave Gather</button></li>);
|
||||
} else {
|
||||
joinButton = (<li><JoinGatherButton /></li>);
|
||||
}
|
||||
var inviteButton;
|
||||
if (this.props.gather.state === 'gathering') {
|
||||
inviteButton = (<li><button
|
||||
onClick={this.inviteToGather}
|
||||
className="btn btn-primary">Invite to Gather</button></li>);
|
||||
}
|
||||
return (
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
<strong>NS2 Gather </strong>
|
||||
<span className="badge add-left">{this.props.gather.gatherers.length}</span>
|
||||
<br />
|
||||
{this.stateDescription()}
|
||||
</div>
|
||||
<Gatherers gather={this.props.gather} currentGatherer={this.currentGatherer()} />
|
||||
<GatherProgress gather={this.props.gather} />
|
||||
<div className="panel-footer text-right">
|
||||
<ul className="list-inline">
|
||||
{inviteButton}
|
||||
{joinButton}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var LeaderPoll = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<div className="panel-body">
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Gatherers = React.createClass({
|
||||
render: function () {
|
||||
var self = this;
|
||||
var gatherers = this.props.gather.gatherers.map(function (gatherer) {
|
||||
var lifeforms = (
|
||||
gatherer.user.ability.lifeforms.map(function (lifeform) {
|
||||
return (<span className="label label-default">{lifeform}</span>);
|
||||
})
|
||||
);
|
||||
|
||||
var commBadge;
|
||||
if (gatherer.user.ability.commander) {
|
||||
commBadge = (<img src="/images/commander.png"
|
||||
alt="Commander"
|
||||
height="20"
|
||||
width="20" />);
|
||||
}
|
||||
|
||||
var division = (<span className="label label-primary">{gatherer.user.ability.division}</span>);
|
||||
var action = lifeforms;
|
||||
if (self.props.gather.state === "election") {
|
||||
var votes = self.props.gather.gatherers.reduce(function (acc, voter) {
|
||||
if (voter.leaderVote === gatherer.id) acc++;
|
||||
return acc;
|
||||
}, 0)
|
||||
action = (
|
||||
<div className="text-right">
|
||||
<small>{votes + " votes"} </small>
|
||||
|
||||
<VoteButton currentGatherer={self.props.currentGatherer} candidate={gatherer} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<tr key={gatherer.user.id}>
|
||||
<td className="col-md-1">{commBadge}</td>
|
||||
<td className="col-md-5">{gatherer.user.username}</td>
|
||||
<td className="col-md-3">{division} </td>
|
||||
<td className="col-md-2">{action} </td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
if (this.props.gather.gatherers.length) {
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
<h5 className="panel-title">Roster</h5>
|
||||
</div>
|
||||
<table className="table roster-table">
|
||||
<tbody>
|
||||
{gatherers}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (<div className="panel-body text-center"><JoinGatherButton buttonClass="btn-lg" buttonName="Start a Gather" /></div>);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var socket;
|
||||
|
||||
function initialiseComponents () {
|
||||
var socketUrl = window.location.protocol + "//" + window.location.host;
|
||||
socket = io(socketUrl)
|
||||
.on("connect", function () {
|
||||
console.log("Connected");
|
||||
})
|
||||
.on("reconnect", function () {
|
||||
console.log("Reconnected");
|
||||
})
|
||||
.on("disconnect", function () {
|
||||
console.log("Disconnected")
|
||||
});
|
||||
|
||||
React.render(<UserMenu />, document.getElementById('side-menu'));
|
||||
React.render(<Chatroom />, document.getElementById('chatroom'));
|
||||
React.render(<Gather />, document.getElementById('gathers'));
|
||||
React.render(<CurrentUser />, document.getElementById('currentuser'));
|
||||
};
|
||||
|
||||
initialiseComponents();
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
354
lib/react/gather.jsx
Normal file
354
lib/react/gather.jsx
Normal file
|
@ -0,0 +1,354 @@
|
|||
"use strict";
|
||||
|
||||
var VoteButton = React.createClass({
|
||||
cancelVote: function (e) {
|
||||
socket.emit("gather:vote", {
|
||||
leader: {
|
||||
candidate: null
|
||||
}
|
||||
});
|
||||
},
|
||||
vote: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:vote", {
|
||||
leader: {
|
||||
candidate: parseInt(e.target.value, 10)
|
||||
}
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
if (this.props.currentGatherer === null) {
|
||||
return false;
|
||||
}
|
||||
if (this.props.currentGatherer.leaderVote === this.props.candidate.id) {
|
||||
return (
|
||||
<button
|
||||
onClick={this.cancelVote}
|
||||
className="btn btn-xs btn-success">Voted
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button
|
||||
onClick={this.vote}
|
||||
className="btn btn-xs btn-default"
|
||||
value={this.props.candidate.id}>Vote
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var JoinGatherButton = React.createClass({
|
||||
joinGather: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:join", {});
|
||||
},
|
||||
render: function () {
|
||||
var message = this.props.buttonName || "Join Gather";
|
||||
var buttonClass = "btn btn-primary";
|
||||
if (this.props.buttonClass) {
|
||||
buttonClass += " " + this.props.buttonClass;
|
||||
}
|
||||
return (<button
|
||||
onClick={this.joinGather}
|
||||
className={buttonClass}>{message}</button>)
|
||||
}
|
||||
});
|
||||
|
||||
var SelectPlayerButton = React.createClass({
|
||||
selectPlayer: function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
render: function () {
|
||||
if (!this.props.currentGatherer.leader) {
|
||||
return false;
|
||||
} else {
|
||||
return (<button
|
||||
onClick={this.selectPlayer}
|
||||
className="btn btn-xs btn-primary"> Select
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
var GatherTeams = React.createClass({
|
||||
alienGatherers: function () {
|
||||
return this.props.gather.gatherers.filter(function (gatherer) {
|
||||
return gatherer.team === "alien";
|
||||
}).sort(function (gatherer) {
|
||||
return (gatherer.leader) ? 1 : 0;
|
||||
});
|
||||
},
|
||||
marineGatherers: function () {
|
||||
return this.props.gather.gatherers.filter(function (gatherer) {
|
||||
return gatherer.team === "marine";
|
||||
}).sort(function (gatherer) {
|
||||
return (gatherer.leader) ? 1 : 0;
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var extractGatherer = function (gatherer) {
|
||||
var image;
|
||||
if (gatherer.leader) {
|
||||
image = (<img src="/images/commander.png"
|
||||
alt="Commander"
|
||||
height="20"
|
||||
width="20" />);
|
||||
}
|
||||
return (
|
||||
<tr key={gatherer.id}>
|
||||
<td className="col-md-1">{image}</td>
|
||||
<td className="col-md-11">{gatherer.user.username}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
var marines = this.marineGatherers().map(extractGatherer);
|
||||
var aliens = this.alienGatherers().map(extractGatherer);
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
Aliens
|
||||
</div>
|
||||
<table className="table">
|
||||
<tbody>
|
||||
{aliens}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
Marines
|
||||
</div>
|
||||
<table className="table">
|
||||
<tbody>
|
||||
{marines}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
var GatherProgress = React.createClass({
|
||||
stateDescription: function () {
|
||||
switch(this.props.gather.state) {
|
||||
case "gathering":
|
||||
return "Waiting for more gatherers.";
|
||||
case "election":
|
||||
return "Currently voting for team leaders.";
|
||||
case "selection":
|
||||
return "Waiting for leaders to picking teams.";
|
||||
case "done":
|
||||
return "Gather completed.";
|
||||
default:
|
||||
return "Initialising gather.";
|
||||
}
|
||||
},
|
||||
gatheringProgress: function () {
|
||||
var num = this.props.gather.gatherers.length;
|
||||
var den = 12;
|
||||
var remaining = den - num;
|
||||
var message = (remaining === 1) ? "Waiting for last player" : "Waiting for " + remaining + " more players";
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: message
|
||||
};
|
||||
},
|
||||
electionProgress: function () {
|
||||
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
|
||||
if (gatherer.leaderVote) acc++;
|
||||
return acc;
|
||||
}, 0);
|
||||
var den = 12;
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: den - num + " more votes required"
|
||||
};
|
||||
},
|
||||
selectionProgress: function () {
|
||||
var num = this.props.gather.gatherers.reduce(function (acc, gatherer) {
|
||||
if (gatherer.team !== "lobby") acc++;
|
||||
return acc;
|
||||
}, 0);
|
||||
var den = 12;
|
||||
|
||||
return {
|
||||
num: num,
|
||||
den: den,
|
||||
message: num + " out of " + den + " players assigned"
|
||||
};
|
||||
},
|
||||
render: function () {
|
||||
var progress;
|
||||
var gatherState = this.props.gather.state;
|
||||
if (gatherState === 'gathering' && this.props.gather.gatherers.length) {
|
||||
progress = this.gatheringProgress();
|
||||
} else if (gatherState === 'election') {
|
||||
progress = this.electionProgress();
|
||||
} else if (gatherState === 'selection') {
|
||||
progress = this.selectionProgress();
|
||||
}
|
||||
if (progress) {
|
||||
var style = {
|
||||
width: Math.round((progress.num / progress.den * 100)) + "%"
|
||||
};
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<p><strong>{this.stateDescription()}</strong> {progress.message}</p>
|
||||
<div className="progress">
|
||||
<div className="progress-bar progress-bar-striped active"
|
||||
data-role="progressbar"
|
||||
data-aria-valuenow={progress.num}
|
||||
data-aria-valuemin="0"
|
||||
data-aria-valuemax={progress.den}
|
||||
style={style}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var Gather = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
gather: {
|
||||
gatherers: []
|
||||
}
|
||||
}
|
||||
},
|
||||
joinedGather: function () {
|
||||
return this.props.currentGatherer !== null;
|
||||
},
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
socket.on("gather:refresh", function (data) {
|
||||
self.setProps({
|
||||
gather: data.gather,
|
||||
currentGatherer: data.currentGatherer
|
||||
});
|
||||
});
|
||||
},
|
||||
leaveGather: function (e) {
|
||||
e.preventDefault();
|
||||
socket.emit("gather:leave", {});
|
||||
},
|
||||
inviteToGather: function (e) {
|
||||
e.preventDefault();
|
||||
},
|
||||
render: function () {
|
||||
var joinButton;
|
||||
if (this.joinedGather()) {
|
||||
joinButton = (<li><button
|
||||
onClick={this.leaveGather}
|
||||
className="btn btn-danger">Leave Gather</button></li>);
|
||||
} else {
|
||||
joinButton = (<li><JoinGatherButton /></li>);
|
||||
}
|
||||
var inviteButton;
|
||||
if (this.props.gather.state === 'gathering') {
|
||||
inviteButton = (<li><button
|
||||
onClick={this.inviteToGather}
|
||||
className="btn btn-primary">Invite to Gather</button></li>);
|
||||
}
|
||||
var gatherTeams;
|
||||
if (this.props.gather.state === 'selection') {
|
||||
gatherTeams = <GatherTeams gather={this.props.gather} />
|
||||
}
|
||||
return (
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
<strong>NS2 Gather </strong>
|
||||
<span className="badge add-left">{this.props.gather.gatherers.length}</span>
|
||||
</div>
|
||||
<Gatherers gather={this.props.gather} currentGatherer={this.props.currentGatherer} />
|
||||
{gatherTeams}
|
||||
<GatherProgress gather={this.props.gather} />
|
||||
<div className="panel-footer text-right">
|
||||
<ul className="list-inline">
|
||||
{inviteButton}
|
||||
{joinButton}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Gatherers = React.createClass({
|
||||
render: function () {
|
||||
var self = this;
|
||||
var gatherers = this.props.gather.gatherers.map(function (gatherer) {
|
||||
var lifeforms = (
|
||||
gatherer.user.ability.lifeforms.map(function (lifeform) {
|
||||
return (<span className="label label-default">{lifeform}</span>);
|
||||
})
|
||||
);
|
||||
|
||||
// Switch this to online status
|
||||
var online= (<span src="/images/commander.png"
|
||||
alt="online"
|
||||
className="user-online"> </span>);
|
||||
|
||||
var division = (<span className="label label-primary">{gatherer.user.ability.division}</span>);
|
||||
var action = lifeforms;
|
||||
if (self.props.gather.state === "election") {
|
||||
var votes = self.props.gather.gatherers.reduce(function (acc, voter) {
|
||||
if (voter.leaderVote === gatherer.id) acc++;
|
||||
return acc;
|
||||
}, 0)
|
||||
action = (
|
||||
<span>
|
||||
<small>{votes + " votes"} </small>
|
||||
<VoteButton currentGatherer={self.props.currentGatherer} candidate={gatherer} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<tr key={gatherer.user.id}>
|
||||
<td className="col-md-1">{online}</td>
|
||||
<td className="col-md-5">{gatherer.user.username}</td>
|
||||
<td className="col-md-3">{division} </td>
|
||||
<td className="col-md-2 text-right">{action} </td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
if (this.props.gather.gatherers.length) {
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
<h5 className="panel-title">Roster</h5>
|
||||
</div>
|
||||
<table className="table roster-table">
|
||||
<tbody>
|
||||
{gatherers}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (<div className="panel-body text-center"><JoinGatherButton buttonClass="btn-lg" buttonName="Start a Gather" /></div>);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
22
lib/react/init.jsx
Normal file
22
lib/react/init.jsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
"use strict";
|
||||
|
||||
var socket;
|
||||
|
||||
function initialiseComponents () {
|
||||
var socketUrl = window.location.protocol + "//" + window.location.host;
|
||||
socket = io(socketUrl)
|
||||
.on("connect", function () {
|
||||
console.log("Connected");
|
||||
})
|
||||
.on("reconnect", function () {
|
||||
console.log("Reconnected");
|
||||
})
|
||||
.on("disconnect", function () {
|
||||
console.log("Disconnected")
|
||||
});
|
||||
|
||||
React.render(<UserMenu />, document.getElementById('side-menu'));
|
||||
React.render(<Chatroom />, document.getElementById('chatroom'));
|
||||
React.render(<Gather />, document.getElementById('gathers'));
|
||||
React.render(<CurrentUser />, document.getElementById('currentuser'));
|
||||
};
|
146
lib/react/message.jsx
Normal file
146
lib/react/message.jsx
Normal file
|
@ -0,0 +1,146 @@
|
|||
"use strict";
|
||||
|
||||
var Chatroom = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
history: []
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
var TIMER_INTERVAL = 60000; // Every minute
|
||||
|
||||
socket.on("message:new", function (data) {
|
||||
var history = self.props.history;
|
||||
history.push(data);
|
||||
self.setProps({
|
||||
history: history
|
||||
});
|
||||
self.scrollToBottom();
|
||||
});
|
||||
|
||||
// Message History Retrieved
|
||||
socket.on("message:refresh", function (data) {
|
||||
self.setProps({
|
||||
history: data.chatHistory
|
||||
});
|
||||
self.scrollToBottom();
|
||||
});
|
||||
|
||||
socket.emit("message:refresh", {});
|
||||
|
||||
self.timer = setInterval(function () {
|
||||
if (self.refs.messages) self.refs.messages.refreshTime();
|
||||
}, TIMER_INTERVAL);
|
||||
},
|
||||
|
||||
componentDidUnmount: function () {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
sendMessage: function (message) {
|
||||
socket.emit("newMessage", {message: message});
|
||||
},
|
||||
scrollToBottom: function () {
|
||||
var node = React.findDOMNode(this.refs.messageContainer);
|
||||
node.scrollTop = node.scrollHeight;
|
||||
},
|
||||
render: function () {
|
||||
var messages = this.props.history.map(function (message) {
|
||||
return (
|
||||
<ChatMessage
|
||||
avatar={message.author.avatar}
|
||||
username={message.author.username}
|
||||
content={message.content}
|
||||
ref="messages"
|
||||
createdAt={message.createdAt} />
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">Gather Chat</div>
|
||||
<div className="panel-body">
|
||||
<ul className="chat" id="chatmessages" ref="messageContainer">
|
||||
{messages}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="panel-footer">
|
||||
<MessageBar />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ChatMessage = React.createClass({
|
||||
getInitialState: function () {
|
||||
return {
|
||||
timeAgo: $.timeago(this.props.createdAt)
|
||||
}
|
||||
},
|
||||
refreshTime: function () {
|
||||
var self = this;
|
||||
self.setState({
|
||||
timeAgo: $.timeago(self.props.createdAt)
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<li className="left clearfix">
|
||||
<span className="chat-img pull-left">
|
||||
<img
|
||||
src={this.props.avatar}
|
||||
alt="User Avatar"
|
||||
height="40"
|
||||
width="40"
|
||||
className="img-circle" />
|
||||
</span>
|
||||
<div className="chat-body clearfix">
|
||||
<div className="header">
|
||||
<strong className="primary-font">{this.props.username}</strong>
|
||||
<small className="pull-right text-muted">
|
||||
<i className="fa fa-clock-o fa-fw"></i> {this.state.timeAgo}
|
||||
</small>
|
||||
</div>
|
||||
<p>{this.props.content}</p>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var MessageBar = React.createClass({
|
||||
sendMessage: function (content) {
|
||||
socket.emit("message:new", {
|
||||
content: content
|
||||
});
|
||||
},
|
||||
handleSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
var content = React.findDOMNode(this.refs.content).value.trim();
|
||||
if (!content) return;
|
||||
React.findDOMNode(this.refs.content).value = '';
|
||||
this.sendMessage(content);
|
||||
return;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit} >
|
||||
<div className="input-group">
|
||||
<input
|
||||
id="btn-input"
|
||||
type="text"
|
||||
className="form-control"
|
||||
ref="content"
|
||||
placeholder="Be polite please..." />
|
||||
<span className="input-group-btn">
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary"
|
||||
id="btn-chat"
|
||||
value="Send" />
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
});
|
111
lib/react/user.jsx
Normal file
111
lib/react/user.jsx
Normal file
|
@ -0,0 +1,111 @@
|
|||
"use strict";
|
||||
|
||||
var UserCounter = React.createClass({
|
||||
render: function () {
|
||||
return (
|
||||
<li>
|
||||
<a href="#">
|
||||
<i className="fa fa-users fa-fw"></i> Online
|
||||
<span className="badge add-left"> {this.props.count} </span>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var UserLogin = React.createClass({
|
||||
authorizeId: function (id) {
|
||||
id = parseInt(id, 10);
|
||||
socket.emit("users:authorize", {
|
||||
id: id
|
||||
});
|
||||
},
|
||||
handleSubmit: function (e) {
|
||||
e.preventDefault();
|
||||
var id = React.findDOMNode(this.refs.authorize_id).value.trim();
|
||||
if (!id) return;
|
||||
React.findDOMNode(this.refs.authorize_id).value = '';
|
||||
this.authorizeId(id);
|
||||
return;
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit} >
|
||||
<div className="input-group signin">
|
||||
<input
|
||||
id="btn-input"
|
||||
type="text"
|
||||
className="form-control"
|
||||
ref="authorize_id"
|
||||
placeholder="Choose an ID..." />
|
||||
<span className="input-group-btn">
|
||||
<input
|
||||
type="submit"
|
||||
className="btn btn-primary"
|
||||
id="btn-chat"
|
||||
value="Login" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="signin">
|
||||
<p className="text-center"><small>Just a temporary measure until genuine authentication is implemented</small></p>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
var UserMenu = React.createClass({
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
count: 0,
|
||||
users: []
|
||||
};
|
||||
},
|
||||
componentDidMount: function () {
|
||||
socket.on('users:update', this.updateUsers);
|
||||
},
|
||||
updateUsers: function (data) {
|
||||
this.setProps({
|
||||
count: data.count,
|
||||
users: data.users
|
||||
});
|
||||
},
|
||||
render: function () {
|
||||
var users = this.props.users.map(function (user) {
|
||||
return (
|
||||
<li key={user.id}><a href="#">{user.username}</a></li>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<ul className="nav" id="side-menu">
|
||||
<UserCounter {...this.props} />
|
||||
{users}
|
||||
<li><br /><UserLogin /><br /></li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CurrentUser = React.createClass({
|
||||
componentDidMount: function () {
|
||||
var self = this;
|
||||
socket.on("users:update", function (data) {
|
||||
self.setProps({
|
||||
user: data.currentUser
|
||||
});
|
||||
});
|
||||
socket.emit("users:refresh", {});
|
||||
},
|
||||
render: function () {
|
||||
if (this.props.user) {
|
||||
return (
|
||||
<a href="#">{this.props.user.username} <img src={this.props.user.avatar}
|
||||
alt="User Avatar"
|
||||
height="20"
|
||||
width="20" /></a>
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
780
npm-shrinkwrap.json
generated
780
npm-shrinkwrap.json
generated
|
@ -2,6 +2,11 @@
|
|||
"name": "sws_gathers",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "1.4.0",
|
||||
"from": "async@",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-1.4.0.tgz"
|
||||
},
|
||||
"express": {
|
||||
"version": "4.13.1",
|
||||
"from": "express@",
|
||||
|
@ -405,6 +410,781 @@
|
|||
"from": "extend@",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
|
||||
},
|
||||
"gulp": {
|
||||
"version": "3.9.0",
|
||||
"from": "gulp@",
|
||||
"resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.0.tgz",
|
||||
"dependencies": {
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"from": "archy@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz"
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.0",
|
||||
"from": "chalk@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.1.0",
|
||||
"from": "ansi-styles@^2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz"
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.3",
|
||||
"from": "escape-string-regexp@^1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz"
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"from": "has-ansi@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.0.0",
|
||||
"from": "ansi-regex@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.0",
|
||||
"from": "strip-ansi@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz",
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.0.0",
|
||||
"from": "ansi-regex@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"from": "supports-color@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"deprecated": {
|
||||
"version": "0.0.1",
|
||||
"from": "deprecated@^0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz"
|
||||
},
|
||||
"gulp-util": {
|
||||
"version": "3.0.6",
|
||||
"from": "gulp-util@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.6.tgz",
|
||||
"dependencies": {
|
||||
"array-differ": {
|
||||
"version": "1.0.0",
|
||||
"from": "array-differ@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz"
|
||||
},
|
||||
"array-uniq": {
|
||||
"version": "1.0.2",
|
||||
"from": "array-uniq@^1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz"
|
||||
},
|
||||
"beeper": {
|
||||
"version": "1.1.0",
|
||||
"from": "beeper@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.0.tgz"
|
||||
},
|
||||
"dateformat": {
|
||||
"version": "1.0.11",
|
||||
"from": "dateformat@^1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz",
|
||||
"dependencies": {
|
||||
"get-stdin": {
|
||||
"version": "4.0.1",
|
||||
"from": "get-stdin@*",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
|
||||
},
|
||||
"meow": {
|
||||
"version": "3.3.0",
|
||||
"from": "meow@*",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-3.3.0.tgz",
|
||||
"dependencies": {
|
||||
"camelcase-keys": {
|
||||
"version": "1.0.0",
|
||||
"from": "camelcase-keys@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"camelcase": {
|
||||
"version": "1.1.0",
|
||||
"from": "camelcase@^1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.1.0.tgz"
|
||||
},
|
||||
"map-obj": {
|
||||
"version": "1.0.1",
|
||||
"from": "map-obj@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"indent-string": {
|
||||
"version": "1.2.2",
|
||||
"from": "indent-string@^1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz",
|
||||
"dependencies": {
|
||||
"repeating": {
|
||||
"version": "1.1.3",
|
||||
"from": "repeating@^1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz",
|
||||
"dependencies": {
|
||||
"is-finite": {
|
||||
"version": "1.0.1",
|
||||
"from": "is-finite@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz",
|
||||
"dependencies": {
|
||||
"number-is-nan": {
|
||||
"version": "1.0.0",
|
||||
"from": "number-is-nan@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lodash._reescape": {
|
||||
"version": "3.0.0",
|
||||
"from": "lodash._reescape@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz"
|
||||
},
|
||||
"lodash._reevaluate": {
|
||||
"version": "3.0.0",
|
||||
"from": "lodash._reevaluate@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz"
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
"from": "lodash._reinterpolate@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz"
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "3.6.2",
|
||||
"from": "lodash.template@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
|
||||
"dependencies": {
|
||||
"lodash._basecopy": {
|
||||
"version": "3.0.1",
|
||||
"from": "lodash._basecopy@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz"
|
||||
},
|
||||
"lodash._basetostring": {
|
||||
"version": "3.0.1",
|
||||
"from": "lodash._basetostring@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz"
|
||||
},
|
||||
"lodash._basevalues": {
|
||||
"version": "3.0.0",
|
||||
"from": "lodash._basevalues@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz"
|
||||
},
|
||||
"lodash._isiterateecall": {
|
||||
"version": "3.0.9",
|
||||
"from": "lodash._isiterateecall@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz"
|
||||
},
|
||||
"lodash.escape": {
|
||||
"version": "3.0.0",
|
||||
"from": "lodash.escape@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.0.0.tgz"
|
||||
},
|
||||
"lodash.keys": {
|
||||
"version": "3.1.2",
|
||||
"from": "lodash.keys@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
|
||||
"dependencies": {
|
||||
"lodash._getnative": {
|
||||
"version": "3.9.1",
|
||||
"from": "lodash._getnative@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz"
|
||||
},
|
||||
"lodash.isarguments": {
|
||||
"version": "3.0.4",
|
||||
"from": "lodash.isarguments@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.4.tgz"
|
||||
},
|
||||
"lodash.isarray": {
|
||||
"version": "3.0.4",
|
||||
"from": "lodash.isarray@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lodash.restparam": {
|
||||
"version": "3.6.1",
|
||||
"from": "lodash.restparam@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz"
|
||||
},
|
||||
"lodash.templatesettings": {
|
||||
"version": "3.1.0",
|
||||
"from": "lodash.templatesettings@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"multipipe": {
|
||||
"version": "0.1.2",
|
||||
"from": "multipipe@^0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
|
||||
"dependencies": {
|
||||
"duplexer2": {
|
||||
"version": "0.0.2",
|
||||
"from": "duplexer2@0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.1.13",
|
||||
"from": "readable-stream@~1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz",
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.1",
|
||||
"from": "core-util-is@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"from": "isarray@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"from": "string_decoder@~0.10.x",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "3.0.0",
|
||||
"from": "object-assign@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz"
|
||||
},
|
||||
"replace-ext": {
|
||||
"version": "0.0.1",
|
||||
"from": "replace-ext@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz"
|
||||
},
|
||||
"through2": {
|
||||
"version": "2.0.0",
|
||||
"from": "through2@^2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.0.tgz",
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.0.2",
|
||||
"from": "readable-stream@~2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz",
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.1",
|
||||
"from": "core-util-is@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"from": "isarray@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.2",
|
||||
"from": "process-nextick-args@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.2.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"from": "string_decoder@~0.10.x",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.1",
|
||||
"from": "util-deprecate@~1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.0",
|
||||
"from": "xtend@>=4.0.0 <4.1.0-0",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vinyl": {
|
||||
"version": "0.5.0",
|
||||
"from": "vinyl@^0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.0.tgz",
|
||||
"dependencies": {
|
||||
"clone": {
|
||||
"version": "1.0.2",
|
||||
"from": "clone@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz"
|
||||
},
|
||||
"clone-stats": {
|
||||
"version": "0.0.1",
|
||||
"from": "clone-stats@^0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interpret": {
|
||||
"version": "0.6.5",
|
||||
"from": "interpret@^0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.5.tgz"
|
||||
},
|
||||
"liftoff": {
|
||||
"version": "2.1.0",
|
||||
"from": "liftoff@^2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.1.0.tgz",
|
||||
"dependencies": {
|
||||
"extend": {
|
||||
"version": "2.0.1",
|
||||
"from": "extend@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz"
|
||||
},
|
||||
"findup-sync": {
|
||||
"version": "0.2.1",
|
||||
"from": "findup-sync@^0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.2.1.tgz",
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "4.3.5",
|
||||
"from": "glob@~4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz",
|
||||
"dependencies": {
|
||||
"inflight": {
|
||||
"version": "1.0.4",
|
||||
"from": "inflight@^1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@2",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "2.0.10",
|
||||
"from": "minimatch@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "1.1.0",
|
||||
"from": "brace-expansion@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "0.2.0",
|
||||
"from": "balanced-match@^0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz"
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"from": "concat-map@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.3.2",
|
||||
"from": "once@^1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"flagged-respawn": {
|
||||
"version": "0.3.1",
|
||||
"from": "flagged-respawn@^0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.1.tgz"
|
||||
},
|
||||
"rechoir": {
|
||||
"version": "0.6.2",
|
||||
"from": "rechoir@^0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz"
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.1.6",
|
||||
"from": "resolve@^1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.1.2",
|
||||
"from": "minimist@^1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.2.tgz"
|
||||
},
|
||||
"orchestrator": {
|
||||
"version": "0.3.7",
|
||||
"from": "orchestrator@^0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.7.tgz",
|
||||
"dependencies": {
|
||||
"end-of-stream": {
|
||||
"version": "0.1.5",
|
||||
"from": "end-of-stream@~0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
|
||||
"dependencies": {
|
||||
"once": {
|
||||
"version": "1.3.2",
|
||||
"from": "once@~1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sequencify": {
|
||||
"version": "0.0.7",
|
||||
"from": "sequencify@~0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz"
|
||||
},
|
||||
"stream-consume": {
|
||||
"version": "0.1.0",
|
||||
"from": "stream-consume@~0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pretty-hrtime": {
|
||||
"version": "1.0.0",
|
||||
"from": "pretty-hrtime@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.0.tgz"
|
||||
},
|
||||
"semver": {
|
||||
"version": "4.3.6",
|
||||
"from": "semver@^4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
|
||||
},
|
||||
"tildify": {
|
||||
"version": "1.1.0",
|
||||
"from": "tildify@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tildify/-/tildify-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"os-homedir": {
|
||||
"version": "1.0.1",
|
||||
"from": "os-homedir@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v8flags": {
|
||||
"version": "2.0.9",
|
||||
"from": "v8flags@^2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.9.tgz",
|
||||
"dependencies": {
|
||||
"user-home": {
|
||||
"version": "1.1.1",
|
||||
"from": "user-home@^1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vinyl-fs": {
|
||||
"version": "0.3.13",
|
||||
"from": "vinyl-fs@^0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.13.tgz",
|
||||
"dependencies": {
|
||||
"defaults": {
|
||||
"version": "1.0.2",
|
||||
"from": "defaults@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.2.tgz",
|
||||
"dependencies": {
|
||||
"clone": {
|
||||
"version": "0.1.19",
|
||||
"from": "clone@~0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-0.1.19.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob-stream": {
|
||||
"version": "3.1.18",
|
||||
"from": "glob-stream@^3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz",
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "4.5.3",
|
||||
"from": "glob@^4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
|
||||
"dependencies": {
|
||||
"inflight": {
|
||||
"version": "1.0.4",
|
||||
"from": "inflight@^1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@2",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"once": {
|
||||
"version": "1.3.2",
|
||||
"from": "once@^1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz",
|
||||
"dependencies": {
|
||||
"wrappy": {
|
||||
"version": "1.0.1",
|
||||
"from": "wrappy@1",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "2.0.10",
|
||||
"from": "minimatch@^2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "1.1.0",
|
||||
"from": "brace-expansion@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"balanced-match": {
|
||||
"version": "0.2.0",
|
||||
"from": "balanced-match@^0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz"
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"from": "concat-map@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ordered-read-streams": {
|
||||
"version": "0.1.0",
|
||||
"from": "ordered-read-streams@^0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz"
|
||||
},
|
||||
"glob2base": {
|
||||
"version": "0.0.12",
|
||||
"from": "glob2base@^0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
|
||||
"dependencies": {
|
||||
"find-index": {
|
||||
"version": "0.1.1",
|
||||
"from": "find-index@^0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"unique-stream": {
|
||||
"version": "1.0.0",
|
||||
"from": "unique-stream@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob-watcher": {
|
||||
"version": "0.0.6",
|
||||
"from": "glob-watcher@^0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz",
|
||||
"dependencies": {
|
||||
"gaze": {
|
||||
"version": "0.5.1",
|
||||
"from": "gaze@^0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.1.tgz",
|
||||
"dependencies": {
|
||||
"globule": {
|
||||
"version": "0.1.0",
|
||||
"from": "globule@~0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "1.0.2",
|
||||
"from": "lodash@~1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz"
|
||||
},
|
||||
"glob": {
|
||||
"version": "3.1.21",
|
||||
"from": "glob@~3.1.21",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
|
||||
"dependencies": {
|
||||
"graceful-fs": {
|
||||
"version": "1.2.3",
|
||||
"from": "graceful-fs@~1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "1.0.0",
|
||||
"from": "inherits@1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "0.2.14",
|
||||
"from": "minimatch@~0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "2.6.5",
|
||||
"from": "lru-cache@2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz"
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.1",
|
||||
"from": "sigmund@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "3.0.8",
|
||||
"from": "graceful-fs@^3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz"
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"from": "mkdirp@^0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"from": "minimist@0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "1.0.0",
|
||||
"from": "strip-bom@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"first-chunk-stream": {
|
||||
"version": "1.0.0",
|
||||
"from": "first-chunk-stream@^1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz"
|
||||
},
|
||||
"is-utf8": {
|
||||
"version": "0.2.0",
|
||||
"from": "is-utf8@^0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"through2": {
|
||||
"version": "0.6.5",
|
||||
"from": "through2@^0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.33",
|
||||
"from": "readable-stream@>=1.0.33-1 <1.1.0-0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
|
||||
"dependencies": {
|
||||
"core-util-is": {
|
||||
"version": "1.0.1",
|
||||
"from": "core-util-is@~1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"from": "isarray@0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"from": "string_decoder@~0.10.x",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@~2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.0",
|
||||
"from": "xtend@>=4.0.0 <4.1.0-0",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vinyl": {
|
||||
"version": "0.4.6",
|
||||
"from": "vinyl@^0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
|
||||
"dependencies": {
|
||||
"clone": {
|
||||
"version": "0.2.0",
|
||||
"from": "clone@^0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz"
|
||||
},
|
||||
"clone-stats": {
|
||||
"version": "0.0.1",
|
||||
"from": "clone-stats@^0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript-state-machine": {
|
||||
"version": "2.3.5",
|
||||
"from": "javascript-state-machine@",
|
||||
|
|
10
package.json
10
package.json
|
@ -10,8 +10,8 @@
|
|||
"scripts": {
|
||||
"test": "NODE_ENV=test mocha spec/",
|
||||
"start": "npm run compile && node index.js",
|
||||
"compile:dev": "node_modules/react-tools/bin/jsx --watch --no-cache-dir --source-map-inline -x jsx lib/react/ public/js/",
|
||||
"compile": "node_modules/react-tools/bin/jsx -x jsx lib/react/ public/js/",
|
||||
"watch": "node_modules/gulp/bin/gulp.js watch",
|
||||
"compile": "node_modules/gulp/bin/gulp.js",
|
||||
"dev": "nodemon index.js"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -29,16 +29,22 @@
|
|||
"express": "~4.13.1",
|
||||
"express-handlebars": "~2.0.1",
|
||||
"extend": "^3.0.0",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-react": "^3.0.1",
|
||||
"javascript-state-machine": "^2.3.5",
|
||||
"morgan": "~1.6.1",
|
||||
"node-mysql": "~0.4.2",
|
||||
"react-tools": "~0.13.3",
|
||||
"request": "~2.60.0",
|
||||
"socket.io": "~1.3.5",
|
||||
"gulp-watch": "^4.3.4",
|
||||
"winston": "~1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "~3.1.0",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-plumber": "^1.0.1",
|
||||
"mocha": "~2.2.5",
|
||||
"nodemon": "~1.3.7",
|
||||
"supertest": "~1.0.1"
|
||||
|
|
|
@ -19,4 +19,14 @@
|
|||
|
||||
.signin {
|
||||
margin: 0px 10px;
|
||||
}
|
||||
|
||||
.user-online {
|
||||
border-radius: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
||||
background-image: -moz-radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%);
|
||||
background-image: -webkit-radial-gradient(45px 45px, circle cover, yellow, orange);
|
||||
background-image: radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%);
|
||||
}
|
826
public/js/app.js
826
public/js/app.js
File diff suppressed because one or more lines are too long
4
public/js/client.js
Normal file
4
public/js/client.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
$(function () {
|
||||
initialiseComponents();
|
||||
|
||||
});
|
282
public/js/gather.js
Normal file
282
public/js/gather.js
Normal file
File diff suppressed because one or more lines are too long
23
public/js/init.js
Normal file
23
public/js/init.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
|
||||
var socket;
|
||||
|
||||
function initialiseComponents () {
|
||||
var socketUrl = window.location.protocol + "//" + window.location.host;
|
||||
socket = io(socketUrl)
|
||||
.on("connect", function () {
|
||||
console.log("Connected");
|
||||
})
|
||||
.on("reconnect", function () {
|
||||
console.log("Reconnected");
|
||||
})
|
||||
.on("disconnect", function () {
|
||||
console.log("Disconnected")
|
||||
});
|
||||
|
||||
React.render(React.createElement(UserMenu, null), document.getElementById('side-menu'));
|
||||
React.render(React.createElement(Chatroom, null), document.getElementById('chatroom'));
|
||||
React.render(React.createElement(Gather, null), document.getElementById('gathers'));
|
||||
React.render(React.createElement(CurrentUser, null), document.getElementById('currentuser'));
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixJQUFJLE1BQU0sQ0FBQzs7QUFFWCxTQUFTLG9CQUFvQixJQUFJO0NBQ2hDLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztDQUN2RSxNQUFNLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQztHQUNwQixFQUFFLENBQUMsU0FBUyxFQUFFLFlBQVk7R0FDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztHQUN6QixDQUFDO0dBQ0QsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZO0dBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7R0FDM0IsQ0FBQztHQUNELEVBQUUsQ0FBQyxZQUFZLEVBQUUsWUFBWTtHQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQztBQUM5QixHQUFHLENBQUMsQ0FBQzs7Q0FFSixLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFFBQVEsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztDQUNqRSxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFFBQVEsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztDQUNoRSxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLE1BQU0sRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztDQUM3RCxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFdBQVcsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztDQUN0RSIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc29ja2V0O1xuXG5mdW5jdGlvbiBpbml0aWFsaXNlQ29tcG9uZW50cyAoKSB7XG5cdHZhciBzb2NrZXRVcmwgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyB3aW5kb3cubG9jYXRpb24uaG9zdDtcblx0c29ja2V0ID0gaW8oc29ja2V0VXJsKVxuXHRcdC5vbihcImNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJDb25uZWN0ZWRcIik7XG5cdFx0fSlcblx0XHQub24oXCJyZWNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJSZWNvbm5lY3RlZFwiKTtcblx0XHR9KVxuXHRcdC5vbihcImRpc2Nvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJEaXNjb25uZWN0ZWRcIilcblx0XHR9KTtcblxuXHRSZWFjdC5yZW5kZXIoPFVzZXJNZW51IC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZS1tZW51JykpO1xuXHRSZWFjdC5yZW5kZXIoPENoYXRyb29tIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hhdHJvb20nKSk7XG5cdFJlYWN0LnJlbmRlcig8R2F0aGVyIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ2F0aGVycycpKTtcblx0UmVhY3QucmVuZGVyKDxDdXJyZW50VXNlciAvPiwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N1cnJlbnR1c2VyJykpO1xufTsiXX0=
|
148
public/js/message.js
Normal file
148
public/js/message.js
Normal file
File diff suppressed because one or more lines are too long
114
public/js/user.js
Normal file
114
public/js/user.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -147,6 +147,7 @@ describe("Gather Model:", function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("addUser", function () {
|
||||
it ("adds gatherer to lobby", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -159,6 +160,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.gatherers.length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeUser", function () {
|
||||
it ("removes gatherer altogether", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -168,6 +170,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.gatherers.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("moveToMarine", function () {
|
||||
it ("moves a player to marine", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -183,6 +186,7 @@ describe("Gather Model:", function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("moveToAlien", function () {
|
||||
it ("moves a player to alien", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -198,6 +202,7 @@ describe("Gather Model:", function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("moveToLobby", function () {
|
||||
it ("moves a player to lobby", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -208,6 +213,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.lobby()[0].id, user.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aliens", function () {
|
||||
it ("returns all gatherers in aliens", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -215,6 +221,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.aliens().length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("marines", function () {
|
||||
it ("returns all gatherers in marines", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -222,12 +229,14 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.marines().length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("lobby", function () {
|
||||
it ("returns all gatherers in lobby", function () {
|
||||
gather.addUser(user);
|
||||
assert.equal(gather.lobby().length, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("toJson", function () {
|
||||
it ("returns a json representation of the gather instance", function () {
|
||||
var output = gather.toJson();
|
||||
|
@ -235,6 +244,7 @@ describe("Gather Model:", function () {
|
|||
assert.isString(output.state);
|
||||
});
|
||||
});
|
||||
|
||||
describe("leaderVotes", function () {
|
||||
beforeEach(function () {
|
||||
gatherers.forEach(function (user) {
|
||||
|
@ -261,6 +271,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(gather.leaderVotes().length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("voteForLeader", function () {
|
||||
beforeEach(function () {
|
||||
gatherers.forEach(function (user) {
|
||||
|
@ -289,6 +300,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(votes[0], secondCandidate.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("alienLeader", function () {
|
||||
beforeEach(function () {
|
||||
gatherers.forEach(function (gatherer) {
|
||||
|
@ -304,6 +316,7 @@ describe("Gather Model:", function () {
|
|||
assert.isUndefined(gather.alienLeader());
|
||||
});
|
||||
});
|
||||
|
||||
describe("marineLeader", function () {
|
||||
beforeEach(function () {
|
||||
gatherers.forEach(function (gatherer) {
|
||||
|
@ -319,6 +332,7 @@ describe("Gather Model:", function () {
|
|||
assert.isUndefined(gather.marineLeader());
|
||||
});
|
||||
});
|
||||
|
||||
describe("assignMarineLeader", function () {
|
||||
it ("assigns a marine leader", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -327,6 +341,7 @@ describe("Gather Model:", function () {
|
|||
assert.equal(leader.id, user.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("assignAlienLeader", function () {
|
||||
it ("assigns an alien leader", function () {
|
||||
gather.addUser(user);
|
||||
|
@ -335,6 +350,21 @@ describe("Gather Model:", function () {
|
|||
assert.equal(leader.id, user.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getGatherer", function () {
|
||||
beforeEach(function () {
|
||||
gather.addGatherer(user);
|
||||
});
|
||||
it ("returns a gatherer given a user", function () {
|
||||
var gatherer = gather.getGatherer(user);
|
||||
assert.equal(gatherer.id, user.id);
|
||||
});
|
||||
it ("returns null if user is not a gatherer", function () {
|
||||
var gatherer = gather.getGatherer(gatherers[0]);
|
||||
assert.isNull(gatherer);
|
||||
});
|
||||
});
|
||||
|
||||
describe("confirmTeam", function () {
|
||||
var leader;
|
||||
beforeEach(function () {
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
<script src="/js/app.js"></script>
|
||||
<script src="/js/app.js"></script>
|
||||
<script src="/js/client.js"></script>
|
Loading…
Reference in a new issue