Private
Public Access
1
0

new: usr: add mineseeker game to the symfony 4 project #3

This commit is contained in:
2019-10-27 13:35:33 +01:00
parent 6caf340302
commit 3bbc96c76c
160 changed files with 49951 additions and 602 deletions

View File

@@ -1,3 +0,0 @@
body {
background-color: lightgray;
}

View File

@@ -0,0 +1,186 @@
* {
outline: none;
padding: 0;
margin: 0;
}
html, body {
background: #ffffff;
display: block;
width: 100%;
height: 100%;
}
header {
background: #d1e8ff;
position: relative;
width: 100%;
height: 950px;
color: #ffffff;
overflow: hidden;
}
header section {
display: flex;
align-items: flex-start;
justify-content: flex-start;
flex-direction: column;
max-width: 1300px;
width: 100%;
height: 100%;
padding: 20px;
margin: 0 auto;
}
header section div.logo img {
width: 350px;
margin: 50px 0;
}
header section div.logo a {
display: block;
}
header section > img {
position: absolute;
width: 1300px;
height: 1300px;
right: -20%;
top: -10%;
z-index: 1;
}
header section > div {
z-index: 2;
}
header section h1 {
font: bold 40px 'Rajdhani', sans-serif;
color: #434242;
margin-bottom: 100px;
}
header section h2 {
font: normal 32px 'Rajdhani', sans-serif;
color: #434242;
margin-top: 100px;
}
header section h3 {
display: block;
font: bold 16px 'Rajdhani', sans-serif;
color: #434242;
margin-top: 10px;
}
header section h3 img {
width: 16px;
}
header section div.buttons > a {
background: #69788e;
display: table;
font: bold 32px 'Rajdhani', sans-serif;
text-transform: uppercase;
text-decoration: none;
border: 5px solid #57667b;
color: #FFFFFF;
padding: 25px 150px;
margin-bottom: 20px;
-webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
header section div.buttons > a:hover {
background: #57667b;
-webkit-box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
header section div.buttons > a.small {
background: #83aed9;
display: inline-block;
font: bold 22px 'Rajdhani', sans-serif;
border: 1px solid #6890ba;
color: #FFFFFF;
padding: 10px;
-webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
header section div.buttons > a.small:hover {
background: #86b5e1;
border: 1px solid #658fb8;
color: #FFFFFF;
-webkit-box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
@media screen and (max-width: 1100px) {
header section {
align-items: center;
justify-content: center;
text-align: center;
}
header section div.buttons > a {
margin: 0 auto 20px auto;
}
header section h1 {
margin-bottom: 20px;
}
header section div.logo img {
margin-bottom: 0;
}
header section > img {
display: none;
}
}
@media screen and (max-width: 500px) {
/*header {*/
/*min-height: 100%;*/
/*height: auto;*/
/*}*/
header section {
width: auto;
}
header section div.logo img {
width: 100%;
}
header section div.buttons > a {
display: block;
padding: 25px 5px;
}
}

View File

@@ -0,0 +1,398 @@
@import url('https://fonts.googleapis.com/css?family=Rajdhani:300,400,500,600,700&subset=latin-ext');
@import "~bootstrap/dist/css/bootstrap.min.css";
@import "style.homepage";
::-webkit-input-placeholder {
color: #888982;
}
::-moz-placeholder {
color: #888982;
}
:-ms-input-placeholder {
color: #888982;
}
:-moz-placeholder {
color: #888982;
}
* {
padding: 0;
margin: 0;
outline: 0;
}
*,
*:after,
*::before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.ac-custom {
width: 100%;
}
header section .form-check {
display: table;
position: relative;
margin: 20px 0;
}
header section h1 {
margin: 10px 0;
}
header section .input-submit button,
header section .input-submit button:hover,
header section .form-input,
header section .form-input:focus,
header section .form-input:hover {
-webkit-transition: all 250ms ease-in-out;
-moz-transition: all 250ms ease-in-out;
-o-transition: all 250ms ease-in-out;
transition: all 250ms ease-in-out;
}
header section .input-submit button {
background: #83aed9;
display: table;
font: bold 32px 'Rajdhani', sans-serif;
text-transform: uppercase;
text-decoration: none;
width: 500px;
border: 1px solid #658fb8;
color: #FFFFFF;
padding: 25px 150px;
margin-top: 20px;
-webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
-webkit-border-radius: 3px;
border-radius: 3px;
}
header section .input-submit button:hover {
background: #86b5e1;
-webkit-box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
box-shadow: 0 7px 15px rgba(0, 0, 0, 0.2);
}
header section .form-input {
display: block;
width: 500px;
font: bold 22px 'Rajdhani', sans-serif;
border: 1px solid #dddddd;
color: #000000;
padding: 15px;
margin-bottom: 10px;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
}
header section .form-input:focus,
header section .form-input:hover {
-webkit-box-shadow: 0 7px 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 7px 10px rgba(0, 0, 0, 0.1);
}
header section .failure {
background: #f00;
position: relative;
border: 3px solid #fff;
font: bold 16px 'Rajdhani', sans-serif;
color: #FFFFFF;
padding: 10px;
margin: 30px 0 10px 0;
-webkit-border-radius: 5px;
border-radius: 5px;
}
header section .failure:after,
header section .failure:before {
content: " ";
position: absolute;
bottom: 100%;
left: 50px;
height: 0;
width: 0;
border: solid transparent;
pointer-events: none;
}
header section .failure:after {
border-color: rgba(0, 0, 0, 0);
border-bottom-color: #f00;
border-width: 20px;
margin-left: -20px;
}
header section .failure:before {
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #ffffff;
border-width: 26px;
margin-left: -26px;
}
header section .failure ul {
display: inline-block;
list-style: none;
padding: 0;
margin: 0 10px 0 0;
}
header section h3.or {
font: bold 16px 'Rajdhani', sans-serif;
text-transform: uppercase;
color: #a1a1a1;
margin: 20px 0;
}
header section #id_welcome {
display: flex;
flex-direction: row;
margin-bottom: 115px;
}
header section #id_welcome > div {
padding-right: 20px;
}
header section #id_welcome img {
width: 100px;
border: 5px solid #414040;
-webkit-border-radius: 50%;
border-radius: 50%;
}
header section .buttons,
header section form {
z-index: 2;
}
header section div.buttons > a.fb-login,
header section div.buttons > a.slack-login {
position: relative;
display: block;
width: 500px;
height: 93px;
padding: 25px 0 25px 150px;
margin-bottom: 10px;
overflow: hidden;
cursor: pointer;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
}
header section div.buttons > a.fb-login:hover,
header section div.buttons > a.slack-login:hover {
text-decoration: none;
-webkit-box-shadow: 0 7px 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 7px 10px rgba(0, 0, 0, 0.1);
}
header section div.buttons > a.fb-login i,
header section div.buttons > a.slack-login i {
position: absolute;
font-size: 130px;
top: 0;
left: 15px;
}
header section div.buttons > a.fb-login {
background: #5975b1;
border: 1px solid #50649f;
}
header section div.buttons > a.fb-login:hover {
background: #42598c;
color: #FFFFFF;
}
header section div.buttons > a.slack-login {
background: #FFFFFF;
border: 1px solid #5c3a58;
color: #5c3a58;
}
header section div.buttons > a.slack-login:hover {
background: #e6e6e6;
color: #5c3a58;
}
header section .failure-main {
background: #f00;
max-width: 500px;
border: 3px solid #fff;
font: bold 16px 'Rajdhani', sans-serif;
color: #FFFFFF;
padding: 10px;
margin: 0 0 20px 0;
-webkit-border-radius: 5px;
border-radius: 5px;
}
main div.txt {
width: 100%;
max-width: 1000px;
font-family: 'Rajdhani', sans-serif;
color: #414040;
margin: 50px auto 0 auto;
}
main div.txt h2 {
margin: 0 0 50px 0;
}
main div.txt p {
font: normal 16px 'Rajdhani', sans-serif;
}
main div.txt li {
font: normal 16px 'Rajdhani', sans-serif;
padding-left: 10px;
margin-left: 50px;
}
main .technologies {
text-align: center;
}
main .technologies img {
display: inline-block;
width: 90%;
max-width: 100px;
margin: 20px;
}
main .technologies h1 {
font-weight: bold;
}
footer {
background: #414040;
width: 100%;
min-height: 50px;
margin-top: 50px;
}
footer nav {
display: block;
text-align: center;
}
footer nav ul {
display: inline-block;
list-style: none;
padding: 0;
margin: 0;
}
footer nav ul li {
display: inline-block;
font: bold 16px 'Rajdhani', sans-serif;
color: #FFFFFF;
}
footer nav ul li:nth-child(even) {
width: 50px;
text-align: center;
}
footer nav ul li a {
text-align: center;
line-height: 50px;
color: #FFFFFF;
}
footer nav ul li a:hover {
color: #FFFFFF;
}
@media screen and (max-width: 1100px) {
header section #id_welcome {
align-items: center;
justify-content: center;
margin-top: 50px;
}
header section .form-input,
header section .form-check {
margin-left: auto;
margin-right: auto;
}
header section .input-submit button {
margin: 0 auto;
}
header section > div {
width: 100%;
}
header section div.buttons > a.fb-login,
header section div.buttons > a.slack-login {
margin: 0 auto;
}
main div.txt {
padding: 0 20px;
}
}
@media screen and (max-width: 550px) {
header section #id_welcome {
display: block;
}
header section {
padding: 20px;
}
header section .form-input {
width: 100%;
margin-left: auto;
margin-right: auto;
}
header section .form-check {
margin: 20px auto;
}
header section .input-submit button {
width: 100%;
}
header section div.buttons > a.fb-login,
header section div.buttons > a.slack-login {
width: 100%;
}
header section div.buttons > a.fb-login span,
header section div.buttons > a.slack-login span {
display: none;
}
footer nav ul li {
display: block;
}
footer nav ul li:nth-child(even) {
display: none;
}
}

File diff suppressed because it is too large Load Diff

10
assets/js/mine-seeker.js Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import MineSeeker from './mine-seeker/app';
ReactDOM.render(
<MineSeeker env={document.getElementById('mine-wrapper').dataset.env}
gameId={document.getElementById('mine-wrapper').dataset.gameId}
ssl={document.getElementById('mine-wrapper').dataset.ssl}/>,
document.getElementById('mine-wrapper')
);

View File

@@ -0,0 +1,459 @@
import React from 'react';
import Grid from './grid/grid';
import GridControl from './grid/grid-control';
class MineSeeker extends React.Component {
constructor(props) {
super(props);
let gameAssoc = props.gameId !== '' ? props.gameId : this.makeGameAssoc(50);
let channel = "mineseeker/channel/" + gameAssoc;
this.state = {
env: props.env,
ssl: props.ssl,
gameInherited: props.gameId !== '',
gameAssoc: gameAssoc,
channel: channel,
session: null,
createGrid: false,
stepCache: [],
connectionLost: false,
end: false
}
}
makeGameAssoc(len) {
let text = "";
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < len; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
currectGridSize() {
let $field = $('#mine-wrapper .grid');
$field.height($field.width());
$field = $('#mine-wrapper .grid .field-wrapper');
$field.height($field.width());
$('#mine-wrapper .grid .field-wrapper .field')
.height($field.width())
.css('line-height', ($field.width() - 2) + 'px');
}
/**
* STEP
*
* @param coords
* @returns {{red: *, blue: *}}
*/
makePointsCalcAndStep(coords) {
let users = this.refs.gridControl.refs.userControl,
activePlayer = users.state.activePlayer ? 'blue' : 'red',
inactivePlayer = users.state.activePlayer ? 'red' : 'blue',
redPoints = activePlayer === 'red'
? users.refs[activePlayer].state.mines
: users.refs[inactivePlayer].state.mines,
bluePoints = activePlayer === 'blue'
? users.refs[activePlayer].state.mines
: users.refs[inactivePlayer].state.mines;
this.refs.gridControl.stepEvent(coords);
let mineCache = this.refs.gridControl.state.foundUserMineCache;
redPoints += activePlayer === 'red' ? mineCache : 0;
bluePoints += activePlayer === 'blue' ? mineCache : 0;
return {red: redPoints, blue: bluePoints};
}
/**
* START
*
* @param payload
*/
makeGameStart(payload) {
/** every time the blue starts */
this.refs.gridControl.refs.userControl.setState({activePlayer: 1});
/** Set up player names w/ server data */
this.refs.gridControl.refs.userControl.refs.red.setState({
name: payload.users.red !== '' ? payload.users.red : payload.users.redAnon,
});
this.refs.gridControl.refs.userControl.refs.blue.setState({
name: payload.users.blue !== '' ? payload.users.blue : payload.users.blueAnon,
desc: this.refs.gridControl.state.webPlayer === 'blue'
? this.refs.gridControl.state.desc.you
: this.refs.gridControl.state.desc.buddy,
active: true,
});
this.refs.gridControl.setState({overlay: false});
}
/**
* THE END
*
* @param bluePoints
* @param redPoints
* @param resign
*/
makeGameEndIfItEnds(bluePoints, redPoints, resign = false) {
let redWins = redPoints > 25,
blueWins = bluePoints > 25;
if (redWins || blueWins || resign) {
this.refs.gridControl.state.sound.won.play();
if (false === resign) {
this.refs.gridControl.setState({
overlay: true,
overlayTitle: (redWins ? 'Red' : 'Blue') + " wins the game!",
overlaySubTitle: "Play again!"
});
}
this.refs.gridControl.showLeftMines();
this.refs.gridControl.refs.userControl.setState({activePlayer: false});
this.refs.gridControl.refs.userControl.refs.red.setState({desc: ""});
this.refs.gridControl.refs.userControl.refs.blue.setState({desc: ""});
}
}
resignProcess(color) {
this.refs.gridControl.setState({
overlay: true,
overlayTitle: color === this.refs.gridControl.state.webPlayer
? "You have been give up"
: "Your opponent has been resigned",
overlaySubTitle: color === this.refs.gridControl.state.webPlayer
? "You LOSE!"
: "You WIN!"
});
this.setState({end: true});
this.makeGameEndIfItEnds(0, 0, true);
}
clickResign() {
/** PUBLISH */
this.state.session.publish(this.state.channel, {
'resign': this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red'
});
this.resignProcess(this.refs.gridControl.state.webPlayer);
}
clickResignCancel() {
this.refs.gridControl.setState({
overlay: false
});
}
/** RESIGN */
resign() {
let users = this.refs.gridControl.refs.userControl,
activePlayer = users.state.activePlayer ? 'blue' : 'red';
if (this.refs.gridControl.state.webPlayer === activePlayer) {
this.refs.gridControl.setState({
overlay: true,
overlayTitle: "Are u sure u want to resign?!",
overlaySubTitle: <div className="resign">
<a onClick={this.clickResign.bind(this)}>Yes</a>
<a onClick={this.clickResignCancel.bind(this)}>No!</a>
</div>
});
}
}
/**
* @see https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
* @see https://developers.facebook.com/docs/sharing/reference/send-dialog
* @see https://developers.facebook.com/docs/plugins/share-button/
*/
clickFBShare() {
let display = 'popup';
FB.getLoginStatus(function (response) {
display = response.status === 'connected'
? 'dialog'
: 'popup';
});
FB.ui({
method: 'send',
display: display,
link: window.location.href + '/' + this.state.gameAssoc,
});
}
wInit(session, gridServer, gridClient) {
this.setState({session: session});
/** save session to GridControl */
/** render grid fields - @see #12 */
this.refs.gridControl.setState({
grid: this.state.gameInherited ? gridServer : gridClient,
channel: this.state.channel,
desc: {
buddy: <div>
Your buddy is <br/>
making a <br/>
move.
</div>,
you: <div>
It is your turn! <br/>
Make a move.
</div>
},
overlay: true,
overlayTitle: "We are waiting for your opponent...",
overlaySubTitle: this.state.gameAssoc
?
<div>
<h3>Share this unique link w/ your opponent</h3>
<div className="clippy">
<input id="foo"
defaultValue={window.location.href + '/' + this.state.gameAssoc}/>
</div>
{this.state.env !== 'dev' &&
<a onClick={this.clickFBShare.bind(this)}>Share in Facebook message</a>
}
{this.state.env === 'dev' &&
<a href={"/play/" + this.state.gameAssoc} target="_blank">Play w/ me!</a>
}
</div>
: '',
renderGridFields: this.state.gameAssoc
});
}
wSubscribe(payload, rpcUsers = null) {
this.state.env === 'dev' && console.info(
(typeof payload.user !== 'undefined' ? payload.user : 'user') + " has been subscribed to the channel!"
);
let firstUser = !rpcUsers;
this.refs.gridControl.state.webPlayer === null && this.refs.gridControl.setState({
webPlayer: payload.user === payload.users.blue ||
(
firstUser && payload.users.blueAnon !== '' ||
!firstUser && (rpcUsers.blueAnon === '' && rpcUsers.blue === '')
)
? 'blue' : 'red'
});
/** rwd */
(900 > $(document).width()) && this.currectGridSize();
/** every user has been came */
if (
payload.userCnt === 2 &&
(
!this.state.connectionLost ||
this.state.connectionLost && false === this.refs.gridControl.refs.userControl.state.activePlayer && !this.state.end
)
) {
this.makeGameStart(payload);
}
}
wUnsubscribe(payload) {
this.state.env === 'dev' && console.info(payload.msg);
this.refs.gridControl.setState({
overlay: true,
overlayTitle: "The connection has been lost w/ your friend...",
overlaySubTitle: "Please, restart the game!"
});
}
wTopic(payload) {
/** Auto-Step if this player is not the current user */
if (this.refs.gridControl.state.webPlayer !== payload.data.player) {
if (null === payload.data.resign) {
this.state.env === 'dev' && console.warn(payload.user + " has been stepped to coords: " + payload.data.coords[0] + ', ' + payload.data.coords[1]);
this.state.env === 'dev' && console.warn('Opponent stepped: Auto-Step process');
this.refs.gridControl.refs.userControl.setState({bombSelected: payload.data.bomb});
/** STEP */
let points = this.makePointsCalcAndStep(payload.data.coords);
/** THE END */
this.makeGameEndIfItEnds(points.blue, points.red);
} else {
/** RESIGN */
/** THE END */
this.resignProcess(payload.data.resign);
}
}
}
/** Connect - Subscribe */
subscribe(rpcUsers = null) {
this.state.session.subscribe(
this.state.channel,
(uri, payload, log) => {
let isTopicEvent = typeof payload.data !== 'undefined',
isNotUnsubscribe = typeof payload.msg === 'undefined';
/** CONNECTION */
if (isTopicEvent) {
this.wTopic(payload);
} else {
if (isNotUnsubscribe) {
this.wSubscribe(payload, rpcUsers);
} else {
this.wUnsubscribe(payload);
}
}
/** RECONNECTION */
if (payload.userCnt === 2 && this.state.connectionLost) {
this.state.env === 'dev' && console.info('Reconnection process');
/** PUBLISH */
let cache = this.state.stepCache;
cache.forEach((item) => this.state.session.publish(this.state.channel, item));
this.setState({connectionLost: false, stepCache: []});
}
});
}
connectWithWebsocket() {
/** Create Websocket w/ Bahnhof.js */
let websocket = WS.connect(
// this.state.env === 'dev'
// ? "ws://localhost:6450"
(this.state.ssl === 'true' ? "wss" : "ws") + "://" + window.location.hostname + ":6450/"
// : (this.state.ssl === 'true' ? "wss" : "ws") + "://mineseeker.splendidbear.org:6450"
);
/**
* Connect
* Session is an Autobahn JS WAMP session.
*/
websocket.on("socket/connect", (session) => {
this.state.env === 'dev' && console.info("Successfully connected to the Server!");
if (!this.state.connectionLost) {
let gridClient = this.state.gameInherited || new Grid().state.grid;
/**
* Connect - RPC
* Send grid information to the server
*/
session
.call(
this.state.gameInherited ? "mineseeker-rpc/connectGame" : "mineseeker-rpc/startGame",
this.state.gameInherited ? this.state.gameAssoc : [window.btoa(JSON.stringify(gridClient)), this.state.gameAssoc]
)
.then(
(data) => {
this.state.env === 'dev' && console.info('RPC has been called');
let serverData = data[0] !== true
? JSON.parse(window.atob(data))
: data;
/** Check the grid if the user is inherited @see #30 */
if ((this.state.gameInherited && typeof serverData.grid !== 'undefined') || !this.state.gameInherited) {
this.wInit(session, serverData.grid, gridClient);
this.subscribe(this.state.gameInherited && serverData.users);
} else {
this.refs.gridControl.setState({
overlay: true,
overlayTitle: "This channel does not exists!",
overlaySubTitle: <a href={"/play"} target="_self">Restart game!</a>
});
console.error("This channel does not exists!");
}
},
(error, desc) => this.state.env === 'dev' && console.error(["RPC Error", error, desc])
);
} else {
this.setState({session: session});
this.subscribe();
}
});
/**
* DisConnect
* Error provides us with some insight into the disconnection: error.reason and error.code
*/
websocket.on("socket/disconnect", (error) => {
this.state.env === 'dev' && console.error("Disconnected for " + error.reason + " with code " + error.code);
error.code === 6 && this.setState({connectionLost: true});
error.code === 3 && setTimeout(this.componentDidMount().bind(this), 500);
});
}
/** After rendering */
componentDidMount() {
this.connectWithWebsocket();
}
/**
* Cache the steps unless reconnection
*
* @param dataPack
*/
cachePublish(dataPack) {
let cache = this.state.stepCache;
cache.push(dataPack);
this.setState({stepCache: cache});
}
onClick(coords) {
let activePlayer = this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red';
/** if the clicked field is NEVER CLICKED */
if (this.refs.gridControl.checkFieldHasBeenNeverClicked(coords[0], coords[1])) {
/** Player step and it is the current player */
if (activePlayer === this.refs.gridControl.state.webPlayer) {
/** STEP */
let points = this.makePointsCalcAndStep(coords);
/** THE END */
this.makeGameEndIfItEnds(points.blue, points.red);
let dataPack = {
'coords': coords,
'player': activePlayer,
'bomb': this.refs.gridControl.refs.userControl.state.bombSelected,
'redPoints': points.red,
'bluePoints': points.blue,
'resign': null,
'redExplodedBomb': activePlayer === 'red' && this.refs.gridControl.refs.userControl.state.bombSelected,
'blueExplodedBomb': activePlayer === 'blue' && this.refs.gridControl.refs.userControl.state.bombSelected
};
/** PUBLISH */
!this.state.connectionLost
? this.state.session.publish(this.state.channel, dataPack)
: this.cachePublish(dataPack);
}
}
}
render() {
return (
<GridControl ref="gridControl"
env={this.props.env === 'dev'}
resign={this.resign.bind(this)}
onClick={this.onClick.bind(this)}/>
);
}
}
export default MineSeeker;

View File

@@ -0,0 +1,449 @@
import React from 'react';
import GridField from './grid-field';
import UserControl from '../user/user-control';
import {Howl, Howler} from 'howler';
class GridControl extends React.Component {
constructor(props) {
super(props);
let click = new Howl({src: ['/sound/click.mp3']}),
bomb = new Howl({src: ['/sound/bomb.mp3']}),
mine = new Howl({src: ['/sound/mine.mp3']}),
warning = new Howl({src: ['/sound/warning.mp3']}),
won = new Howl({src: ['/sound/won.mp3']});
this.state = {
env: props.env,
webPlayer: null,
grid: null,
desc: null,
renderGridFields: false,
gridFields: [],
updatedFieldCache: [],
bombFieldCache: [],
foundUserMineCache: 0,
playBomb: false,
overlay: false,
overlayTitle: "",
overlaySubTitle: "",
sound: {
click: click,
bomb: bomb,
mine: mine,
warning: warning,
won: won
},
lastClicked: {
red: null,
blue: null
}
};
}
refString(row, col) {
return 'gridField_' + row + '_' + col;
}
checkMine(row, col) {
return typeof this.state.grid[row] !== 'undefined' && typeof this.state.grid[row][col] !== 'undefined' && this.state.grid[row][col] !== 'm';
}
checkFieldHasBeenNeverClicked(row, col) {
return this.state.updatedFieldCache.indexOf(this.refString(row, col)) < 0 && !this.refs[this.refString(row, col)].state.active;
}
getBombRadius(row, col) {
let isBombTargetCenter = row > 1 && row < this.state.grid.length - 2 && col > 1 && col < this.state.grid[row].length - 2;
/** if the (5x5) target not fits the grid */
if (!isBombTargetCenter) {
col = col < 2 ? 2 : col;
row = row < 2 ? 2 : row;
row = row > this.state.grid.length - 3 ? this.state.grid.length - 3 : row;
col = col > this.state.grid[0].length - 3 ? this.state.grid[0].length - 3 : col;
}
return [
[row, col], [row - 2, col - 2], [row - 2, col], [row - 2, col + 2], [row, col - 2], [row, col + 2],
[row + 2, col - 2], [row + 2, col], [row + 2, col + 2], [row - 2, col + 1], [row - 2, col - 1],
[row - 1, col - 2], [row - 1, col - 1], [row - 1, col], [row - 1, col + 1], [row - 1, col + 2],
[row, col - 1], [row, col + 1], [row + 1, col - 2], [row + 1, col - 1], [row + 1, col],
[row + 1, col + 1], [row + 1, col + 2], [row + 2, col - 1], [row + 2, col + 1]
];
}
getBombFieldRadius() {
return [
[null, null], [0, 0], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1, 2], [2, 2],
[null, null], [null, null], [null, null], [null, null], [null, null], [null, null], [null, null],
[null, null], [null, null], [null, null], [null, null], [null, null], [null, null], [null, null],
[null, null], [null, null]
];
}
getNeighbourRadius(row, col) {
return [
[row - 1, col], [row - 1, col - 1], [row - 1, col + 1], [row, col - 1], [row, col + 1], [row + 1, col],
[row + 1, col + 1], [row + 1, col - 1]
];
}
checkNeighbourItem(row, col) {
if (this.checkMine(row, col)) {
var currentField = this.refs[this.refString(row, col)];
/**
* It must be cached because the GridField.state not updated until
* all showAppropriateFields() method runned out!!
*/
if (this.checkFieldHasBeenNeverClicked(row, col)) {
this.state.updatedFieldCache.push(this.refString(row, col));
currentField.setState({
currentImage: this.state.grid[row][col],
currentObj: this.state.grid[row][col],
active: true
});
if (this.state.grid[row][col] === 0) {
return {
row: row,
col: col
};
}
}
}
return false;
}
checkNeighbours(row, col) {
let anotherFields = [],
neighbours = this.getNeighbourRadius(row, col);
for (let i = 0, j = neighbours.length; i < j; i++) {
anotherFields.push(this.checkNeighbourItem(neighbours[i][0], neighbours[i][1]));
}
return anotherFields;
}
bombClear() {
if (this.state.bombFieldCache.length) {
for (var i = 0, j = this.state.bombFieldCache.length; i < j; i++) {
var cacheItem = this.state.bombFieldCache[i];
this.refs[this.refString(cacheItem[0], cacheItem[1])]
.setState({bombTargetArea: null});
}
this.state.bombFieldCache = [];
}
}
bombCreate(row, col) {
var bombFieldSymbols = this.getBombFieldRadius(),
bombFields = this.getBombRadius(row, col);
for (var i = 0, j = bombFields.length; i < j; i++) {
this.state.bombFieldCache.push(bombFields[i]);
this.refs[this.refString(bombFields[i][0], bombFields[i][1])]
.setState({bombTargetArea: bombFieldSymbols[i]});
}
}
showLeftMines() {
for (let i = 0, j = this.state.grid.length; i < j; i++) {
for (let k = 0, l = this.state.grid[i].length; k < l; k++) {
let currentField = this.refs[this.refString(i, k)];
if (this.state.grid[i][k] === 'm' && this.checkFieldHasBeenNeverClicked(i, k)) {
currentField.setState({
currentImage: currentField.state.icons.root + currentField.state.icons.left
});
}
}
}
}
/** set __ACTIVE__ player in the UserControl !!!! */
changePlayer(idx, max, currentObject) {
var userControl = this.refs.userControl,
activePlayer = userControl.state.activePlayer ? 'blue' : 'red',
inactivePlayer = userControl.state.activePlayer ? 'red' : 'blue';
if (
userControl.state.bombSelected && idx === (max - 1) ||
!idx && !userControl.state.bombSelected && currentObject !== 'm'
) {
userControl.setState({
activePlayer: userControl.state.activePlayer ? 0 : 1
});
/** the desc is inversely because the user.active is not changed yet !!! */
userControl.refs[activePlayer].setState({
active: false,
desc: ""
});
userControl.refs[inactivePlayer].setState({
active: true,
desc: activePlayer === this.state.webPlayer
? this.state.desc.buddy
: this.state.desc.you
});
}
}
/**
* Show all fields that needed after click
*
* @param currentField
* @param row
* @param col
*/
showAppropriateFields(currentField, row, col) {
currentField.setState({
currentObj: this.state.grid[row][col],
active: true
});
if (this.checkFieldHasBeenNeverClicked(row, col)) {
this.state.updatedFieldCache.push(this.refString(row, col));
}
if (this.state.grid[row][col] === 0) {
var neighbours = this.checkNeighbours(row, col);
neighbours
.filter((i) => {
return i !== false;
})
.forEach((element, index, array) => {
var currentField = this.refs[this.refString(element.row, element.col)];
this.showAppropriateFields(currentField, element.row, element.col);
});
}
}
/**
* Player control method
*
* @param currentObject {int|string} Current object from Grid class
* @param row {int}
* @param col {int}
* @param justOnFirstIteration {int} When bomb is being used check the whole explosion area
*/
handleGridField(currentObject, row, col, justOnFirstIteration = 0) {
var userControl = this.refs.userControl,
gridFieldControl = this.refs[this.refString(row, col)],
activePlayer = userControl.state.activePlayer ? 'blue' : 'red',
inactivePlayer = userControl.state.activePlayer ? 'red' : 'blue';
/** if the clicked field is NEVER CLICKED */
if (this.checkFieldHasBeenNeverClicked(row, col)) {
/** update LAST CLICKED grid field */
if (!justOnFirstIteration) {
if (this.state.lastClicked[activePlayer] !== null) {
this.refs[this.refString(this.state.lastClicked[activePlayer][0], this.state.lastClicked[activePlayer][1])].setState({
lastClickedRed: false,
lastClickedBlue: false
});
}
}
this.state.lastClicked[activePlayer] = [row, col];
/** if you found mine */
if (currentObject === 'm') {
this.state.foundUserMineCache++;
if (!justOnFirstIteration) {
/** set last clicked field w/ color */
this.state.lastClicked[activePlayer] = [row, col];
this.state.sound[
(userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache) > 20
? 'warning'
: 'mine'
].play();
}
/** set current image in field */
gridFieldControl.setState({
currentImage: gridFieldControl.state.icons.root + gridFieldControl.state.icons.flag[activePlayer]
});
} else {
this.state.sound.click.play();
/** set current image in field - WHEN it is a number */
if (!isNaN(currentObject)) {
gridFieldControl.setState({
currentImage: currentObject
});
}
}
/**
* set bombs status - we must add one mine (currentObject === 'm' ? 1 : 0) to current mine
* when it found NOW because the status is not refreshed unless the handleGridField() ends
*/
userControl.refs[activePlayer].setState({
enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) <= userControl.refs[inactivePlayer].state.mines
});
userControl.refs[inactivePlayer].setState({
enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) >= userControl.refs[inactivePlayer].state.mines
});
/** set-up last clicked */
if (!justOnFirstIteration) {
gridFieldControl.setState({
lastClickedRed: activePlayer === 'red',
lastClickedBlue: activePlayer === 'blue'
});
}
}
}
/**
* Show elems w/ conditions
*
* @param row
* @param col
* @param idx
* @param max
*/
show(row, col, idx = 0, max = 0) {
this.handleGridField(this.state.grid[row][col], row, col, idx);
this.showAppropriateFields(this.refs[this.refString(row, col)], row, col);
this.changePlayer(idx, max, this.state.grid[row][col]);
}
/**
* STEP one
*
* @param coords
*/
stepEvent(coords) {
/** if the clicked field is NEVER CLICKED */
if (this.checkFieldHasBeenNeverClicked(coords[0], coords[1])) {
var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red';
this.state.foundUserMineCache = 0;
this.state.playBomb = true;
/** Show elements */
if (this.refs.userControl.state.bombSelected) {
this.state.sound.bomb.play();
var bombRadius = this.getBombRadius(coords[0], coords[1]);
for (var i = 0, j = bombRadius.length; i < j; i++) {
this.show(bombRadius[i][0], bombRadius[i][1], i, j);
}
/** remove BOMB from activePlayer */
this.refs.userControl.refs[activePlayer].setState({
haveBomb: false
});
} else {
this.show(coords[0], coords[1]);
}
/** Mine score handling */
if (this.state.foundUserMineCache) {
this.refs.userControl.setState({
mines: this.refs.userControl.state.mines - this.state.foundUserMineCache,
foundMines: true
}, () => {
/** because of CSS animation in .found-mine */
setTimeout(() => this.refs.userControl.setState({foundMines: false}), 500);
/** add the found mines to the active Player */
this.refs.userControl.refs[activePlayer].setState({
mines: this.refs.userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache
});
});
}
/** Reset BOMB status */
if (this.refs.userControl.state.bombSelected) {
/** reset bomb selected status */
this.refs.userControl.setState({bombSelected: false});
/** clear cache, reset symbols */
this.bombClear();
}
}
}
/**
* On Hover when you want to drop BOMB
* Target grid field
* @param coords
*/
onHoverGridField(coords) {
if (this.refs.userControl.state.bombSelected) {
var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red';
if (activePlayer === this.state.webPlayer) {
/** clear cache, reset symbols */
this.bombClear();
/** new cache && field activate */
this.bombCreate(coords[0], coords[1]);
} else {
this.refs.userControl.setState({bombSelected: false});
}
}
}
overlayClass() {
return 'game-overlay' + (this.state.overlay ? '' : ' hide');
}
renderGridFields() {
for (let i = 0, j = this.state.grid.length; i < j; i++) {
for (let k = 0, l = this.state.grid[i].length; k < l; k++) {
this.state.gridFields.push(
<GridField row={i}
col={k}
ref={this.refString(i, k)}
key={window.btoa((Math.random() * 0.5).toString())}
handleHoverOn={this.onHoverGridField.bind(this, [i, k])}
onClick={this.props.onClick.bind(null, [i, k])}/>
);
}
}
}
render() {
/** Render the grid fields just one time in one party #12 */
this.state.renderGridFields && this.renderGridFields();
this.state.renderGridFields = false;
return (
<div className="game-wrapper">
<div className={this.overlayClass()}>
<div className="game-overlay-window">
<h1>{this.state.overlayTitle}</h1>
<h2>{this.state.overlaySubTitle}</h2>
</div>
</div>
<UserControl ref="userControl"
resign={this.props.resign}
webPlayer={this.state.webPlayer}
bombClear={this.bombClear.bind(this)}/>
<div className="grid-container">
<div className="grid">
<>
{this.state.gridFields}
</>
</div>
</div>
</div>
);
}
}
export default GridControl;

View File

@@ -0,0 +1,145 @@
import React from 'react';
class GridField extends React.Component {
constructor(props) {
super(props);
this.state = {
currentObj: 'w',
currentImage: null,
active: false,
lastClickedRed: false,
lastClickedBlue: false,
bombTargetArea: null,
icons: {
root: '/images/',
water: {
1: 'bg-wave-1-outbg.png',
2: 'bg-wave-1-outbg.png',
3: 'bg-wave-2-outbg.png'
},
flag: {
red: 'bg-flag-red-outbg.png',
blue: 'bg-flag-blue-outbg.png'
},
target: {
lastBlue: 'bg-last-blue-outbg.png',
lastRed: 'bg-last-red-outbg.png',
crosshair: 'bg-target-outbg.png',
crosshairBomb: 'bg-target-bomb-outbg.png'
},
left: 'bg-left-mine-outbg.png'
}
};
}
componentWillMount() {
var wave = Math.floor(Math.random() * 3) + 1;
this.setState({
currentImage: this.state.icons.root + this.state.icons.water[wave]
});
}
classNameWhenActive() {
return 'field'
+ (this.state.active === true ? ' active' : '')
+ (this.state.active === true && this.state.currentObj === 'm' ? ' mine' : '')
+ ' color-' + this.state.currentObj;
}
currentImage() {
return isNaN(this.state.currentImage)
?
<div className="flag-mine">
<img src={this.state.currentImage}/>
<div className="flag-mine-base"></div>
</div>
: this.state.currentImage ? <div className="flag-number">{this.state.currentImage}</div> : '';
}
lastClickedClass() {
return 'field-'
+ (this.state.lastClickedRed ? 'red' : '')
+ (this.state.lastClickedBlue ? 'blue' : '') + '-last last-clicked';
}
lastClickedSrc() {
return this.state.lastClickedRed
? "/images/bg-last-red-outbg.png"
: "/images/bg-last-blue-outbg.png";
}
currentLastClicked() {
return this.state.lastClickedRed || this.state.lastClickedBlue
? <img className={this.lastClickedClass()}
src={this.lastClickedSrc()}
alt="blue last"/>
: '';
}
createBombTarget() {
if (this.state.bombTargetArea !== null) {
var vert = '', hor = '';
switch (this.state.bombTargetArea[0]) {
case 0:
vert = 'left';
break;
case 1:
vert = 'center';
break;
case 2:
vert = 'right';
break;
default:
vert = null;
break;
}
switch (this.state.bombTargetArea[1]) {
case 0:
hor = 'top';
break;
case 1:
hor = 'middle';
break;
case 2:
hor = 'bottom';
break;
default:
vert = null;
break;
}
var src = vert === null
? '/images/bg-bomb-empty-outbg.png'
: '/images/bg-bomb-' + hor + '-' + vert + '-outbg.png';
return <img className="field-bomb-target"
src={src}
alt="bomb target"/>
}
}
render() {
return (
<div className="field-wrapper"
onClick={this.props.onClick}
onMouseEnter={this.props.handleHoverOn}>
<img className="field-target"
src="/images/bg-target-outbg.png"
alt="target"/>
{this.createBombTarget()}
{this.currentLastClicked()}
<div className={this.classNameWhenActive()}>
<div className="field-corner">
{this.currentImage()}
</div>
</div>
</div>
);
}
}
export default GridField;

View File

@@ -0,0 +1,101 @@
import React from 'react';
class Grid extends React.Component {
constructor() {
super();
this.state = {
row: 16,
col: 16,
mines: 51,
set: []
};
this.state.grid = this.numberingGrid(
this.createGrid(
this.shuffleSet(
this.createSet(
this.state.set
)
)
)
);
}
createSet(obj) {
for (var i = 0, j = this.state.row * this.state.col; i < j; i++) {
obj.push(
this.state.mines > 0
? "m"
: "w"
);
this.state.mines--;
}
return obj;
}
shuffleSet(obj) {
return obj.sort(function () {
return Math.round(Math.random()) - .5;
});
}
createGrid(obj) {
var grid = [[]],
row = 0,
col = 0;
for (var i = 0, j = obj.length; i < j; i++) {
grid[row][col] = obj[i];
if (col === 15 && row !== 15) {
row++;
col = 0;
grid.push([]);
} else {
col++;
}
}
return grid;
}
checkMine(field, i, j) {
return typeof field[i] !== 'undefined' && typeof field[i][j] !== 'undefined' && field[i][j] === 'm';
}
isThereMine(obj, row, col) {
if (this.checkMine(obj, row, col)) {
return 1;
}
return 0;
}
numberingGrid(obj) {
var nbr = 0;
for (var i = 0; i < this.state.row; i++) {
for (var j = 0; j < this.state.col; j++) {
if (obj[i][j] === 'w') {
nbr = 0;
nbr += this.isThereMine(obj, i - 1, j);
nbr += this.isThereMine(obj, i - 1, j - 1);
nbr += this.isThereMine(obj, i - 1, j + 1);
nbr += this.isThereMine(obj, i, j - 1);
nbr += this.isThereMine(obj, i, j + 1);
nbr += this.isThereMine(obj, i + 1, j);
nbr += this.isThereMine(obj, i + 1, j + 1);
nbr += this.isThereMine(obj, i + 1, j - 1);
obj[i][j] = nbr;
}
}
}
return obj;
}
}
export default Grid;

View File

@@ -0,0 +1,78 @@
import React from 'react';
import User from './user';
class UserControl extends React.Component {
constructor() {
super();
/**
* activePlayer - red: 0, blue: 1
* @type {{activePlayer: boolean, mines: number, bombSelected: boolean, foundMines: boolean}}
*/
this.state = {
activePlayer: false,
mines: 51,
bombSelected: false,
foundMines: false
};
}
youCanSelectBomb(activePlayer, clickedPlayer) {
return this.refs[activePlayer].state.haveBomb &&
this.refs[activePlayer].state.enabledBomb &&
this.state.activePlayer === clickedPlayer;
}
onClickBombSelector(clickedPlayer) {
let activePlayer = this.state.activePlayer ? 'blue' : 'red';
if (this.youCanSelectBomb(activePlayer, clickedPlayer)) {
this.state.bombSelected = !this.state.bombSelected;
if (!this.state.bombSelected) {
this.props.bombClear();
}
}
}
getResignClass(webPlayer) {
let activePlayer = this.state.activePlayer === 1 ? 'blue' : 'red';
return "resign" + (webPlayer !== activePlayer ? ' disabled' : '');
}
activeMines() {
return "active-mines" + (this.state.foundMines ? ' found-mine' : '');
}
render() {
return (
<div className="users">
<User ref="blue"
color="blue"
webPlayer={this.props.webPlayer}
active={this.state.activePlayer === 1}
onClickBombSelector={this.onClickBombSelector.bind(this, 1)}/>
<div className="active-mines-container">
<i className="fa fa-star"></i>
<div className={this.activeMines()}>
<div className="active-mines-nbr">{this.state.mines}</div>
<div className="active-mines-shine"></div>
</div>
<i className="fa fa-star"></i>
</div>
<div className="clear"></div>
<User ref="red"
color="red"
webPlayer={this.props.webPlayer}
active={this.state.activePlayer === 0}
onClickBombSelector={this.onClickBombSelector.bind(this, 0)}/>
<button className={this.getResignClass(this.props.webPlayer)} onClick={this.props.resign}>
<div className="resign-shine"></div>
Resign
</button>
</div>
);
}
}
export default UserControl;

View File

@@ -0,0 +1,90 @@
import React from 'react';
class User extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "...",
desc: "",
active: props.active,
color: props.color === 'blue' ? 1 : 0,
mines: 0,
srcRoot: '/images/',
haveBomb: true,
enabledBomb: true
};
}
setColor(color) {
return 'user-container user-' + color;
}
getSrc(color) {
return this.state.srcRoot + 'bg-flag-' + color + '-outbg.png';
}
getBombBuzzClass(webPlayer) {
let activePlayer = this.state.color === 1 ? 'blue' : 'red';
return "bomb-container" +
(
this.state.active && (activePlayer === webPlayer) && this.state.haveBomb && this.state.enabledBomb
? ' buzz'
: ''
);
}
getBomb() {
let src = this.state.srcRoot;
if (this.state.haveBomb) {
src += this.state.enabledBomb && this.state.active
? 'bg-bomb-outbg.png'
: 'bg-bomb-disabled-outbg.png';
} else {
src += 'bg-bomb-exploded-outbg.png';
}
return src;
}
getFigure(color) {
return this.state.srcRoot + 'bg-figure-' + color + '-outbg.png';
}
getCursor(state, color) {
return state
? <img src={this.state.srcRoot + 'bg-cursor-' + color + '-outbg.png'} alt="cursor" className="user-cursor"/>
: '';
}
render() {
return (
<div className={this.setColor(this.props.color)}>
<div className="user-header">
<div className="user-color">{this.props.color}</div>
{this.getCursor(this.props.active, this.props.color)}
<img src={this.getFigure(this.props.color)} alt="figure"/>
</div>
<div className="user-name"> {this.state.name} </div>
<div className="user-caret"><i className="fa fa-caret-down"></i></div>
<div className="user-desc"> {this.state.desc} </div>
<div className="user-control">
<img src={this.getSrc(this.props.color)} alt="flag"/>
<div className="user-control-mines">
{this.state.mines}
</div>
<div className={this.getBombBuzzClass(this.props.webPlayer)} onClick={this.props.onClickBombSelector}>
<div className="bomb">
<img src={this.getBomb()} alt="bomb"/>
</div>
</div>
<div className="clear"></div>
</div>
</div>
);
}
}
export default User;

42
assets/js/src/build/react-dom-server.js vendored Normal file
View File

@@ -0,0 +1,42 @@
/**
* ReactDOMServer v15.3.2
*
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
;(function(f) {
// CommonJS
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f(require('react'));
// RequireJS
} else if (typeof define === "function" && define.amd) {
define(['react'], f);
// <script>
} else {
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
// works providing we're not in "use strict";
// needed for Java 8 Nashorn
// see https://github.com/facebook/react/issues/3037
g = this;
}
g.ReactDOMServer = f(g.React);
}
})(function(React) {
return React.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
});

View File

@@ -0,0 +1,12 @@
/**
* ReactDOMServer v15.3.2
*
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(require("react"));else if("function"==typeof define&&define.amd)define(["react"],e);else{var f;f="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,f.ReactDOMServer=e(f.React)}}(function(e){return e.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED});

42
assets/js/src/build/react-dom.js vendored Normal file
View File

@@ -0,0 +1,42 @@
/**
* ReactDOM v15.3.2
*
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
;(function(f) {
// CommonJS
if (typeof exports === "object" && typeof module !== "undefined") {
module.exports = f(require('react'));
// RequireJS
} else if (typeof define === "function" && define.amd) {
define(['react'], f);
// <script>
} else {
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
// works providing we're not in "use strict";
// needed for Java 8 Nashorn
// see https://github.com/facebook/react/issues/3037
g = this;
}
g.ReactDOM = f(g.React);
}
})(function(React) {
return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
});

12
assets/js/src/build/react-dom.min.js vendored Normal file
View File

@@ -0,0 +1,12 @@
/**
* ReactDOM v15.3.2
*
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(require("react"));else if("function"==typeof define&&define.amd)define(["react"],e);else{var f;f="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,f.ReactDOM=e(f.React)}}(function(e){return e.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED});

22926
assets/js/src/build/react-with-addons.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

20595
assets/js/src/build/react.js vendored Normal file

File diff suppressed because it is too large Load Diff

16
assets/js/src/build/react.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.