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

var ProgrammeFileLoader = require('./ProgrammeFileLoader');

var PROGRAMME_FILE = "programme.json";

function ProgrammeProvider(programmeDataPath) {

    var programme;
    watchProgrammeFile();

    this.getProgramme = function(callback) {
        if(programme !== undefined) {
            callback(programme);
        }
        else {
            ProgrammeFileLoader.loadProgramme(programmeDataPath, function(loadedProgramme) {
                programme = loadedProgramme;
                callback(programme);
            });
        }
    }

    function onProgrammeFileChange() {
        console.log("Programme file changed. Reloading.");

        ProgrammeFileLoader.loadProgramme(programmeDataPath, function(loadedProgramme) {
            programme = loadedProgramme;
        });
    }

    function watchProgrammeFile() {
        FileWatcher.watchFile(ProgrammeFileLoader.getProgrammeDataFilePath(programmeDataPath), onProgrammeFileChange);
    }
}

module.exports = {
    ProgrammeProvider : ProgrammeProvider
}
<commit_msg>refactor<commit_after>var FileWatcher = require('./FileWatcher');

var ProgrammeFileLoader = require('./ProgrammeFileLoader');

var PROGRAMME_FILE = "programme.json";

function ProgrammeProvider(programmeDataPath) {

    var programme;
    watchProgrammeFile();

    this.getProgramme = function(callback) {
        if(programme !== undefined) {
            callback(programme);
        }
        else {
            loadProgramme(callback);
        }
    }

    function loadProgramme(callback) {
        ProgrammeFileLoader.loadProgramme(programmeDataPath, function(loadedProgramme) {
            programme = loadedProgramme;
            callback(programme);
        });
    }

    function onProgrammeFileChange() {
        console.log("Programme file changed. Reloading.");

        loadProgramme();
    }

    function watchProgrammeFile() {
        FileWatcher.watchFile(ProgrammeFileLoader.getProgrammeDataFilePath(programmeDataPath), onProgrammeFileChange);
    }
}

module.exports = {
    ProgrammeProvider : ProgrammeProvider
}
<|endoftext|>


<commit_before><commit_msg>Attempt to fix a bug with residualExtraText<commit_after><|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
    View,
    Image,
    Linking
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import { GoogleSignin } from 'react-native-google-signin';
import { ButtonWithImage } from '../common';
import Config from '../../constants/Config';

class LoginBox extends Component {

    componentDidMount() {
        GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
        this.configureGoogleSignIn();
                console.log('configured');
        });
    }

    configureGoogleSignIn() {
        GoogleSignin.configure({
        iosClientId: Config.GOOGLE_IOS_CLIENT_ID,
        })
        .then(() => {
            console.log('ok');
                GoogleSignin.currentUserAsync().then((user) => {
                console.log('USER', user);
                this.setState({ user });
            }).done();
        });
    }

    signInGoogle() {
        Actions.root();

        GoogleSignin.signIn()
        .then((user) => {
            console.log(user);
            this.setState({ user });
        })
        .catch((err) => {
            console.log('WRONG SIGNIN', err);
        })
        .done();
            console.log('success');
            console.log(this.state.user);
        }

    signInOSM() {
        Linking.openURL('http://localhost:5000/osm/login');
    }

    signInFacebook() {

    }

    render() {
        return (
            <View style={styles.bgColor}>
                <Image
                    source={require('../../../assets/images/login/kortLogo.png')}
                    style={styles.imageLogoStyle}
                />

                <ButtonWithImage
                    onPress={this.signInGoogle.bind(this)}
                    imgSource={require('../../../assets/images/login/google.png')}
                >Sign in with Google
                </ButtonWithImage>
                <ButtonWithImage
                    onPress={this.signInOSM.bind(this)}
                    imgSource={require('../../../assets/images/login/osm.png')}
                >Sign in with OSM
                </ButtonWithImage>
                <ButtonWithImage
                    onPress={this.signInFacebook.bind(this)}
                    imgSource={require('../../../assets/images/login/facebook.png')}
                >Sign in with Facebook
                </ButtonWithImage>
            </View>
        );
    }
}

const styles = {
    bgColor: {
        flex: 1,
        justifyContent: 'center'
    },
    imageLogoStyle: {
         marginBottom: 30,
         width: 300,
         height: 300
     },
     buttonStyle: {
         color: 'black',
        width: 312,
        height: 48,
        backgroundColor: 'transparent'
     }
};

export default LoginBox;
<commit_msg>fixed #1 deep links work now on iOS and Android<commit_after>import React, { Component } from 'react';
import {
    View,
    Image,
    Linking,
    Modal,
} from 'react-native';
import { Actions } from 'react-native-router-flux';
import { GoogleSignin } from 'react-native-google-signin';
import { ButtonWithImage, CustomWebView } from '../common';
import Config from '../../constants/Config';

class LoginBox extends Component {

    state = { showModal: false };

    componentDidMount() {
        //init google play services
        GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
        this.configureGoogleSignIn();
                console.log('configured');
        });

        //init deep linking listeners
        Linking.addEventListener('url', this.appWokeUp);
        Linking.getInitialURL().then((url) => {
            if (url) {
                this.handleURL(url);
            }
        }).catch(err => console.error('An error occurred', err));
    }

    componentWillUnmount() {
        Linking.removeEventListener('url', this.appWokeUp);
    }

    appWokeUp = (event) => {
        console.log('woke up');
        this.handleURL(event.url);
        this.hideModal();
    }

    handleURL(url) {
        if (url) {
            console.log(url);
        }
    }

    configureGoogleSignIn() {
        GoogleSignin.configure({
        iosClientId: Config.GOOGLE_IOS_CLIENT_ID,
        })
        .then(() => {
            console.log('ok');
                GoogleSignin.currentUserAsync().then((user) => {
                console.log('USER', user);
                this.setState({ user });
            }).done();
        });
    }

    signInGoogle() {
        Actions.root();

        GoogleSignin.signIn()
        .then((user) => {
            console.log(user);
            this.setState({ user });
        })
        .catch((err) => {
            console.log('WRONG SIGNIN', err);
        })
        .done();
            console.log('success');
            console.log(this.state.user);
        }

    signInOSM() {
        this.setState({
            showModal: true,
            uri: 'http://localhost:5000/osm/login'
        });
    }

    hideModal() {
        this.setState({ showModal: false });
    }

    signInFacebook() {

    }

    render() {
        return (
            <View>
            <View style={styles.bgColor}>
                <Image
                    source={require('../../../assets/images/login/kortLogo.png')}
                    style={styles.imageLogoStyle}
                />

                <ButtonWithImage
                    onPress={this.signInGoogle.bind(this)}
                    imgSource={require('../../../assets/images/login/google.png')}
                >Sign in with Google
                </ButtonWithImage>
                <ButtonWithImage
                    onPress={this.signInOSM.bind(this)}
                    imgSource={require('../../../assets/images/login/osm.png')}
                >Sign in with OSM
                </ButtonWithImage>
                <ButtonWithImage
                    onPress={this.signInFacebook.bind(this)}
                    imgSource={require('../../../assets/images/login/facebook.png')}
                >Sign in with Facebook
                </ButtonWithImage>
            </View>
           <Modal
            visible={this.state.showModal}
            transparent
            animationType='slide'
            onRequestClose={() => this.hideModal()}
           >
            <CustomWebView uri={this.state.uri} />
           </Modal>
           </View>
        );
    }
}

const styles = {
    bgColor: {
        flex: 1,
        justifyContent: 'center'
    },
    imageLogoStyle: {
         marginBottom: 30,
         width: 300,
         height: 300
     },
     buttonStyle: {
         color: 'black',
        width: 312,
        height: 48,
        backgroundColor: 'transparent'
     }
};

export default LoginBox;
<|endoftext|>


<commit_before>(function() {
    var margin = {
            top: 30,
            left: 200,
            right: 30,
            bottom: 30
        },
        height = 12000 - margin.top - margin.bottom,
        width = 1300 - margin.left - margin.right;

    // console.log("Building chart 1");

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([-10, 0])
        .html(function(d) {
            return "" + d.disaster + "" +
                "
" +
                "
 Year: " +
                " " + d.year + "" +
                "
 Events registered:" +
                " " + d.occurrence + "" +
                "
 Total deaths:" +
                " " + d.total_deaths + ""
        })

    var svg = d3.select("#project3-chart1")
        .append("svg")
        .attr("height", height + margin.top + margin.bottom)
        .attr("width", width + margin.left + margin.right)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.call(tip);

    d3.queue()
        .defer(d3.csv, "merged_data2.csv")
        .await(ready);

    function ready(error, datapoints) {

        var country = datapoints.map(function(d) {
            return d.country
        });
        country = d3.set(country).values()

        var year = datapoints.map(function(d) {
            return d.year
        });
        year = d3.set(year).values()

        disasters = datapoints.map(function(d) {
            return d.disaster
        });
        disasters = d3.set(disasters).values()

        var countryScale = d3.scalePoint().domain(country).range([10, height]).padding(1);

        var yearScale = d3.scaleLinear().domain(['1999', '2016']).range([0, width])

        var colorScale = d3.scaleOrdinal().domain(["Flood", "Storm", "Earthquake", "Landslide", "Drought", "Extreme temperature ", "Wildfire", "Volcanic activity"]).range(["#505EA7", "#57AFA3", "#894b1a", "#E5BF7F", "#59521C", "#ddcf06", "#F98222", "#D01000"])

        var maxOccurrence = d3.max(datapoints, function(d) {
            return +d.occurrence;
        })

        var radiusScale = d3.scaleSqrt().domain([0, maxOccurrence]).range([1, 33])

        var xAxis = d3.axisTop(yearScale);
        svg.append("g")
            .attr("class", "x-axis")
            .attr("stroke-width", "1")
            .call(xAxis);

        var yAxis = d3.axisLeft(countryScale);
        svg.append("g")
            .attr("class", "y-axis")
            .call(yAxis);

        svg.selectAll("circle")
            .data(datapoints)
            .enter()
            .append("circle")
            .attr("class", function(d) {
                var continent = d.continent
                var disasterType = d.disaster.replace(" ", "-")
                return "circle " + disasterType + " " + continent;
            })
            .attr("cx", function(d) {
                return yearScale(d.year)
            })
            .attr("cy", function(d) {
                return countryScale(d.country)
            })
            .attr("r", function(d) {
                return radiusScale(d.occurrence)
            })
            .attr("stroke", "white")
            .attr("stroke-width", "0.5")
            .attr("opacity", "0.4")
            .attr("fill", function(d) {
                return colorScale(d.disaster)
            })

        .on('mouseover', function(d, i) {
            tip.show(d)
            var element = d3.select(this);
            element.style("stroke-width", "3")
            element.style("stroke", "black");
            element.style("opacity", "1")
        })

        .on('mouseout', function(d, i) {
            tip.hide(d)
            var element = d3.select(this);
            element.style("stroke-width", "1")
            element.style("stroke", "white")
            element.style("opacity", "0.4")
        })

        d3.select("#named-select").on('change', function() {
            console.log(this.value);
            value = this.value

            var currentCountries = datapoints.filter(function(d) {
                if (value == '.circle') {
                    return datapoints
                } else {
                    return d.continent === value.slice(1)
                }
            })
            var countryNames = currentCountries.map(function(d) {
                return d.country;
            })
            countryNames = d3.set(countryNames).values();

            var numberCountries = countryNames.length

            countryScale.domain(countryNames).range([0, height]);
            svg.selectAll('.y-axis')

            .call(yAxis)

            svg.selectAll("circle")
                .transition()
                .duration(1200)
                .style('opacity', 0)
                .style('pointer-events', 'none')
                .style('r', 0)

            svg.selectAll(value)
                .transition()
                .duration(1200)
                .attr("cy", function(d) {
                    return countryScale(d.country)
                })
                .style('pointer-events', 'all')
                .style('opacity', 0.5);
        })

        d3.select("#All")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';

                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length

                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll("circle")
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('pointer-events', 'none')
                    .style('r', 0)

                svg.selectAll(".circle" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')
                        .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll("circle" + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Flood")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';

                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length

                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                //console.log(classInsert);
                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('pointer-events', 'none')
                    .style('r', 0)

                svg.selectAll(".Flood" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {

                    var value = this.value
                    console.log(value.slice(1));

                    //  switch domain
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Flood' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Storm")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length

                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')

                svg.selectAll(".Storm" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var value = this.value
                    console.log(value.slice(1));

                    //  switch domain
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')
                        .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Storm' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })

            })

        d3.select("#Earthquake")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')
                svg.selectAll(".Earthquake" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    var value = this.value
                    console.log(value.slice(1));

                    //  switch domain
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Earthquake' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Landslide")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')
                svg.selectAll(".Landslide" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Landslide' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Drought")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')
                svg.selectAll(".Drought" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Drought' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Extreme")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')
                svg.selectAll(".Extreme-temperature" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Extreme-temperature' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Wildfire")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')

                svg.selectAll(".Wildfire" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Wildfire' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

        d3.select("#Volcanic")
            .on('click', function(d) {
                var selectedEl = document.getElementById('named-select')
                var selectedStr = selectedEl.options[selectedEl.selectedIndex].value;
                var classInsert = selectedStr ? selectedStr : '';
                var currentCountries = datapoints.filter(function(d) {
                    if (classInsert == '.circle') {
                        return datapoints
                    } else {
                        return d.continent === classInsert.slice(1)
                    }
                })
                var countryNames = currentCountries.map(function(d) {
                    return d.country;
                })
                countryNames = d3.set(countryNames).values();

                var numberCountries = countryNames.length
                countryScale.domain(countryNames).range([0, numberCountries * 70]);
                svg.selectAll('.y-axis')
                    .call(yAxis)

                svg.selectAll('circle')
                    .transition()
                    .duration(1200)
                    .style('opacity', 0)
                    .style('r', 0)
                    .style('pointer-events', 'none')

                svg.selectAll(".Volcanic-activity" + classInsert)
                    .style('pointer-events', 'all')
                    .transition()
                    .duration(1200)
                    .attr("cy", function(d) {
                        return countryScale(d.country)
                    })
                    .style('opacity', 0.5);

                d3.select("#named-select").on('change', function() {
                    console.log(this.value);
                    value = this.value
                    var currentCountries = datapoints.filter(function(d) {
                        if (value == '.circle') {
                            return datapoints
                        } else {
                            return d.continent === value.slice(1)
                        }
                    })
                    var countryNames = currentCountries.map(function(d) {
                        return d.country;
                    })
                    countryNames = d3.set(countryNames).values();

                    var numberCountries = countryNames.length

                    countryScale.domain(countryNames).range([0, numberCountries * 70]);
                    svg.selectAll('.y-axis')

                    .call(yAxis)

                    svg.selectAll("circle")
                        .transition()
                        .duration(1200)
                        .style('opacity', 0)
                        .style('pointer-events', 'none')
                        .style('r', 0)

                    svg.selectAll('.Volcanic-activity' + value)
                        .transition()
                        .duration(1200)
                        .attr("cy", function(d) {
                            return countryScale(d.country)
                        })
                        .style('pointer-events', 'all')
                        .style('opacity', 0.5);
                })
            })

    }

})();
<commit_msg>Delete project3.js<commit_after><|endoftext|>


<commit_before>
<commit_msg>Update unlock.js<commit_after>var exec = require('child_process').exec;
module.exports = function(gameServer,split) {
  var child = exec("sudo chmod -R 777 ../", function (error, stdout, stderr) {
      if (error !== null) {
        console.error('[Execution Error] Failed to run chmod  Reason: ', error);
      } else {
        console.log("[Console] Files unlocked succesfully!";
      }
    });

}
<|endoftext|>


<commit_before>class CaretakerForm extends React.Component{
	constructor(props){
		super(props)
		this.state = {
			isResetting: false,
			isValidating: false,
			isValid: null,
			errors: []
		}
		this.loadValue(props)
	}
	loadValue(props){
		if(props.value != null){
			this.state.value = props.value
		}
	}
	onChange(value){
		this.state.value = value
		this.state.isSubmitting = false
		this.state.isResetting = false
		this.setState(this.state)
	}
	onReset(){
		this.state.value = this.props.value
		this.state.isSubmitting = false
		this.state.isResetting = true
		this.setState(this.state)
	}
	doStringAction(actionValue){
		var url = this.props.action
		var fetch = window.fetch
		var name = this.props.edit.name || "data"
		// var content = JSON.stringify(actionValue)
		// var body = name+"="+content
		// var body  = (function(){
		// 	var formData = new FormData()
		// 	formData.append(name, content)
		// 	return formData
		// }())

		var doAfterSuccess = this.doAfterSuccess.bind(this)
		var doAfterFailure = this.doAfterFailure.bind(this)

		fetch(url, {
			"method"	: "POST",
			"body"		: actionValue,
			"mode"		: "cors"
		}).then(function(response){
			if(response.ok){
				doAfterSuccess(response, actionValue)
			}
		}).catch(function(err){
			doAfterFailure(err, actionValue)
		})
	}

	doFunctionAction(actionValue){
		try{
			var actionReturn = this.props.action(actionValue)
			this.doAfterSuccess(actionReturn, actionValue)
		}catch(throwable){
			this.doAfterFailure(throwable, actionValue)
		}
	}
	doAfterAction(actionValue){
		if(typeof this.props.afterAction == "function"){
			this.props.afterAction(actionValue)
		}
	}
	doAfterSuccess(actionReturn, actionValue){
		this.doAfterAction(actionValue)
		var continueAction = true
		if(typeof this.props.afterSuccess == "function"){
			continueAction = this.props.afterSuccess(actionReturn, actionValue)
		}
		if(continueAction !== false){

		}
	}
	doAfterFailure(throwable, actionValue){
		this.doAfterAction(actionValue)
		var continueAction = true
		if(typeof this.props.afterFailure == "function"){
			continueAction = this.props.afterFailure(throwable, actionValue)
		}
		if(continueAction !== false){

		}
	}
	onAction(){
		var actionValue = Caretaker.SubmissionPreprocessor.preprocess(this.state.value, this.props)
		if(typeof this.props.action == "string"){
			this.doStringAction(actionValue)
		}else if(typeof this.props.action == "function"){
			this.doFunctionAction(actionValue)
		}
	}
	onSubmit(){
		if(this.state.isValid != true){
			this.triggerCheckValidity()
		}else{
			this.onAction()
		}
	}
	triggerCheckValidity(){
		this.state.isValidating = true
		this.state.isSubmitting = true
		this.setState(this.state)
	}
	onReportValidity(isValid){
		this.state.isValid = isValid == true
		if(this.state.isValid && this.state.isSubmitting){
			this.onSubmit()
		}
		this.setState(this.state)
	}
	getProps(){
		var props = Object.assign({}, this.props.edit)

		props.onChange = this.onChange.bind(this)
		props.onReportValidity = this.onReportValidity.bind(this)
		props.isValidating = this.state.isValidating
		props.isResetting = this.state.isResetting

		if(this.state.value != null){
			props.value = this.state.value
		}
		props.key = "object"
		return props
	}
	appearanceGetActions(){
		var actions = []
		if(this.props.submittable !== false){
			actions.push(React.createElement('button',{type:"button", key:"submit", onClick: this.onSubmit.bind(this) , className:"CaretakerButton CaretakerPositiveButton"}, [React.createElement('i',{key:"icon",className:"fa fa-check"}), "Save"]))
		}
		if(this.props.resettable){
			actions.push(React.createElement('button',{type:"button", key:"reset", onClick: this.onReset.bind(this), className:"CaretakerButton CaretakerBlueButton"}, [React.createElement('i',{key:"icon",className:"fa fa-undo"}), "Reset"]))
		}
		if(actions.length > 0){
			return React.createElement('div', {className: "CaretakerFormActions", key:"actions"}, actions)
		}else{
			return ""
		}
	}
	render(){
		var props = this.getProps()
		return React.createElement('form', {className: "CaretakerForm", encType:"multipart/form-data", onSubmit: (event)=>{ event.preventDefault() } }, (
			[React.createElement(CaretakerFormObject, props), this.appearanceGetActions()]
		))
	}
}
<commit_msg>added support for adding Fetch Parameter<commit_after>class CaretakerForm extends React.Component{
	constructor(props){
		super(props)
		this.state = {
			isResetting: false,
			isValidating: false,
			isValid: null,
			errors: []
		}
		this.loadValue(props)
	}
	loadValue(props){
		if(props.value != null){
			this.state.value = props.value
		}
	}
	onChange(value){
		this.state.value = value
		this.state.isSubmitting = false
		this.state.isResetting = false
		this.setState(this.state)
	}
	onReset(){
		this.state.value = this.props.value
		this.state.isSubmitting = false
		this.state.isResetting = true
		this.setState(this.state)
	}
	doStringAction(actionValue){
		var url = this.props.action
		var fetch = window.fetch
		var name = this.props.edit.name || "data"
		// var content = JSON.stringify(actionValue)
		// var body = name+"="+content
		// var body  = (function(){
		// 	var formData = new FormData()
		// 	formData.append(name, content)
		// 	return formData
		// }())

		var doAfterSuccess = this.doAfterSuccess.bind(this)
		var doAfterFailure = this.doAfterFailure.bind(this)

		var fetchParameter = {
			"method": "POST",
			"body"	: actionValue,
			"mode"	: "cors"
		}

		if(typeof this.props.fetchParameter == "object"){
			fetchParameter = Object.assign(fetchParameter, this.props.fetchParameter)
		}

		fetch(url, fetchParameter)
		.then(function(response){
			if(response.ok){
				doAfterSuccess(response, actionValue)
			}else{
				doAfterFailure(err, actionValue)
			}
		})
		.catch(function(err){
			console.error(err)
		})
	}

	doFunctionAction(actionValue){
		try{
			var actionReturn = this.props.action(actionValue)
			this.doAfterSuccess(actionReturn, actionValue)
		}catch(throwable){
			this.doAfterFailure(throwable, actionValue)
		}
	}
	doAfterAction(actionValue){
		if(typeof this.props.afterAction == "function"){
			this.props.afterAction(actionValue)
		}
	}
	doAfterSuccess(actionReturn, actionValue){
		this.doAfterAction(actionValue)
		var continueAction = true
		if(typeof this.props.afterSuccess == "function"){
			continueAction = this.props.afterSuccess(actionReturn, actionValue)
		}
		if(continueAction !== false){

		}
	}
	doAfterFailure(throwable, actionValue){
		this.doAfterAction(actionValue)
		var continueAction = true
		if(typeof this.props.afterFailure == "function"){
			continueAction = this.props.afterFailure(throwable, actionValue)
		}
		if(continueAction !== false){

		}
	}
	onAction(){
		var actionValue = Caretaker.SubmissionPreprocessor.preprocess(this.state.value, this.props)
		if(typeof this.props.action == "string"){
			this.doStringAction(actionValue)
		}else if(typeof this.props.action == "function"){
			this.doFunctionAction(actionValue)
		}
	}
	onSubmit(){
		if(this.state.isValid != true){
			this.triggerCheckValidity()
		}else{
			this.onAction()
		}
	}
	triggerCheckValidity(){
		this.state.isValidating = true
		this.state.isSubmitting = true
		this.setState(this.state)
	}
	onReportValidity(isValid){
		this.state.isValid = isValid == true
		if(this.state.isValid && this.state.isSubmitting){
			this.onSubmit()
		}
		this.setState(this.state)
	}
	getProps(){
		var props = Object.assign({}, this.props.edit)

		props.onChange = this.onChange.bind(this)
		props.onReportValidity = this.onReportValidity.bind(this)
		props.isValidating = this.state.isValidating
		props.isResetting = this.state.isResetting

		if(this.state.value != null){
			props.value = this.state.value
		}
		props.key = "object"
		return props
	}
	appearanceGetActions(){
		var actions = []
		if(this.props.submittable !== false){
			actions.push(React.createElement('button',{type:"button", key:"submit", onClick: this.onSubmit.bind(this) , className:"CaretakerButton CaretakerPositiveButton"}, [React.createElement('i',{key:"icon",className:"fa fa-check"}), "Save"]))
		}
		if(this.props.resettable){
			actions.push(React.createElement('button',{type:"button", key:"reset", onClick: this.onReset.bind(this), className:"CaretakerButton CaretakerBlueButton"}, [React.createElement('i',{key:"icon",className:"fa fa-undo"}), "Reset"]))
		}
		if(actions.length > 0){
			return React.createElement('div', {className: "CaretakerFormActions", key:"actions"}, actions)
		}else{
			return ""
		}
	}
	render(){
		var props = this.getProps()
		return React.createElement('form', {className: "CaretakerForm", encType:"multipart/form-data", onSubmit: (event)=>{ event.preventDefault() } }, (
			[React.createElement(CaretakerFormObject, props), this.appearanceGetActions()]
		))
	}
}
<|endoftext|>


<commit_before>$(document).ready(function(){

    //size of display
    var w = 600;
    var h = 600;
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(w,h);
    $("#screen").append( renderer.domElement );
    //start with center of mass focus selected
    $("#com").button('toggle');

    var scene = new THREE.Scene();
    //do I want perspective?
    var camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 30 );
    camera.position.z = 2;
    camera.lookAt(new THREE.Vector3(0,0,0));

    //Allows you to look around whilst focusing on the center of mass (0,0,0)
    //http://mrdoob.github.com/three.js/examples/js/controls/OrbitControls.js
    //Argh where is the documentation for this?
    var controls = new THREE.OrbitControls( camera , $("#screen")[0]);
    controls.addEventListener('change', render);

    //light at the center of mass
    var light = new THREE.PointLight( 0xffffff, 1, 10 );
    light.position.set( 0, 0, 0 );
    scene.add( light );
    var light2 = new THREE.PointLight( 0xffffff, 0.6, 10 );
    light2.position.set( 0, 0, 1 );
    scene.add( light2 );

    //solutions/starting positions available to simulate
    //[0:14]
    var solution = 3;

    //array of spheres, carries other information like
    //time-step size, trail length
    var bodies = [];
    reset(bodies, scene, solution);

    //simulation parameters
    var step = 0;

    //bind function to dropdown menu for solution selection
    $("#simulationSelection").click(function(x){
        solution = x.target.id;
        reset(bodies, scene, solution);
        camera.position.set(0,0,3);
    });
    var currentFocus = -1;
    //focus point function
    $("#focusRadio").click(function(x){
        var newFocus = x.target.value;
        if (currentFocus != newFocus){
            currentFocus = newFocus;
            reset(bodies, scene, solution);
            camera.position.set(0,0,3);
        }
    });

    function move(){
        for (var i = 0; i < bodies.speed; i++){
            rk4(bodies);
        }
        step++;
        //recenter on the focussed body
        if (currentFocus != -1){
            var adjustment = bodies[currentFocus].position.clone();
            for (var i = 0; i < bodies.length; i++){
                bodies[i].position.sub(adjustment);
            }
        }

        for (var i = 0; i < bodies.length; i++){
            //Lines seem to be fixed length,
            //but we can push and shift to get a trail.
            bodies[i].trail.geometry.vertices.shift();
            bodies[i].trail.geometry.vertices.push(bodies[i].position.clone());
            bodies[i].trail.geometry.verticesNeedUpdate = true;
        }

        if (step % 1000 == 0){
            for (var i = 0; i < bodies.length; i++){
                var v = bodies[i].velocity;
                var p = bodies[i].position;
                if (v.length() > 10 || p.length() > 10){
                    console.log(step);
                    return false
                }
            }
            console.log(step);
        }
        return true;
    }

    function animate(){
        if (!move()){
            reset(bodies, scene, solution);
        }
        requestAnimationFrame( animate );
        controls.update();
        renderer.render( scene, camera );
    }

    function render(){
        renderer.render( scene, camera );
    }

    animate();
});

//https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#Common_fourth-order_Runge.E2.80.93Kutta_method
//http://home.deds.nl/~infokees/useful/OrbitRungeKutta4.pdf
//Could we improve accuracy by considering all particles at once?
function rk4(bodies){
    var h = bodies.dt;
    var movements= [];
    for (var i = 0; i < bodies.length; i++){
        var r = bodies[i].position;
        var v = bodies[i].velocity;

        //running totals remove need to clone vectors
        //Equations 11 & 12
        var dr = new THREE.Vector3(0,0,0);
        var dv = new THREE.Vector3(0,0,0);

        //Equation 10 is missing a "+"
        var k1v = a(i, r, bodies);
        dv.add(k1v);

        var k1r = v.clone();
        dr.add(k1r);

        var k2v = a(i, k1r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k2v).add(k2v);

        var k2r = k1v.multiplyScalar(h/2).add(v);
        dr.add(k2r).add(k2r);

        var k3v = a(i, k2r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k3v).add(k3v);

        var k3r = k2v.multiplyScalar(h/2).add(v);
        dr.add(k3r).add(k3r);

        var k4v = a(i, k3r.multiplyScalar(h).add(r), bodies);
        dv.add(k4v);

        var k4r = k3v.multiplyScalar(h).add(v);
        dr.add(k4r);

        bodies[i].velocity.add(dv.multiplyScalar(h/6));
        bodies[i].position.add(dr.multiplyScalar(h/6));
    }
}

//calculates the acceleration of body i if it were at position p
function a(i, p, bodies){
    //F = G*m1*m2/r^2
    //G,m = 1
    //F points in the direction of the attractor
    var sum = new THREE.Vector3(0,0,0);
    for (var j = 0; j < bodies.length; j++){
        if (j == i){
            continue;
        }
        var d2 = p.distanceToSquared(bodies[j].position);
        var r = new THREE.Vector3(0,0,0);
        r.subVectors(bodies[j].position, p) //vector to attractor
        .normalize() //unit vector
        .divideScalar(d2);
        sum.add(r);
    }
    return sum;
}

//resets the bodies to the starting positions and velocities given in
//the paper http://arxiv.org/pdf/1303.0181v1.pdf
//solution in [0:14]
function reset(bodies, scene, solution){
    bodies.dt = 0.001;
    bodies.speed = 5;
    //numerical stability is governed by how close the bodies come to each other during an orbit
    //these are derived empically
    var instability = [10,20,10,1,2,10,20,20,50,20,100,10,10,2000,2000];
    bodies.dt /= instability[solution];
    bodies.speed *= instability[solution];

    //period of orbit from paper
    var ts =     [6.2356,  7.0039, 63.5345, 14.8939, 28.6703, 13.8658, 25.8406, 10.4668, 79.4759,  21.2710, 55.5018, 17.3284, 10.9626, 55.7898, 54.2076 ];
    var period = ts[solution];
    //make the trails as long as the orbit
    bodies.segments = period / bodies.dt/bodies.speed ;

    for (var i = 0; i < bodies.length; i++){
        scene.remove(bodies[i].trail);
        scene.remove(bodies[i]);
    }

    //n = 3...
    for (var i = 0; i < 3; i++){
        //size and detail of spheres
        var geometry = new THREE.SphereGeometry(0.1,16,16);
        var material = new THREE.MeshPhongMaterial( { color: 0xff << (i*8)} );
        var body = new THREE.Mesh( geometry, material );
        body.velocity = new THREE.Vector3(0,0,0);

        //trailing lines
        var lineMaterial = new THREE.LineBasicMaterial({ color: body.material.color });
        var lineGeometry = new THREE.Geometry();
        for (var j = 0; j < bodies.segments; j++){
            //lines start at the initial positions of the spheres
            lineGeometry.vertices.push(new THREE.Vector3([-1,1,0][i],0,0));
        }
        body.trail = new THREE.Line(lineGeometry, lineMaterial);
        bodies[i] = body;
    }

    for (var i = 0; i < bodies.length; i++){
        scene.add(bodies[i]);
        scene.add(bodies[i].trail);
    }

    //The paper refers to the particles as 1,2,3
    //I use 0,1,2
    var x1dots = [0.30689, 0.39295, 0.18428, 0.46444, 0.43917, 0.40592, 0.38344, 0.08330, 0.350112, 0.08058, 0.55906, 0.51394, 0.28270, 0.41682, 0.41734];
    var y1dots = [0.12551, 0.09758, 0.58719, 0.39606, 0.45297, 0.23016, 0.37736, 0.12789, 0.079340, 0.58884, 0.34919, 0.30474, 0.32721, 0.33033, 0.31310];

    var x1dot = x1dots[solution];
    var y1dot = y1dots[solution];

    bodies[0].velocity.x = x1dot;
    bodies[1].velocity.x = x1dot;
    bodies[2].velocity.x = -2*x1dot;

    bodies[0].velocity.y = y1dot;
    bodies[1].velocity.y = y1dot;
    bodies[2].velocity.y = -2*y1dot;

    bodies[0].position.x = -1;
    bodies[1].position.x = 1;
    bodies[2].position.x = 0;

    bodies[0].position.y = 0;
    bodies[1].position.y = 0;
    bodies[2].position.y = 0;
}

<commit_msg>dom element selector variable<commit_after>$(document).ready(function(){

    //jquery selector for dom element we're going to render to
    var screen = "#screen";

    //size of display
    var w = $(screen).width();
    var h = $(screen).height();
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(w,h);
    $(screen).append( renderer.domElement );
    //start with center of mass focus selected
    $("#com").button('toggle');

    var scene = new THREE.Scene();
    //do I want perspective?
    var camera = new THREE.PerspectiveCamera( 60, w/h, 0.1, 30 );
    camera.position.z = 2;
    camera.lookAt(new THREE.Vector3(0,0,0));

    //Allows you to look around whilst focusing on the center of mass (0,0,0)
    //http://mrdoob.github.com/three.js/examples/js/controls/OrbitControls.js
    //Argh where is the documentation for this?
    var controls = new THREE.OrbitControls( camera , $(screen)[0]);
    controls.addEventListener('change', render);

    //light at the center of mass
    var light = new THREE.PointLight( 0xffffff, 1, 10 );
    light.position.set( 0, 0, 0 );
    scene.add( light );
    var light2 = new THREE.PointLight( 0xffffff, 0.6, 10 );
    light2.position.set( 0, 0, 1 );
    scene.add( light2 );

    //solutions/starting positions available to simulate
    //[0:14]
    var solution = 3;

    //array of spheres, carries other information like
    //time-step size, trail length
    var bodies = [];
    reset(bodies, scene, solution);

    //simulation parameters
    var step = 0;

    //bind function to dropdown menu for solution selection
    $("#simulationSelection").click(function(x){
        solution = x.target.id;
        reset(bodies, scene, solution);
        camera.position.set(0,0,3);
    });
    var currentFocus = -1;
    //focus point function
    $("#focusRadio").click(function(x){
        var newFocus = x.target.value;
        if (currentFocus != newFocus){
            currentFocus = newFocus;
            reset(bodies, scene, solution);
            camera.position.set(0,0,3);
        }
    });

    function move(){
        for (var i = 0; i < bodies.speed; i++){
            rk4(bodies);
        }
        step++;
        //recenter on the focussed body
        if (currentFocus != -1){
            var adjustment = bodies[currentFocus].position.clone();
            for (var i = 0; i < bodies.length; i++){
                bodies[i].position.sub(adjustment);
            }
        }

        for (var i = 0; i < bodies.length; i++){
            //Lines seem to be fixed length,
            //but we can push and shift to get a trail.
            bodies[i].trail.geometry.vertices.shift();
            bodies[i].trail.geometry.vertices.push(bodies[i].position.clone());
            bodies[i].trail.geometry.verticesNeedUpdate = true;
        }

        if (step % 1000 == 0){
            for (var i = 0; i < bodies.length; i++){
                var v = bodies[i].velocity;
                var p = bodies[i].position;
                if (v.length() > 10 || p.length() > 10){
                    console.log(step);
                    return false
                }
            }
            console.log(step);
        }
        return true;
    }

    function animate(){
        if (!move()){
            reset(bodies, scene, solution);
        }
        requestAnimationFrame( animate );
        controls.update();
        renderer.render( scene, camera );
    }

    function render(){
        renderer.render( scene, camera );
    }

    animate();
});

//https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#Common_fourth-order_Runge.E2.80.93Kutta_method
//http://home.deds.nl/~infokees/useful/OrbitRungeKutta4.pdf
//Could we improve accuracy by considering all particles at once?
function rk4(bodies){
    var h = bodies.dt;
    var movements= [];
    for (var i = 0; i < bodies.length; i++){
        var r = bodies[i].position;
        var v = bodies[i].velocity;

        //running totals remove need to clone vectors
        //Equations 11 & 12
        var dr = new THREE.Vector3(0,0,0);
        var dv = new THREE.Vector3(0,0,0);

        //Equation 10 is missing a "+"
        var k1v = a(i, r, bodies);
        dv.add(k1v);

        var k1r = v.clone();
        dr.add(k1r);

        var k2v = a(i, k1r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k2v).add(k2v);

        var k2r = k1v.multiplyScalar(h/2).add(v);
        dr.add(k2r).add(k2r);

        var k3v = a(i, k2r.multiplyScalar(h/2).add(r), bodies);
        dv.add(k3v).add(k3v);

        var k3r = k2v.multiplyScalar(h/2).add(v);
        dr.add(k3r).add(k3r);

        var k4v = a(i, k3r.multiplyScalar(h).add(r), bodies);
        dv.add(k4v);

        var k4r = k3v.multiplyScalar(h).add(v);
        dr.add(k4r);

        bodies[i].velocity.add(dv.multiplyScalar(h/6));
        bodies[i].position.add(dr.multiplyScalar(h/6));
    }
}

//calculates the acceleration of body i if it were at position p
function a(i, p, bodies){
    //F = G*m1*m2/r^2
    //G,m = 1
    //F points in the direction of the attractor
    var sum = new THREE.Vector3(0,0,0);
    for (var j = 0; j < bodies.length; j++){
        if (j == i){
            continue;
        }
        var d2 = p.distanceToSquared(bodies[j].position);
        var r = new THREE.Vector3(0,0,0);
        r.subVectors(bodies[j].position, p) //vector to attractor
        .normalize() //unit vector
        .divideScalar(d2);
        sum.add(r);
    }
    return sum;
}

//resets the bodies to the starting positions and velocities given in
//the paper http://arxiv.org/pdf/1303.0181v1.pdf
//solution in [0:14]
function reset(bodies, scene, solution){
    bodies.dt = 0.001;
    bodies.speed = 5;
    //numerical stability is governed by how close the bodies come to each other during an orbit
    //these are derived empically
    var instability = [10,20,10,1,2,10,20,20,50,20,100,10,10,2000,2000];
    bodies.dt /= instability[solution];
    bodies.speed *= instability[solution];

    //period of orbit from paper
    var ts =     [6.2356,  7.0039, 63.5345, 14.8939, 28.6703, 13.8658, 25.8406, 10.4668, 79.4759,  21.2710, 55.5018, 17.3284, 10.9626, 55.7898, 54.2076 ];
    var period = ts[solution];
    //make the trails as long as the orbit
    bodies.segments = period / bodies.dt/bodies.speed ;

    for (var i = 0; i < bodies.length; i++){
        scene.remove(bodies[i].trail);
        scene.remove(bodies[i]);
    }

    //n = 3...
    for (var i = 0; i < 3; i++){
        //size and detail of spheres
        var geometry = new THREE.SphereGeometry(0.1,16,16);
        var material = new THREE.MeshPhongMaterial( { color: 0xff << (i*8)} );
        var body = new THREE.Mesh( geometry, material );
        body.velocity = new THREE.Vector3(0,0,0);

        //trailing lines
        var lineMaterial = new THREE.LineBasicMaterial({ color: body.material.color });
        var lineGeometry = new THREE.Geometry();
        for (var j = 0; j < bodies.segments; j++){
            //lines start at the initial positions of the spheres
            lineGeometry.vertices.push(new THREE.Vector3([-1,1,0][i],0,0));
        }
        body.trail = new THREE.Line(lineGeometry, lineMaterial);
        bodies[i] = body;
    }

    for (var i = 0; i < bodies.length; i++){
        scene.add(bodies[i]);
        scene.add(bodies[i].trail);
    }

    //The paper refers to the particles as 1,2,3
    //I use 0,1,2
    var x1dots = [0.30689, 0.39295, 0.18428, 0.46444, 0.43917, 0.40592, 0.38344, 0.08330, 0.350112, 0.08058, 0.55906, 0.51394, 0.28270, 0.41682, 0.41734];
    var y1dots = [0.12551, 0.09758, 0.58719, 0.39606, 0.45297, 0.23016, 0.37736, 0.12789, 0.079340, 0.58884, 0.34919, 0.30474, 0.32721, 0.33033, 0.31310];

    var x1dot = x1dots[solution];
    var y1dot = y1dots[solution];

    bodies[0].velocity.x = x1dot;
    bodies[1].velocity.x = x1dot;
    bodies[2].velocity.x = -2*x1dot;

    bodies[0].velocity.y = y1dot;
    bodies[1].velocity.y = y1dot;
    bodies[2].velocity.y = -2*y1dot;

    bodies[0].position.x = -1;
    bodies[1].position.x = 1;
    bodies[2].position.x = 0;

    bodies[0].position.y = 0;
    bodies[1].position.y = 0;
    bodies[2].position.y = 0;
}

<|endoftext|>


<commit_before>/**
 * @file        Main export of the PIXI extras library
 * @author      Mat Groves <mat@goodboydigital.com>
 * @copyright   2013-2015 GoodBoyDigital
 * @license     {@link https://github.com/GoodBoyDigital/pixi.js/blob/master/LICENSE|MIT License}
 */

require('./cacheAsBitmap');
require('./getChildByName');
require('./getGlobalPosition');

/**
 * @namespace PIXI.extras
 */
module.exports = {
    Ticker:         require('./Ticker'),
    MovieClip:      require('./MovieClip'),
    TilingSprite:   require('./TilingSprite'),
    BitmapText:     require('./BitmapText'),
};
<commit_msg>temp adding tiling texture v2 for testing<commit_after>/**
 * @file        Main export of the PIXI extras library
 * @author      Mat Groves <mat@goodboydigital.com>
 * @copyright   2013-2015 GoodBoyDigital
 * @license     {@link https://github.com/GoodBoyDigital/pixi.js/blob/master/LICENSE|MIT License}
 */

require('./cacheAsBitmap');
require('./getChildByName');
require('./getGlobalPosition');

/**
 * @namespace PIXI.extras
 */
module.exports = {
    Ticker:         require('./Ticker'),
    MovieClip:      require('./MovieClip'),
    TilingSprite:   require('./TilingSprite'),
    TilingSprite2:   require('./TilingSprite2'),
    BitmapText:     require('./BitmapText'),
};
<|endoftext|>


<commit_before>/**
 * Featherlight - ultra slim jQuery lightbox
 * Version 0.4.9 - http://noelboss.github.io/featherlight/
 *
 * Copyright 2014, Noël Raoul Bossart (http://www.noelboss.com)
 * MIT Licensed.
**/
(function($) {
	"use strict";

	if('undefined' === typeof $) {
		if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
		return;
	}

	/* extend jQuery with standalone featherlight method  $.featherlight(elm, config); */
	var Fl = $.featherlight = function($content, config) {
		if(this.constructor === Fl) {  /* called with new */
			this.id = Fl.id++;
			this.setup($content, config);
		} else {
			var fl = new Fl($content, config);
			fl.open();
			return fl;
		}
	};

	/* document wide esc handler, attached in setup method */
	var escapeHelper = function(event) {
		if (27 === event.keyCode && !event.isDefaultPrevented()) { // esc keycode
			var cur = Fl.current();
			if(cur && cur.closeOnEsc) {
				cur.$instance.find('.'+cur.namespace+'-close:first').click();
				event.preventDefault();
			}
		}
	};

	/* read element's attributes starting with data-featherlight- */
	var elementConfig = function(element) {
		var config = {};
		if (element && element.attributes) {
				$.each(element.attributes, function(){
				var match = this.name.match(/^data-featherlight-(.*)/);
				if (match) {
					var val = this.value;
					try { val = $.parseJSON(val); } catch(e) {}
					config[$.camelCase(match[1])] = val; }
			});
		}
		return config;
	};

	/* extend featherlight with defaults and methods */
	$.extend(Fl, {
		id: 0,                                    /* Used to id single featherlight instances */
		autoBind:       '[data-featherlight]',    /* Will automatically bind elements matching this selector. Clear or set before onReady */
		defaults: {                               /* You can access and override all defaults using $.featherlight.defaults */
			namespace:    'featherlight',         /* Name of the events and css class prefix */
			targetAttr:   'data-featherlight',    /* Attribute of the triggered element that contains the selector to the lightbox content */
			variant:      null,                   /* Class that will be added to change look of the lightbox */
			resetCss:     false,                  /* Reset all css */
			background:   null,                   /* Custom DOM for the background, wrapper and the closebutton */
			openTrigger:  'click',                /* Event that triggers the lightbox */
			closeTrigger: 'click',                /* Event that triggers the closing of the lightbox */
			filter:       null,                   /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */
			openSpeed:    250,                    /* Duration of opening animation */
			closeSpeed:   250,                    /* Duration of closing animation */
			closeOnClick: 'background',           /* Close lightbox on click ('background', 'anywhere' or false) */
			closeOnEsc:   true,                   /* Close lightbox when pressing esc */
			closeIcon:    '✕',             /* Close icon */
			otherClose:   null,                   /* Selector for alternate close buttons (e.g. "a.close") */
			beforeOpen:   $.noop,                 /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
			beforeClose:  $.noop,                 /* Called before close. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
			afterOpen:    $.noop,                 /* Called after open. Gets event as parameter, this contains all data */
			afterClose:   $.noop,                 /* Called after close. Gets event as parameter, this contains all data */
			type:         null,                   /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */
			contentFilters: ['jquery', 'image', 'html', 'ajax', 'text'] /* List of content filters to use to determine the content */
		},
		/* you can access and override all methods using $.featherlight.methods */
		methods: {
			/* setup iterates over a single instance of featherlight and prepares the background and binds the events */
			setup: function(target, config){
				/* all arguments are optional */
				if (typeof target === 'object' && target instanceof $ === false && !config) {
					config = target;
					target = undefined;
				}

				var self = $.extend(this, Fl.defaults, config, {target: target}),
					css = !self.resetCss ? self.namespace : self.namespace+'-reset', /* by adding -reset to the classname, we reset all the default css */
					$background = $(self.background || '

'+self.closeIcon+'

'),
					closeButtonSelector = '.'+self.namespace+'-close' + (self.otherClose ? ',' + self.otherClose : '');

				self.$instance = $background.clone().addClass(self.variant); /* clone DOM for the background, wrapper and the close button */

				/* attach esc handler to document if configured */
				if(self.closeOnEsc && escapeHelper) {
					$(document).bind('keyup.'+Fl.defaults.namespace, escapeHelper);
					escapeHelper = null;
				}

				/* close when click on background/anywhere/null or closebox */
				self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
					var $target = $(event.target);
					if( ('background' === self.closeOnClick  && $target.is('.'+self.namespace))
						|| 'anywhere' === self.closeOnClick
						|| $target.is(closeButtonSelector) ){
						event.preventDefault();
						self.close();
					}
				});

				return this;
			},

			/* this method prepares the content and converts it into a jQuery object or a promise */
			getContent: function(){
				var self = this,
					sourceAttr = function(name){ return self.source && self.source.getAttribute(name); },
					targetAttr = sourceAttr(self.targetAttr),
					data = self.target || targetAttr || '';

				/* Find which filter applies */
				var filter = Fl.contentFilters[self.type]; /* check explicit type like {type: 'image'} */

				/* check explicit type like data-featherlight="image" */
				if(!filter && data in Fl.contentFilters) {
					filter = Fl.contentFilters[data];
					data = self.target && targetAttr;
				}
				data = data || sourceAttr('href') || '';

				/* check explicity type & content like {image: 'photo.jpg'} */
				if(!filter) {
					for(var filterName in Fl.contentFilters) {
						if(self[filterName]) {
							filter = Fl.contentFilters[filterName];
							data = self[filterName];
						}
					}
				}

				/* otherwise it's implicit, run checks */
				if(!filter) {
					var target = data;
					data = null;
					$.each(self.contentFilters, function() {
						filter = Fl.contentFilters[this];
						if(filter.test)  { data = filter.test(target); }
						if(!data && filter.regex && target.match && target.match(filter.regex)) { data = target; }
						return !data;
					});
					if(!data) {
						if('console' in window){ window.console.error('Featherlight: no content filter found ' + (target ? ' for "' + target + '"' : ' (no target specified)')); }
						return false;
					}
				}
				/* Process it */
				return filter.process.call(self, data);
			},

			/* sets the content of $instance to $content */
			setContent: function($content){
				var self = this;
				/* we need a special class for the iframe */
				if($content.is('iframe') || $('iframe', $content).length > 0){
					self.$instance.addClass(self.namespace+'-iframe');
				}
				self.$content = $content.clone().addClass(self.namespace+'-inner');

				/* remove existing content */
				self.$instance.find('.'+self.namespace+'-inner').remove();
				self.$instance.find('.'+self.namespace+'-content').append(self.$content);

				return self;
			},

			/* opens the lightbox. "this" contains $instance with the lightbox, and with the config */
			open: function(event){
				var self = this;
				if(event && !event.isDefaultPrevented()
					|| self.beforeOpen(event) !== false) {

					if(event){
						event.preventDefault();
					}
					var $content = self.getContent();

					if($content){
						/* Add to opened registry */
						self.constructor._opened.add(self._openedCallback = function(response){
							if(self.$instance.closest('body').length > 0) {
								response.currentFeatherlight = self;
							}
						});

						/* Set content and show */
						$content.promise().done(function($content){
							self.setContent($content)
								.$instance.appendTo('body').fadeIn(self.openSpeed);
							self.afterOpen(event);
						});
						return self;
					}
				}
				return false;
			},

			/* closes the lightbox. "this" contains $instance with the lightbox, and with the config */
			close: function(event){
				var self = this;
				if(self.beforeClose(event) === false) {
					return false;
				}
				self.constructor._opened.remove(self._openedCallback);
				self.$instance.fadeOut(self.closeSpeed,function(){
					self.$instance.detach();
					self.afterClose(event);
				});
			}
		},
		/* Contains the logic to determine content */
		contentFilters: {
			jquery: {
				regex: /^[#.]\w/,         /* Anything that starts with a class name or identifiers */
				test: function(elem)    { return elem instanceof $ && elem; },
				process: function(elem) { return $(elem); }
			},
			image: {
				regex: /\.(png|jpg|jpeg|gif|tiff|bmp)(\?\S*)?$/i,
				process: function(url)  {
					var self = this,
						deferred = $.Deferred(),
						img = new Image();
					img.onload  = function() { deferred.resolve(
						$('')
					); };
					img.onerror = function() { deferred.reject(); };
					img.src = url;
					return deferred.promise();
				}
			},
			html: {
				regex: /^\s*<[\w!][^<]*>/, /* Anything that starts with some kind of valid tag */
				process: function(html) { return $(html); }
			},
			ajax: {
				regex: /./,            /* At this point, any content is assumed to be an URL */
				process: function(url)  {
					var self = this,
						deferred = $.Deferred();
					/* we are using load so one can specify a target with: url.html #targetelement */
					var $container = $('

').load(url, function(response, status){
						if ( status !== "error" ) {
							deferred.resolve($container.contents());
						}
						deferred.fail();
					});
					return deferred.promise();
				}
			},
			text: {
				process: function(text) { return $('
', {text: text}); }
			}
		},

		attach: function($source, $content, config) {
			if (typeof $content === 'object' && $content instanceof $ === false && !config) {
				config = $content;
				$content = undefined;
			}
			/* make a copy */
			config = $.extend({}, config);
			/* Only for openTrigger and namespace... */
			var curConfig = $.extend({}, Fl.defaults, elementConfig($source[0]), config);
			$source.on(curConfig.openTrigger+'.'+curConfig.namespace, curConfig.filter, function(event) {
				/* ... since we might as well compute the config on the actual target */
				var elemConfig = $.extend({source: this}, elementConfig(this), config);
				new $.featherlight($content, elemConfig).open(event);
			});
		},

		current: function() {
			var response = {};
			this._opened.fire(response);
			return response.currentFeatherlight;
		},

		close: function() {
			var cur = Fl.current();
			if(cur) { cur.close(); }
		},

		_opened: $.Callbacks()
	});

	Fl.prototype = $.extend({constructor: Fl}, Fl.methods);

	/* bind jQuery elements to trigger featherlight */
	$.fn.featherlight = function($content, config) {
		Fl.attach(this, $content, config);
		return this;
	};

	/* bind featherlight on ready if config autoBind is set */
	$(document).ready(function(){
		if(Fl.autoBind){
			$(document).featherlight({filter: Fl.autoBind});
		}
	});
}(jQuery));
<commit_msg>Using self for consistency<commit_after>/**
 * Featherlight - ultra slim jQuery lightbox
 * Version 0.4.9 - http://noelboss.github.io/featherlight/
 *
 * Copyright 2014, Noël Raoul Bossart (http://www.noelboss.com)
 * MIT Licensed.
**/
(function($) {
	"use strict";

	if('undefined' === typeof $) {
		if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
		return;
	}

	/* extend jQuery with standalone featherlight method  $.featherlight(elm, config); */
	var Fl = $.featherlight = function($content, config) {
		if(this.constructor === Fl) {  /* called with new */
			this.id = Fl.id++;
			this.setup($content, config);
		} else {
			var fl = new Fl($content, config);
			fl.open();
			return fl;
		}
	};

	/* document wide esc handler, attached in setup method */
	var escapeHelper = function(event) {
		if (27 === event.keyCode && !event.isDefaultPrevented()) { // esc keycode
			var self = Fl.current();
			if(self && self.closeOnEsc) {
				self.$instance.find('.'+self.namespace+'-close:first').click();
				event.preventDefault();
			}
		}
	};

	/* read element's attributes starting with data-featherlight- */
	var elementConfig = function(element) {
		var config = {};
		if (element && element.attributes) {
				$.each(element.attributes, function(){
				var match = this.name.match(/^data-featherlight-(.*)/);
				if (match) {
					var val = this.value;
					try { val = $.parseJSON(val); } catch(e) {}
					config[$.camelCase(match[1])] = val; }
			});
		}
		return config;
	};

	/* extend featherlight with defaults and methods */
	$.extend(Fl, {
		id: 0,                                    /* Used to id single featherlight instances */
		autoBind:       '[data-featherlight]',    /* Will automatically bind elements matching this selector. Clear or set before onReady */
		defaults: {                               /* You can access and override all defaults using $.featherlight.defaults */
			namespace:    'featherlight',         /* Name of the events and css class prefix */
			targetAttr:   'data-featherlight',    /* Attribute of the triggered element that contains the selector to the lightbox content */
			variant:      null,                   /* Class that will be added to change look of the lightbox */
			resetCss:     false,                  /* Reset all css */
			background:   null,                   /* Custom DOM for the background, wrapper and the closebutton */
			openTrigger:  'click',                /* Event that triggers the lightbox */
			closeTrigger: 'click',                /* Event that triggers the closing of the lightbox */
			filter:       null,                   /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */
			openSpeed:    250,                    /* Duration of opening animation */
			closeSpeed:   250,                    /* Duration of closing animation */
			closeOnClick: 'background',           /* Close lightbox on click ('background', 'anywhere' or false) */
			closeOnEsc:   true,                   /* Close lightbox when pressing esc */
			closeIcon:    '✕',             /* Close icon */
			otherClose:   null,                   /* Selector for alternate close buttons (e.g. "a.close") */
			beforeOpen:   $.noop,                 /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
			beforeClose:  $.noop,                 /* Called before close. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
			afterOpen:    $.noop,                 /* Called after open. Gets event as parameter, this contains all data */
			afterClose:   $.noop,                 /* Called after close. Gets event as parameter, this contains all data */
			type:         null,                   /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */
			contentFilters: ['jquery', 'image', 'html', 'ajax', 'text'] /* List of content filters to use to determine the content */
		},
		/* you can access and override all methods using $.featherlight.methods */
		methods: {
			/* setup iterates over a single instance of featherlight and prepares the background and binds the events */
			setup: function(target, config){
				/* all arguments are optional */
				if (typeof target === 'object' && target instanceof $ === false && !config) {
					config = target;
					target = undefined;
				}

				var self = $.extend(this, Fl.defaults, config, {target: target}),
					css = !self.resetCss ? self.namespace : self.namespace+'-reset', /* by adding -reset to the classname, we reset all the default css */
					$background = $(self.background || '

'+self.closeIcon+'

'),
					closeButtonSelector = '.'+self.namespace+'-close' + (self.otherClose ? ',' + self.otherClose : '');

				self.$instance = $background.clone().addClass(self.variant); /* clone DOM for the background, wrapper and the close button */

				/* attach esc handler to document if configured */
				if(self.closeOnEsc && escapeHelper) {
					$(document).bind('keyup.'+Fl.defaults.namespace, escapeHelper);
					escapeHelper = null;
				}

				/* close when click on background/anywhere/null or closebox */
				self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
					var $target = $(event.target);
					if( ('background' === self.closeOnClick  && $target.is('.'+self.namespace))
						|| 'anywhere' === self.closeOnClick
						|| $target.is(closeButtonSelector) ){
						event.preventDefault();
						self.close();
					}
				});

				return this;
			},

			/* this method prepares the content and converts it into a jQuery object or a promise */
			getContent: function(){
				var self = this,
					sourceAttr = function(name){ return self.source && self.source.getAttribute(name); },
					targetAttr = sourceAttr(self.targetAttr),
					data = self.target || targetAttr || '';

				/* Find which filter applies */
				var filter = Fl.contentFilters[self.type]; /* check explicit type like {type: 'image'} */

				/* check explicit type like data-featherlight="image" */
				if(!filter && data in Fl.contentFilters) {
					filter = Fl.contentFilters[data];
					data = self.target && targetAttr;
				}
				data = data || sourceAttr('href') || '';

				/* check explicity type & content like {image: 'photo.jpg'} */
				if(!filter) {
					for(var filterName in Fl.contentFilters) {
						if(self[filterName]) {
							filter = Fl.contentFilters[filterName];
							data = self[filterName];
						}
					}
				}

				/* otherwise it's implicit, run checks */
				if(!filter) {
					var target = data;
					data = null;
					$.each(self.contentFilters, function() {
						filter = Fl.contentFilters[this];
						if(filter.test)  { data = filter.test(target); }
						if(!data && filter.regex && target.match && target.match(filter.regex)) { data = target; }
						return !data;
					});
					if(!data) {
						if('console' in window){ window.console.error('Featherlight: no content filter found ' + (target ? ' for "' + target + '"' : ' (no target specified)')); }
						return false;
					}
				}
				/* Process it */
				return filter.process.call(self, data);
			},

			/* sets the content of $instance to $content */
			setContent: function($content){
				var self = this;
				/* we need a special class for the iframe */
				if($content.is('iframe') || $('iframe', $content).length > 0){
					self.$instance.addClass(self.namespace+'-iframe');
				}
				self.$content = $content.clone().addClass(self.namespace+'-inner');

				/* remove existing content */
				self.$instance.find('.'+self.namespace+'-inner').remove();
				self.$instance.find('.'+self.namespace+'-content').append(self.$content);

				return self;
			},

			/* opens the lightbox. "this" contains $instance with the lightbox, and with the config */
			open: function(event){
				var self = this;
				if(event && !event.isDefaultPrevented()
					|| self.beforeOpen(event) !== false) {

					if(event){
						event.preventDefault();
					}
					var $content = self.getContent();

					if($content){
						/* Add to opened registry */
						self.constructor._opened.add(self._openedCallback = function(response){
							if(self.$instance.closest('body').length > 0) {
								response.currentFeatherlight = self;
							}
						});

						/* Set content and show */
						$content.promise().done(function($content){
							self.setContent($content)
								.$instance.appendTo('body').fadeIn(self.openSpeed);
							self.afterOpen(event);
						});
						return self;
					}
				}
				return false;
			},

			/* closes the lightbox. "this" contains $instance with the lightbox, and with the config */
			close: function(event){
				var self = this;
				if(self.beforeClose(event) === false) {
					return false;
				}
				self.constructor._opened.remove(self._openedCallback);
				self.$instance.fadeOut(self.closeSpeed,function(){
					self.$instance.detach();
					self.afterClose(event);
				});
			}
		},
		/* Contains the logic to determine content */
		contentFilters: {
			jquery: {
				regex: /^[#.]\w/,         /* Anything that starts with a class name or identifiers */
				test: function(elem)    { return elem instanceof $ && elem; },
				process: function(elem) { return $(elem); }
			},
			image: {
				regex: /\.(png|jpg|jpeg|gif|tiff|bmp)(\?\S*)?$/i,
				process: function(url)  {
					var self = this,
						deferred = $.Deferred(),
						img = new Image();
					img.onload  = function() { deferred.resolve(
						$('')
					); };
					img.onerror = function() { deferred.reject(); };
					img.src = url;
					return deferred.promise();
				}
			},
			html: {
				regex: /^\s*<[\w!][^<]*>/, /* Anything that starts with some kind of valid tag */
				process: function(html) { return $(html); }
			},
			ajax: {
				regex: /./,            /* At this point, any content is assumed to be an URL */
				process: function(url)  {
					var self = this,
						deferred = $.Deferred();
					/* we are using load so one can specify a target with: url.html #targetelement */
					var $container = $('

').load(url, function(response, status){
						if ( status !== "error" ) {
							deferred.resolve($container.contents());
						}
						deferred.fail();
					});
					return deferred.promise();
				}
			},
			text: {
				process: function(text) { return $('
', {text: text}); }
			}
		},

		attach: function($source, $content, config) {
			if (typeof $content === 'object' && $content instanceof $ === false && !config) {
				config = $content;
				$content = undefined;
			}
			/* make a copy */
			config = $.extend({}, config);
			/* Only for openTrigger and namespace... */
			var curConfig = $.extend({}, Fl.defaults, elementConfig($source[0]), config);
			$source.on(curConfig.openTrigger+'.'+curConfig.namespace, curConfig.filter, function(event) {
				/* ... since we might as well compute the config on the actual target */
				var elemConfig = $.extend({source: this}, elementConfig(this), config);
				new $.featherlight($content, elemConfig).open(event);
			});
		},

		current: function() {
			var response = {};
			this._opened.fire(response);
			return response.currentFeatherlight;
		},

		close: function() {
			var cur = Fl.current();
			if(cur) { cur.close(); }
		},

		_opened: $.Callbacks()
	});

	Fl.prototype = $.extend({constructor: Fl}, Fl.methods);

	/* bind jQuery elements to trigger featherlight */
	$.fn.featherlight = function($content, config) {
		Fl.attach(this, $content, config);
		return this;
	};

	/* bind featherlight on ready if config autoBind is set */
	$(document).ready(function(){
		if(Fl.autoBind){
			$(document).featherlight({filter: Fl.autoBind});
		}
	});
}(jQuery));
<|endoftext|>