<commit_before>// util.js
// This contains various utilities used throughout the code.

import dnt from '/imports/lib/dnt';
import rx from '/imports/common/rx';
import select2 from '/imports/lib/select2';
import userMsg from '/imports/common/userMsg';

exports.get_username = function (callback) {

    // Callback will be called with one parameter: the username or undefined
    Meteor.call('get_username', function (error, results) {
        if (error || !results) {
            callback(undefined);
        } else {
            callback(results);
        }
    });
}

exports.isValidFileName = function (name) {
    var index = name.search(/[^A-Za-z0-9_\-\.]/g);
    return (index < 0);
}

exports.clean_file_name = function (dirty) {

    // Make a directory or file name out of some string
    // Valid characters:
    //     a-z, A-Z, 0-9, dash (-), dot (.), underscore (_)
    // All other characters are replaced with underscores.

    if (!dirty) { return undefined; }

    return dirty.replace(/[^A-Za-z0-9_\-\.]/g, "_");
}

exports.getDataType = function (layerName) {
    let dataType = layers[layerName.dataType];
    if (dataType === undefined) {
        if (exports.is_binary(layerName)){
            dataType = "binary"
        } else if (exports.is_continuous(layerName)){
            dataType = "continuous"
        } else if (exports.is_categorical(layerName)){
            dataType = "categorical"
        } else {
            throw 'No dataType for attribute: ' + layerName;
        }
    }
    return dataType;
}

exports.is_continuous = function (layer_name) {
    return (ctx.cont_layers.indexOf(layer_name.toString()) > -1);
}

exports.is_categorical = function (layer_name) {
        var is_cat;
        if ( _.isUndefined(layer_name) ){
            is_cat = false
        } else {
            is_cat = (ctx.cat_layers.indexOf(layer_name.toString()) > -1)
}
        return is_cat;
    }

exports.is_cat_or_bin = function (layer_name){
        return (exports.is_categorical(layer_name) ||
            exports.is_binary(layer_name));
    }

exports.is_binary = function (layer_name) {
        var is_bin;
        if ( _.isUndefined(layer_name) ){
            is_bin = false
        } else {
            is_bin = (ctx.bin_layers.indexOf(layer_name.toString()) > -1)
}
        return is_bin;
    }

exports.round = function (x, n) {
    if (!n) {
        n = 0;
    }
    var m = Math.pow(10, n);
    return Math.round(x * m) / m;
}

exports.getHumanProject = function (project) {

    // Transform a project from dir structure to display for humans
    return project.slice(0, -1);
}

export function hideAllSnakes () {
    rx.set('snake.map.hide');
    rx.set('snake.project.hide');
    rx.set('snake.shortlist.hide');
}

exports.mapNotFoundNotify = function (more, stackTrace) {
    if (!ctx.mapNotFoundNotified) {
        ctx.mapNotFoundNotified = true;

        var name = exports.getHumanProject(ctx.project),
            msg = 'Map "' + name + '" not found.\nPlease select another';
        if (Meteor.user() === null) {
            msg += ' or sign in'
        }
        msg += '. ' + more;
        userMsg.error(msg, {logStr: stackTrace});
        hideAllSnakes();
    }
}

exports.parseTsv = function (data) {

    if (data.length < 1) {
        return [];
    }

    // Separate the data into an array of rows
    var rows = data.split('\n'),

    // Separate each row into an array of values
    parsed = _.map(rows, function(row) {
        return row.split('\t');
    });

    // Remove any empty row left from the new-line split
    if (parsed[parsed.length-1].length === 1 &&
            parsed[parsed.length-1][0] === '') {
        parsed.pop();
    }
    return parsed;
}

exports.removeFromDataTypeList = function (layer_name) {

    // Remove this layer from the appropriate data type list
    var index = ctx.bin_layers.indexOf(layer_name);
    if (index > -1) {
        ctx.bin_layers.splice(index, 1);
    } else {
        index = ctx.cat_layers.indexOf(layer_name);
        if (index > -1) {
            ctx.cat_layers.splice(index, 1);
        } else {
            index = ctx.cont_layers.indexOf(layer_name);
            if (index > -1) {
                ctx.cont_layers.splice(index, 1);
            }
        }
    }
}

function setHeightSelect2 ($el) {

    // Make the bottom of the list no longer than the main window
    $el.parent().on('select2-open', function () {
        var results = $('#select2-drop .select2-results');
        results.css(
            'max-height', $(window).height() - results.offset().top - 15);
    });
}

exports.createOurSelect2 = function ($el, optsIn, defaultSelection) {

    // Create a select2 drop-down.

    // Including our favorite options
    var opts = {
        dropdownAutoWidth: true,
        minimumResultsForSearch: -1,
    };

    // The caller's options override our favorite options
    for (var key in optsIn) {
        if (optsIn.hasOwnProperty(key)) {
            opts[key] = optsIn[key];
        }
    }

    // Create the select2 object
    $el.select2(opts);

    // Set the default selection
    if (defaultSelection) {
        $el.select2('val', defaultSelection);
    }

    setHeightSelect2($el);
}

exports.addToDataTypeList = function (layer_name, dataType) {
    if (dataType === 'binary') {
        ctx.bin_layers.push(layer_name);
    } else if (dataType === 'categorical') {
        ctx.cat_layers.push(layer_name);
    } else {
        ctx.cont_layers.push(layer_name);
    }
}

exports.googleAnalytics = function () {

    // Before including google analytics, respect the user's wish not to be
    // tracked if she set this in her browser preferences.
    if (!dnt._dntEnabled() || (window.ga && ga.loaded)) {
        /* eslint-disable */
        window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
        ga('create', 'UA-76132249-2', 'auto');
        ga('send', 'pageview');
        /* eslint-enable */
    } else {
        document.location = url;
    }
}

<commit_msg>save url if google analytics not there<commit_after>// util.js
// This contains various utilities used throughout the code.

import dnt from '/imports/lib/dnt';
import rx from '/imports/common/rx';
import select2 from '/imports/lib/select2';
import userMsg from '/imports/common/userMsg';

exports.get_username = function (callback) {

    // Callback will be called with one parameter: the username or undefined
    Meteor.call('get_username', function (error, results) {
        if (error || !results) {
            callback(undefined);
        } else {
            callback(results);
        }
    });
}

exports.isValidFileName = function (name) {
    var index = name.search(/[^A-Za-z0-9_\-\.]/g);
    return (index < 0);
}

exports.clean_file_name = function (dirty) {

    // Make a directory or file name out of some string
    // Valid characters:
    //     a-z, A-Z, 0-9, dash (-), dot (.), underscore (_)
    // All other characters are replaced with underscores.

    if (!dirty) { return undefined; }

    return dirty.replace(/[^A-Za-z0-9_\-\.]/g, "_");
}

exports.getDataType = function (layerName) {
    let dataType = layers[layerName.dataType];
    if (dataType === undefined) {
        if (exports.is_binary(layerName)){
            dataType = "binary"
        } else if (exports.is_continuous(layerName)){
            dataType = "continuous"
        } else if (exports.is_categorical(layerName)){
            dataType = "categorical"
        } else {
            throw 'No dataType for attribute: ' + layerName;
        }
    }
    return dataType;
}

exports.is_continuous = function (layer_name) {
    return (ctx.cont_layers.indexOf(layer_name.toString()) > -1);
}

exports.is_categorical = function (layer_name) {
        var is_cat;
        if ( _.isUndefined(layer_name) ){
            is_cat = false
        } else {
            is_cat = (ctx.cat_layers.indexOf(layer_name.toString()) > -1)
}
        return is_cat;
    }

exports.is_cat_or_bin = function (layer_name){
        return (exports.is_categorical(layer_name) ||
            exports.is_binary(layer_name));
    }

exports.is_binary = function (layer_name) {
        var is_bin;
        if ( _.isUndefined(layer_name) ){
            is_bin = false
        } else {
            is_bin = (ctx.bin_layers.indexOf(layer_name.toString()) > -1)
}
        return is_bin;
    }

exports.round = function (x, n) {
    if (!n) {
        n = 0;
    }
    var m = Math.pow(10, n);
    return Math.round(x * m) / m;
}

exports.getHumanProject = function (project) {

    // Transform a project from dir structure to display for humans
    return project.slice(0, -1);
}

export function hideAllSnakes () {
    rx.set('snake.map.hide');
    rx.set('snake.project.hide');
    rx.set('snake.shortlist.hide');
}

exports.mapNotFoundNotify = function (more, stackTrace) {
    if (!ctx.mapNotFoundNotified) {
        ctx.mapNotFoundNotified = true;

        var name = exports.getHumanProject(ctx.project),
            msg = 'Map "' + name + '" not found.\nPlease select another';
        if (Meteor.user() === null) {
            msg += ' or sign in'
        }
        msg += '. ' + more;
        userMsg.error(msg, {logStr: stackTrace});
        hideAllSnakes();
    }
}

exports.parseTsv = function (data) {

    if (data.length < 1) {
        return [];
    }

    // Separate the data into an array of rows
    var rows = data.split('\n'),

    // Separate each row into an array of values
    parsed = _.map(rows, function(row) {
        return row.split('\t');
    });

    // Remove any empty row left from the new-line split
    if (parsed[parsed.length-1].length === 1 &&
            parsed[parsed.length-1][0] === '') {
        parsed.pop();
    }
    return parsed;
}

exports.removeFromDataTypeList = function (layer_name) {

    // Remove this layer from the appropriate data type list
    var index = ctx.bin_layers.indexOf(layer_name);
    if (index > -1) {
        ctx.bin_layers.splice(index, 1);
    } else {
        index = ctx.cat_layers.indexOf(layer_name);
        if (index > -1) {
            ctx.cat_layers.splice(index, 1);
        } else {
            index = ctx.cont_layers.indexOf(layer_name);
            if (index > -1) {
                ctx.cont_layers.splice(index, 1);
            }
        }
    }
}

function setHeightSelect2 ($el) {

    // Make the bottom of the list no longer than the main window
    $el.parent().on('select2-open', function () {
        var results = $('#select2-drop .select2-results');
        results.css(
            'max-height', $(window).height() - results.offset().top - 15);
    });
}

exports.createOurSelect2 = function ($el, optsIn, defaultSelection) {

    // Create a select2 drop-down.

    // Including our favorite options
    var opts = {
        dropdownAutoWidth: true,
        minimumResultsForSearch: -1,
    };

    // The caller's options override our favorite options
    for (var key in optsIn) {
        if (optsIn.hasOwnProperty(key)) {
            opts[key] = optsIn[key];
        }
    }

    // Create the select2 object
    $el.select2(opts);

    // Set the default selection
    if (defaultSelection) {
        $el.select2('val', defaultSelection);
    }

    setHeightSelect2($el);
}

exports.addToDataTypeList = function (layer_name, dataType) {
    if (dataType === 'binary') {
        ctx.bin_layers.push(layer_name);
    } else if (dataType === 'categorical') {
        ctx.cat_layers.push(layer_name);
    } else {
        ctx.cont_layers.push(layer_name);
    }
}

exports.googleAnalytics = function () {

    // Before including google analytics, respect the user's wish not to be
    // tracked if she set this in her browser preferences.
    let url = document.location
    if (!dnt._dntEnabled() || (window.ga && ga.loaded)) {
        /* eslint-disable */
        window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
        ga('create', 'UA-76132249-2', 'auto');
        ga('send', 'pageview');
        /* eslint-enable */
    } else {
        document.location = url;
    }
}

<|endoftext|>


<commit_before>exports.BattleAbilities = {
        "shadowtag": {
                desc: "When this Pokemon enters the field, its non-Ghost-type opponents cannot switch or flee the battle unless they have the same ability, are holding Shed Shell, or they use the moves Baton Pass or U-Turn.",
                shortDesc: "Prevents foes from switching out normally unless they also have this Ability.",
                onFoeModifyPokemon: function(pokemon) {
                        var foeactive = pokemon.side.foe.active;
                        var totalhp = 0;
                        for (var i=0; i<foeactive.length; i++) {
                                if (!foeactive[i] || foeactive[i].fainted) continue;
                                totalhp += foeactive[i].getStat('hp', false, true);
                        }
                       if (totalhp =< foe.maxhp/2) {{
                         if (pokemon.ability !== 'shadowtag') {
                                pokemon.trapped = true;
                        }
                },
                onFoeMaybeTrapPokemon: function(pokemon) {
                        if (pokemon.ability !== 'shadowtag') {
                                pokemon.maybeTrapped = true;
                        }
                },
                id: "shadowtag",
                name: "Shadow Tag",
                rating: 5,
                num: 23
        },
        "searingflames": {
                desc: "All fire moves inflict burn.",
                shortDesc: "blah.",
                onModifyMove: function(move) {
                        if (move.type === 'Fire') {
                        if (!move.secondaries) {
                                move.secondaries = [];
                        }
                        move.secondaries.push({
                                chance: 100,
                                status: 'brn'
                        });
                        }
                },
                id: "searingflames",
                name: "Searing Flames",
                rating: 2,
                num: -5
        },
        "contagious": {
                desc: "Any Pokémon who is contacted by or makes contact with this Pokémon becomes badly.",
                shortDesc: "blah blah.",
                onModifyMove: function(move) {
                        if (!move || !move.isContact) return;
                        if (!move.secondaries) {
                                move.secondaries = [];
                        }
                        move.secondaries.push({
                                chance: 100,
                                status: 'psn'
                        });
                },
                onAfterDamage: function(damage, target, source, move) {
                        if (move && move.isContact) {
                        if (!move.secondaries) {
                                        source.SetStatus('psn', target, move);
                                }
                        }
                },
                id: "contagious",
                name: "Contagious",
                rating: 2,
                num: 143
        }
};
<commit_msg>Update abilities.js<commit_after>exports.BattleAbilities = {
        "shadowtag": {
                desc: "When this Pokemon enters the field, its non-Ghost-type opponents cannot switch or flee the battle unless they have the same ability, are holding Shed Shell, or they use the moves Baton Pass or U-Turn.",
                shortDesc: "Prevents foes from switching out normally unless they also have this Ability.",
                onFoeModifyPokemon: function(pokemon) {
                        var foeactive = pokemon.side.foe.active;
                        var totalhp = 0;
                        for (var i=0; i<foeactive.length; i++) {
                                if (!foeactive[i] || foeactive[i].fainted) continue;
                                totalhp += foeactive[i].getStat('hp', false, true);
                        }
                       if (totalhp =< foe.maxhp/2) {{
                         if (pokemon.ability !== 'shadowtag') {
                                pokemon.trapped = true;
                        }
                },
                onFoeMaybeTrapPokemon: function(pokemon) {
                        if (pokemon.ability !== 'shadowtag') {
                                pokemon.maybeTrapped = true;
                        }
                },
                id: "shadowtag",
                name: "Shadow Tag",
                rating: 5,
                num: 23
        },
        "searingflames": {
                desc: "All fire moves inflict burn.",
                shortDesc: "blah.",
                onModifyMove: function(move) {
                        if (move.type === 'Fire') {
                        if (!move.secondaries) {
                                move.secondaries = [];
                        }
                        move.secondaries.push({
                                chance: 100,
                                status: 'brn'
                        });
                        }
                },
                id: "searingflames",
                name: "Searing Flames",
                rating: 2,
                num: -5
        },
        "contagious": {
                desc: "Any Pokémon who is contacted by or makes contact with this Pokémon becomes badly.",
                shortDesc: "blah blah.",
                onModifyMove: function(move) {
                        if (!move || !move.isContact) return;
                        if (!move.secondaries) {
                                move.secondaries = [];
                        }
                        move.secondaries.push({
                                chance: 100,
                                status: 'psn'
                        });
                },
                onAfterDamage: function(damage, target, source, move) {
                        if (move && move.isContact) {
                        if (!move.secondaries) {
                                        source.SetStatus('psn', target, move);
                                }
                        }
                },
                id: "contagious",
                name: "Contagious",
                rating: 2,
                num: -6
        }
};
<|endoftext|>


<commit_before>import ImageCache from './ImageCache';

const ImageHelper = {
    loadImage(url, options) {
        const image = ImageCache.get(url, options);

        return new Promise((resolve, reject) => {
            const handleSuccess = () => {
                resolve(image);
            };
            const handleError = () => {
                reject(new Error(`failed to preload ${url}`));
            };

            if (image.complete) {
                // image is loaded, go ahead and change the state

                if (image.naturalWidth && image.naturalHeight) {
                    // successful load
                    handleSuccess();
                } else {
                    // IE CACHED IMAGES RACE CONDITION
                    // -------------------------------
                    // IE11 sometimes reports cached images as image.complete,
                    // but naturalWidth and naturalHeight = 0.
                    // A few ms later it will get the dimensions correct,
                    // so check a few times before rejecting it.
                    let counter = 1;
                    const checkDimensions = setInterval(() => {
                        if (image.naturalWidth && image.naturalHeight) {
                            window.clearInterval(checkDimensions);
                            handleSuccess();
                        }
                        if (counter === 3) {
                            window.clearInterval(checkDimensions);
                            handleError();
                        }
                        counter += 1;
                    }, 50);
                }
            } else {
                image.addEventListener('load', handleSuccess, false);
                image.addEventListener('error', handleError, false);
            }
        });
    },

    loadImages(urls, options) {
        const promises = urls.map(url => this.loadImage(url, options));
        return Promise.all(promises);
    },

    // preload without caring about the result
    stuffImages(urls, options) {
        ImageCache.stuff(urls, options);
    },
};

export default ImageHelper;
<commit_msg>Wait until all promises resolve before rejecting on errors<commit_after>import ImageCache from './ImageCache';

const reflect = p => p.then(v => ({v, status: 'fulfilled' }),
                            e => ({e, status: 'rejected' }));

const ImageHelper = {
    loadImage(url, options) {
        const image = ImageCache.get(url, options);

        return new Promise((resolve, reject) => {
            const handleSuccess = () => {
                resolve(image);
            };
            const handleError = () => {
                reject(new Error(`failed to preload ${url}`));
            };

            if (image.complete) {
                // image is loaded, go ahead and change the state

                if (image.naturalWidth && image.naturalHeight) {
                    // successful load
                    handleSuccess();
                } else {
                    // IE CACHED IMAGES RACE CONDITION
                    // -------------------------------
                    // IE11 sometimes reports cached images as image.complete,
                    // but naturalWidth and naturalHeight = 0.
                    // A few ms later it will get the dimensions correct,
                    // so check a few times before rejecting it.
                    let counter = 1;
                    const checkDimensions = setInterval(() => {
                        if (image.naturalWidth && image.naturalHeight) {
                            window.clearInterval(checkDimensions);
                            handleSuccess();
                        }
                        if (counter === 3) {
                            window.clearInterval(checkDimensions);
                            handleError();
                        }
                        counter += 1;
                    }, 50);
                }
            } else {
                image.addEventListener('load', handleSuccess, false);
                image.addEventListener('error', handleError, false);
            }
        });
    },

    loadImages(urls, options) {
        const promises = urls.map(url =>  reflect(this.loadImage(url, options)));
        return Promise.all(promises).then((promises) => {
            return promises.map((p) => {
                if(p.status !== 'fulfilled') {
                    throw new Exception('One or more images failed to load');
                }
                return p;
            }
        )
        });
    },

    // preload without caring about the result
    stuffImages(urls, options) {
        ImageCache.stuff(urls, options);
    },
};

export default ImageHelper;
<|endoftext|>


<commit_before>/* @flow */
function filterUniqueArray(arr: Array<any>): Array<any> {
  return arr.filter((val, index) => arr.lastIndexOf(val) === index)
}

export default function assignStyle(
  base: Object,
  ...extendingStyles: Array<Object>
) {
  for (let i = 0, len = extendingStyles.length; i < len; ++i) {
    const style = extendingStyles[i]

    for (const property in style) {
      const value = style[property]
      const baseValue = base[property]

      if (baseValue) {
        if (Array.isArray(baseValue)) {
          base[property] = filterUniqueArray(baseValue.concat(value))
          continue
        }

        if (Array.isArray(value)) {
          base[property] = filterUniqueArray([baseValue, ...value])
          continue
        }

        if (typeof value === 'object') {
          base[property] = assignStyle({}, baseValue, value)
          continue
        }
      }

      base[property] = value
    }
  }

  return base
}
<commit_msg>check weather both values exist before merging<commit_after>/* @flow */
function filterUniqueArray(arr: Array<any>): Array<any> {
  return arr.filter((val, index) => arr.lastIndexOf(val) === index)
}

export default function assignStyle(
  base: Object,
  ...extendingStyles: Array<Object>
) {
  for (let i = 0, len = extendingStyles.length; i < len; ++i) {
    const style = extendingStyles[i]

    for (const property in style) {
      const value = style[property]
      const baseValue = base[property]

      if (baseValue && value) {
        if (Array.isArray(baseValue)) {
          base[property] = filterUniqueArray(baseValue.concat(value))
          continue
        }

        if (Array.isArray(value)) {
          base[property] = filterUniqueArray([baseValue, ...value])
          continue
        }

        if (typeof value === 'object') {
          base[property] = assignStyle({}, baseValue, value)
          continue
        }
      }

      base[property] = value
    }
  }

  return base
}
<|endoftext|>


<commit_before>// @flow

import * as React from 'react'
import {Router} from '@reach/router'
import DocumentTitle from 'react-document-title'
import HTML5Backend from 'react-dnd-html5-backend'
import {DragDropContext} from 'react-dnd'
import {createGlobalStyle} from 'styled-components'
import Loadable from 'react-loadable'
import {LoadingComponent} from './components/loading-comp'

let GlobalStyle = createGlobalStyle`
    *, *::before, *::after {
        box-sizing: inherit;
    }

    html {
        font-family: var(--sans-font-stack);
        color: var(--text-color);

        box-sizing: border-box;

        background: var(--background);
        min-height: 100vh;

        line-height: 1.4;

        font-variant-ligatures: common-ligatures;
        hyphens: auto;
    }

    body {
        height: 100%;
    }

    menu {
        padding: 0;
        margin: 0;
    }

    .content {
        padding-top: var(--page-edge-padding);
        padding-bottom: var(--page-edge-padding);
        overflow-y: scroll;
    }
`

let NotFound = () =>
404 Not Found

let AreaEditor = Loadable({
	loader: () =>
		import(/*webpackChunkName: 'screen.area-editor'*/ '@gob/area-editor'),
	loading: LoadingComponent,
	render: (loaded, props) => <loaded.Editor {...props} />,
})

let StudentPicker = Loadable({
	loader: () =>
		import(/*webpackChunkName: 'screen.student-picker'*/ './screens/picker'),
	loading: LoadingComponent,
})

let Degubber = Loadable({
	loader: () =>
		import(/*webpackChunkName: 'screen.degub'*/ './screens/degub'),
	loading: LoadingComponent,
})

let CreateStudent = Loadable({
	loader: () =>
		import(/*webpackChunkName: 'screen.create'*/ './screens/create'),
	loading: LoadingComponent,
})

let Student = Loadable({
	loader: () =>
		import(/*webpackChunkName: 'screen.student'*/ './screens/student'),
	loading: LoadingComponent,
})

// needs to be a stateful component: otherwise DragDropContext can't assign a ref, which it needs
class App extends React.Component<{}> {
	render() {
		return (

				<GlobalStyle />
				<DocumentTitle title="Gobbldygook" />
				<Router>
					<NotFound default />

					<StudentPicker path="/" />
					<Degubber path="/degub" />
					<AreaEditor path="/areas" />
					<Student path="/student/:studentId" />
					<CreateStudent path="/create/*" />
				</Router>

		)
	}
}

export default DragDropContext(HTML5Backend)(App)
<commit_msg>start removing webpackChunkName comments<commit_after>// @flow

import * as React from 'react'
import {Router} from '@reach/router'
import DocumentTitle from 'react-document-title'
import HTML5Backend from 'react-dnd-html5-backend'
import {DragDropContext} from 'react-dnd'
import {createGlobalStyle} from 'styled-components'
import Loadable from 'react-loadable'
import {LoadingComponent} from './components/loading-comp'

let GlobalStyle = createGlobalStyle`
    *, *::before, *::after {
        box-sizing: inherit;
    }

    html {
        font-family: var(--sans-font-stack);
        color: var(--text-color);

        box-sizing: border-box;

        background: var(--background);
        min-height: 100vh;

        line-height: 1.4;

        font-variant-ligatures: common-ligatures;
        hyphens: auto;
    }

    body {
        height: 100%;
    }

    menu {
        padding: 0;
        margin: 0;
    }

    .content {
        padding-top: var(--page-edge-padding);
        padding-bottom: var(--page-edge-padding);
        overflow-y: scroll;
    }
`

let NotFound = () =>
404 Not Found

let AreaEditor = Loadable({
	loader: () => import('@gob/area-editor').then(mod => mod.Editor),
	loading: LoadingComponent,
})

let StudentPicker = Loadable({
	loader: () => import('./screens/picker'),
	loading: LoadingComponent,
})

let Degubber = Loadable({
	loader: () => import('./screens/degub'),
	loading: LoadingComponent,
})

let CreateStudent = Loadable({
	loader: () => import('./screens/create'),
	loading: LoadingComponent,
})

let Student = Loadable({
	loader: () => import('./screens/student'),
	loading: LoadingComponent,
})

// needs to be a stateful component: otherwise DragDropContext can't assign a ref, which it needs
class App extends React.Component<{}> {
	render() {
		return (

				<GlobalStyle />
				<DocumentTitle title="Gobbldygook" />
				<Router>
					<NotFound default />

					<StudentPicker path="/" />
					<Degubber path="/degub" />
					<AreaEditor path="/areas" />
					<Student path="/student/:studentId" />
					<CreateStudent path="/create/*" />
				</Router>

		)
	}
}

export default DragDropContext(HTML5Backend)(App)
<|endoftext|>


<commit_before>const { Monitor } = require("klasa");

module.exports = class extends Monitor {
    constructor(...args) {
        super(...args, {
            name: "prefixHelp",
            enabled: true,
            ignoreEdits: false,
            ignoreOthers: false
        });
    }

    run(msg) {
        var defaultPrefix = msg.client.gateways.guilds.schema.get("prefix").default;
        var guildPrefix = msg.guild.settings.prefix;

        if (msg.content === `${defaultPrefix}help`) {
            if (defaultPrefix !== guildPrefix) {
                return msg.sendLocale("PREFIXHELP_DEFAULT", [guildPrefix]);
            }
        }
        if (msg.content === `${defaultPrefix.replace("~", "-")}help`) {
            if (defaultPrefix.replace("~", "-") !== guildPrefix) {
                return msg.sendLocale("PREFIXHELP_MISREAD");
            }
        }
    }
};<commit_msg>Updated prefixHelp<commit_after>const { Monitor } = require("klasa");

module.exports = class extends Monitor {
    constructor(...args) {
        super(...args, {
            name: "prefixHelp",
            enabled: true,
            ignoreEdits: false,
            ignoreOthers: false
        });
    }

    run(msg) {
        let defaultPrefix = msg.client.gateways.guilds.schema.get("prefix").default;
        let guildPrefix = msg.guild.settings.prefix;

        if (msg.content === `${defaultPrefix}help` && defaultPrefix !== guildPrefix) {
            return msg.sendLocale("PREFIXHELP_DEFAULT", [guildPrefix]);
        }

        if (msg.content === `${defaultPrefix.replace("~", "-")}help` && defaultPrefix.replace("~", "-") !== guildPrefix) {
            return msg.sendLocale("PREFIXHELP_MISREAD");
        }
    }
};<|endoftext|>


<commit_before>// dataLoopExample1.js
//
// This is a simple test script that does the following:
//  open a website
//  validate title
//  validates page with many links
//
//    each link is validated and the page is loaded

// The example demos how to use an array of data and loop through the data to verify URL/TEXT and the page exists

// required libraries
var webdriverio = require('webdriverio'),
  should = require('should');

// a test script block or suite
describe('Loop Data URL Test for Web Driver IO - Tutorial Test Page Website', function() {

// Link data - link and text
var linkArray = [
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/tutorial1.js", "name" : "tutorial1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/linkTextURL1.js", "name" : "linkTextURL1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/copyright1.js", "name" : "copyright1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/formFillSubmit1.js", "name" : "formFillSubmit1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/showHideVerify1.js", "name" : "showHideVerify1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dynamicBrowser.js", "name" : "dynamicBrowser.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/callbackPromise.js", "name" : "callbackPromise.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/debugExample1.js", "name" : "debugExample1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/formFieldValidation.js", "name" : "formFieldValidation.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/common/commonLib.js", "name" : "commonLib.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dataLoopExample1.js", "name" : "dataLoopExample1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dataLoopExample2.js", "name" : "dataLoopExample2.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/cssValidation1.js", "name" : "cssValidation1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/saucelabs.js", "name" : "saucelabs.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/gruntSaucelabs.js", "name" : "gruntSaucelabs.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/Gruntfile.js", "name" : "Gruntfile.js"}
];
  // set timeout to 180 seconds since there are so many links to check
	this.timeout(180000);
  var driver = {};

  // hook to run before tests
  before( function (done) {
    // check for global browser (grunt + grunt-webdriver)
    if(typeof browser === "undefined") {
      // load the driver for browser
      driver = webdriverio.remote({ desiredCapabilities: {browserName: 'firefox'} });
      driver.init(done);
    } else {
      // grunt will load the browser driver
      driver = browser;
      done();
    }
  });

  // a test spec - "specification"
  it('should be load correct page and title', function () {
    // load page, then call function()
    return driver
      .url('http://www.tlkeith.com/WebDriverIOTutorialTest.html')
     // get title, then pass title to function()
      .getTitle().then( function (title) {
        // verify title
        (title).should.be.equal("Web Driver IO - Tutorial Test Page");
        // uncomment for console debug
        // console.log('Current Page Title: ' + title);
      });
  });

  // loop through each linkArray
  linkArray.forEach(function(d) {
    it('should contain text/link then goto page - ' + d.name, function() {
      return driver
      // make sure you are on the starting page
      .url('http://www.tlkeith.com/WebDriverIOTutorialTest.html')
      .getTitle().then( function (title) {
        // verify title
        (title).should.be.equal("Web Driver IO - Tutorial Test Page");
      })
      // find the URL
      .getAttribute('a=' + d.name, "href").then(function (link) {
        (link).should.equal(d.link);
        console.log('URL found: ' + d.link);
      })
      // go to URL page and verify it exists (wait 15 seconds before timeout)
      .click('a=' + d.name)
      .waitForVisible("#js-repo-pjax-container", 15000).then(function () {
        console.log('Github Page Found');
      });
    });
  });

  // a "hook" to run after all tests in this block
	after(function(done) {
    if(typeof browser === "undefined") {
      driver.end(done);
    } else {
      done();
    }
  });
});<commit_msg>Updated with latest file list<commit_after>// dataLoopExample1.js
//
// The example demos how to use an array of data and loop
//  through the data to verify URL/TEXT and the page exists.
//
// This is a simple test script that does the following:
//  open a website
//  validate title
//  validates page with many links
//  each link is validated and the link is loaded

// required libraries
var webdriverio = require('webdriverio'),
  should = require('should');

// a test script block or suite
describe('Loop Data URL Test for Web Driver IO - Tutorial Test Page Website', function() {

// Link data - link and text
var linkArray = [
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/tutorial1.js", "name" : "tutorial1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/linkTextURL1.js", "name" : "linkTextURL1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/copyright1.js", "name" : "copyright1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/formFillSubmit1.js", "name" : "formFillSubmit1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/showHideVerify1.js", "name" : "showHideVerify1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dynamicBrowser.js", "name" : "dynamicBrowser.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/callbackPromise.js", "name" : "callbackPromise.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/debugExample1.js", "name" : "debugExample1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/formFieldValidation.js", "name" : "formFieldValidation.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/common/commonLib.js", "name" : "commonLib.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dataLoopExample1.js", "name" : "dataLoopExample1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dataLoopExample2.js", "name" : "dataLoopExample2.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/cssValidation1.js", "name" : "cssValidation1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/saucelabs.js", "name" : "saucelabs.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/gruntSaucelabs.js", "name" : "gruntSaucelabs.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/Gruntfile.js", "name" : "Gruntfile.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/Gruntfile-dataLoopExample2.js", "name" : "Gruntfile-dataLoopExample2.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/Gruntfile-gruntSaucelabs.js", "name" : "Gruntfile-gruntSaucelabs.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/wdio.conf-saucelabs-dataLoopExample2.js", "name" : "wdio.conf-saucelabs-dataLoopExample2.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/wdio.conf-dataLoopExample2.js", "name" : "wdio.conf-dataLoopExample2.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/restAPIExample1.js", "name" : "restAPIExample1.js"},
{"link" : "https://github.com/onewithhammer/web-driver-io-tutorial/blob/master/dbDataLoopExample.js", "name" : "dbDataLoopExample.js"}
];
  // set timeout to 180 seconds since there are so many links to check
	this.timeout(180000);
  var driver = {};

  // hook to run before tests
  before( function (done) {
    // check for global browser (grunt + grunt-webdriver)
    if(typeof browser === "undefined") {
      // load the driver for browser
      driver = webdriverio.remote({ desiredCapabilities: {browserName: 'firefox'} });
      driver.init(done);
    } else {
      // grunt will load the browser driver
      driver = browser;
      done();
    }
  });

  // a test spec - "specification"
  it('should be load correct page and title', function () {
    // load page, then call function()
    return driver
      .url('http://www.tlkeith.com/WebDriverIOTutorialTest.html')
     // get title, then pass title to function()
      .getTitle().then( function (title) {
        // verify title
        (title).should.be.equal("Web Driver IO - Tutorial Test Page");
        // uncomment for console debug
        // console.log('Current Page Title: ' + title);
      });
  });

  // loop through each linkArray
  linkArray.forEach(function(d) {
    it('should contain text/link then goto page - ' + d.name, function() {
      return driver
      // make sure you are on the starting page
      .url('http://www.tlkeith.com/WebDriverIOTutorialTest.html')
      .getTitle().then( function (title) {
        // verify title
        (title).should.be.equal("Web Driver IO - Tutorial Test Page");
      })
      // find the URL
      .getAttribute('a=' + d.name, "href").then(function (link) {
        (link).should.equal(d.link);
        console.log('URL found: ' + d.link);
      })
      // go to URL page and verify it exists (wait 15 seconds before timeout)
      .click('a=' + d.name)
      .waitForVisible("#js-repo-pjax-container", 15000).then(function () {
        console.log('Github Page Found');
      });
    });
  });

  // a "hook" to run after all tests in this block
	after(function(done) {
    if(typeof browser === "undefined") {
      driver.end(done);
    } else {
      done();
    }
  });
});<|endoftext|>


<commit_before>
var playersClosed = 0;
var playersFinished = 0;
var sameScore = 0;
var viewChildrenCount = 0;
var viewChild = null;

// Disable number that is no longer scorable for any player
// Is passed index of clicked number to compare with other numbers of same index
var closeNumbers = function(indx){
	var hits_on_this_num = 0;
	for(i=0;i<views.length;i++){
		if(views[i].children[indx].hits>=3){
			hits_on_this_num++;
		}
	}
	if(hits_on_this_num==views.length){
		for(i=0;i<views.length;i++){
			views[i].children[indx].touchEnabled=false;
			views[i].children[indx].status=false;
			views[i].children[indx].animate(seeThru);
			views[i].children[indx].color = '#ffffff';
			views[i].children[indx].backgroundImage = 'images/'+device+'/button.png';
		}
		availNums[indx].animate(seeThru);
		return true;
	};
}

var openNumbers = function(button){
	// Reverse the number closure
	if(players[button.playerNum].turn){
		button.touchEnabled=true;
	}
	button.status=true;
	button.animate(notSeeThru);
	highlight(button);
	availNums[button.index].animate(notSeeThru);
}

// determines which player holds highest score, does not account for 2 players having the same high score
// This never runs if the first to finish does not have highest score
var highestIndex = null;
var highestScoreTmp = 0;
var has_highest_score = function(){
	for(i=0;i<totalPlayers;i++){
        if (players[i].score > highestScoreTmp) {
            highestIndex = i;
            highestScoreTmp = players[i].score;
        }
	}
	if(highestIndex!=null){
		if(playerFinishedNums(highestIndex)){
	    	return true;
		}
	} else {
		highestScoreTmp = 0;
	    return false;
	}
}

// This checks if all players have started their turns
var allPlayersFinished = function(){
	for(i=0; i<totalPlayers; i++){
		if(players[i].startedTurn){
			playersFinished++;
		}
	}
	// try removing throwsThisRound == 3 to end game even if not all darts are thrown
	if(playersFinished == totalPlayers && throwsThisRound == 3){
		playersFinished=0;
		return true;
	} else {
		playersFinished = 0;
		return false;
	}
}

var displayWinner = function(winner){
	players[winner].wins += 1;
	GameNumber++;
	//Games to play is defined in options.js, imported after closer.js, this breaks
	if(players[winner].wins>GamesToPlay/2){
		winnerOfSets(players[winner].name);
	} else {
		winnerAlert(players[winner].name);
	}
}

// Counts how many closed numbers the specified player has,
// returns true if player finished all numbers
var currentPlayerFinished = 0;
var playerFinishedNums = function(playerIndex){
	for(var i=0;i<7;i++){
		if(players[playerIndex].buttons[i].closed){
			currentPlayerFinished++;
		}
	}
	if(currentPlayerFinished==7) {
		players[playerIndex].allClosed = true;
		currentPlayerFinished = 0;
		return true;
	} else {
		currentPlayerFinished = 0;
		return false;
	}
}

var someoneFinished = false;
var closedNums = 0;
var closedConfirm = 0
var playersChecked = 0;
var firstPlayerToClose = null;
var checkClosedNums = function(buttons, player){
	// This is in case a player has closed all numbers
	// and then undoes moves to open numbers
	if(someoneFinished) {
		for(var i=0;i<totalPlayers;i++){
			for(var a=0;a<players[i].buttons.length;a++){
				if(players[i].buttons[a].hits>2){
					closedConfirm++;
				}
			}
			if(closedConfirm<7){
				closedConfirm = 0;
				someoneFinished = false;
				players[i].allClosed = false;
			} else {
				closedConfirm = 0;
				someoneFinished = true;
				playersChecked = 0;
				players[i].allClosed = true;
				break;
			}
			playersChecked++;
			if(playersChecked==totalPlayers && !someoneFinished){
				firstPlayerToClose = null;
			}
		}
	}
	for(i=0;i<7;i++){
		if(buttons[i].hits>2){
			closedNums++;
		}
		if(closedNums==7) {
			firstPlayerToClose = currentPlayerIndex;
			someoneFinished = true;
			player.allClosed = true;
		}
	}
	closedNums=0;
}

// Determine if all players have closed all numbers
var playersAllClosed = 0;
var allPlayersClosedAllNumbers = function(){
	for(var i=0;i<totalPlayers;i++){
		for(var a=0;a<players[i].buttons.length;a++){
			if(players[i].buttons[a].hits>2){
				closedConfirm++;
			}
		}
		if(closedConfirm<7){
			closedConfirm = 0;
			playersAllClosed = 0;
			return false;
		} else {
			closedConfirm = 0;
			playersChecked = 0;
			playersAllClosed++;
		}
	}
	if(playersAllClosed==totalPlayers){
		playersAllClosed = 0;
		return true;
	}
}

// Determines if 2 or more players are tied
var matchesHighestScore = function(playerToCheck, topScore){
	if (players[playerToCheck].score == topScore){
    	return true;
    } else {
    	return false;
	}
}

var winner = function(){
	if (totalPlayers == 1) {
		// If only one person is playing
		singlePlayerFinished()
	} else if(has_highest_score() && allPlayersFinished()) {
		// Player who closed all numbers who also has highest score wins
		lastTurn = true;
		displayWinner(highestIndex);
		highestIndex = null;
		highestScoreTmp = 0;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
	} else if(tieGame()) {
		// Game is tied
		lastTurn = true;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
		tieAlert();
	} else if(matchesHighestScore(firstPlayerToClose, highestScore) && allPlayersFinished()) {
		// this is running because it's "matching" the highest score, even if it is itself
		// If at least 2 players are tied in score, but one player has closed all numbers, and all players have finished their last turn
		lastTurn = true;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
		displayWinner(firstPlayerToClose);
	}
}

// Checks if all players have closed all numbers and score is the same
var tieGame = function(){
	for(i=0; i<totalPlayers; i++){
		if(players[i].score == highestScore){
			sameScore++;
		}
	}
	if(allPlayersClosedAllNumbers() && sameScore == totalPlayers){
		sameScore = 0;
		return true;
	} else {
		sameScore = 0;
		return false;
	}
}

var singlePlayerFinished = function(winner){
	var gameWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Game Finished',
	    message: 'You closed all the numbers!',
	    buttonNames: ['New Game', 'Quit'],
	    cancel: 0
	});
	gameWinnerAlert.show();
	gameWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var winnerAlert = function(winner){
	var gameWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Game Finished',
	    message: winner + ' wins!',
	    buttonNames: ['Next Game', 'Quit Set'],
	    cancel: 0
	});
	gameWinnerAlert.show();
	gameWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var tieAlert = function(){
	var gameTieAlert = Titanium.UI.createAlertDialog({
	    title: 'Tie Game!',
	    message: 'Wow... really? Ok well you\'ll have to play that game again. We need a winner!',
	    buttonNames: ['Next Game', 'Quit Set'],
	    cancel: 0
	});
	gameTieAlert.show();
	gameTieAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var resetCounts = function(){
	throwsThisRound = 0;
	numberTracker.length = 0;
}

var winnerOfSets = function(winner){
	var setsWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Set Finished',
	    message: winner + ' wins the set!',
	    buttonNames: ['OK', 'New Set', 'Change Players'],
	    cancel: 0
	});
	setsWinnerAlert.show();
	setsWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			// if user presses OK, all buttons are made untouchable.
			for(numOfButtons=0;numOfButtons<7;numOfButtons++){
				for(var numOfViews=0;numOfViews<totalPlayers;numOfViews++){
					views[numOfViews].touchEnabled = false;
					miss.touchEnabled = false;
					undoPoints.touchEnabled = false;
				}
			}
		} else if(e.index == 1) {
			GameNumber = 0;
			start_new_game();
			for(var i=0;i<totalPlayers;i++){
				players[i].wins = 0;
			}
		} else if(e.index == 2) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var resetGlobalVars = function(){
	currentPlayerIndex = 0;
	throwsThisRound = 0;
	totalThrows = 0;
	numberTracker.length = 0;
	players[0].turn = true;
	players[0].startedTurn = true;
	views[0].touchEnabled = true;
	miss.touchEnabled = true;
	undoPoints.touchEnabled = true;
	someoneFinished = false;
	indicatorsRemoved = false;
	lastTurn = false;
	firstPlayerToClose = null;
	for(i=0; i<totalPlayers; i++){
		players[i].startedTurn = false;
	}
}

// Start new game. This restarts current game. Does not resest Games Played.
// Do not set views to not touch enabled so names can be used to skip turns
// REVERSE THIS LOOP, RUN NUMBERS INSIDE OF PLAYERS TO NOT RUN THINGS TOO MANY TIMES WHEN I DONT NEED TO
var start_new_game = function(){
	for(var numOfViews=0;numOfViews<totalPlayers;numOfViews++){
		for(var numOfButtons=0;numOfButtons<7;numOfButtons++){
			players[numOfViews].buttons[numOfButtons].hits = 0;
			players[numOfViews].buttons[numOfButtons].animate(notSeeThru);
			// May be able to use Status and CLosed for the same thing and make this loop shorter
			players[numOfViews].buttons[numOfButtons].status = true;
			players[numOfViews].buttons[numOfButtons].touchEnabled = false;
			players[numOfViews].buttons[numOfButtons].closed = false;
			calculate_points(players[numOfViews].buttons[numOfButtons], 0, 0);
			availNums[numOfButtons].animate(notSeeThru);
		}
			printScore(views[numOfViews].children[8], 0);
			players[numOfViews].turn = false;
	}
	if(currentPlayerIndex>0){
		slideBanner(turnBanners[currentPlayerIndex],'up');
	}
	resetGlobalVars();
	currentPlayerStart(0);
}

var end_set = function(){
	GameView.animate(gameSlideDown);
	for(i=0;i<totalPlayers;i++){
		viewChildrenCount = views[i].children.length;
		for(var numOfButtons=0;numOfButtons<viewChildrenCount;numOfButtons++){
			viewChild = views[i].children[numOfButtons];
			if(viewChild != null){
				views[i].remove(views[i].children[numOfButtons]);
			}
		}
		players[i].buttons.length = 0;
		GameView.remove(views[i]);
	}
	views.length = 0;
	GameNumber = 0;
	playButtonCheck();
}
<commit_msg>added comments<commit_after>
var playersClosed = 0;
var playersFinished = 0;
var sameScore = 0;
var viewChildrenCount = 0;
var viewChild = null;

// Disable number that is no longer scorable for any player
// Is passed index of clicked number to compare with other numbers of same index
var closeNumbers = function(indx){
	var hits_on_this_num = 0;
	for(i=0;i<views.length;i++){
		if(views[i].children[indx].hits>=3){
			hits_on_this_num++;
		}
	}
	if(hits_on_this_num==views.length){
		for(i=0;i<views.length;i++){
			views[i].children[indx].touchEnabled=false;
			views[i].children[indx].status=false;
			views[i].children[indx].animate(seeThru);
			views[i].children[indx].color = '#ffffff';
			views[i].children[indx].backgroundImage = 'images/'+device+'/button.png';
		}
		availNums[indx].animate(seeThru);
		return true;
	};
}

var openNumbers = function(button){
	// Reverse the number closure
	if(players[button.playerNum].turn){
		button.touchEnabled=true;
	}
	button.status=true;
	button.animate(notSeeThru);
	highlight(button);
	availNums[button.index].animate(notSeeThru);
}

// determines which player holds highest score, does not account for 2 players having the same high score
// This never runs if the first to finish does not have highest score
var highestIndex = null;
var highestScoreTmp = 0;
var has_highest_score = function(){
	for(i=0;i<totalPlayers;i++){
        if (players[i].score > highestScoreTmp) {
            highestIndex = i;
            highestScoreTmp = players[i].score;
        }
	}
	if(highestIndex!=null){
		if(playerFinishedNums(highestIndex)){
	    	return true;
		}
	} else {
		highestScoreTmp = 0;
	    return false;
	}
}

// This checks if all players have started their turns
var allPlayersFinished = function(){
	for(i=0; i<totalPlayers; i++){
		if(players[i].startedTurn){
			playersFinished++;
		}
	}
	// try removing throwsThisRound == 3 to end game even if not all darts are thrown
	if(playersFinished == totalPlayers && throwsThisRound == 3){
		playersFinished=0;
		return true;
	} else {
		playersFinished = 0;
		return false;
	}
}

var displayWinner = function(winner){
	players[winner].wins += 1;
	GameNumber++;
	//Games to play is defined in options.js, imported after closer.js, this breaks
	if(players[winner].wins>GamesToPlay/2){
		winnerOfSets(players[winner].name);
	} else {
		winnerAlert(players[winner].name);
	}
}

// Counts how many closed numbers the specified player has,
// returns true if player finished all numbers
var currentPlayerFinished = 0;
var playerFinishedNums = function(playerIndex){
	for(var i=0;i<7;i++){
		if(players[playerIndex].buttons[i].closed){
			currentPlayerFinished++;
		}
	}
	if(currentPlayerFinished==7) {
		players[playerIndex].allClosed = true;
		currentPlayerFinished = 0;
		return true;
	} else {
		currentPlayerFinished = 0;
		return false;
	}
}

var someoneFinished = false;
var closedNums = 0;
var closedConfirm = 0
var playersChecked = 0;
var firstPlayerToClose = null;
var checkClosedNums = function(buttons, player){
	// This is in case a player has closed all numbers
	// and then undoes moves to open numbers
	if(someoneFinished) {
		for(var i=0;i<totalPlayers;i++){
			for(var a=0;a<players[i].buttons.length;a++){
				if(players[i].buttons[a].hits>2){
					closedConfirm++;
				}
			}
			if(closedConfirm<7){
				closedConfirm = 0;
				someoneFinished = false;
				players[i].allClosed = false;
			} else {
				closedConfirm = 0;
				someoneFinished = true;
				playersChecked = 0;
				players[i].allClosed = true;
				break;
			}
			playersChecked++;
			if(playersChecked==totalPlayers && !someoneFinished){
				firstPlayerToClose = null;
			}
		}
	}
	for(i=0;i<7;i++){
		if(buttons[i].hits>2){
			closedNums++;
		}
		if(closedNums==7) {
			firstPlayerToClose = currentPlayerIndex;
			someoneFinished = true;
			player.allClosed = true;
		}
	}
	closedNums=0;
}

// Determine if all players have closed all numbers
var playersAllClosed = 0;
var allPlayersClosedAllNumbers = function(){
	for(var i=0;i<totalPlayers;i++){
		for(var a=0;a<players[i].buttons.length;a++){
			if(players[i].buttons[a].hits>2){
				closedConfirm++;
			}
		}
		if(closedConfirm<7){
			closedConfirm = 0;
			playersAllClosed = 0;
			return false;
		} else {
			closedConfirm = 0;
			playersChecked = 0;
			playersAllClosed++;
		}
	}
	if(playersAllClosed==totalPlayers){
		playersAllClosed = 0;
		return true;
	}
}

// Determines if 2 or more players are tied
var matchesHighestScore = function(playerToCheck, topScore){
	if (players[playerToCheck].score == topScore){
    	return true;
    } else {
    	return false;
	}
}

var winner = function(){
	if (totalPlayers == 1) {
		// If only one person is playing
		singlePlayerFinished()
	} else if(has_highest_score() && allPlayersFinished()) {
		// Player who closed all numbers who also has highest score wins
		lastTurn = true;
		displayWinner(highestIndex);
		highestIndex = null;
		highestScoreTmp = 0;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
	} else if(tieGame()) {
		// Game is tied
		lastTurn = true;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
		tieAlert();
	} else if(matchesHighestScore(firstPlayerToClose, highestScore) && allPlayersFinished()) {
		// this is running because it's "matching" the highest score, even if it is itself
		// If at least 2 players are tied in score, but one player has closed all numbers, and all players have finished their last turn
		lastTurn = true;
		views[currentPlayerIndex].remove(indicators);
		slideBanner(turnBanners[currentPlayerIndex],'up');
		displayWinner(firstPlayerToClose);
	}
}

// Checks if all players have closed all numbers and score is the same
var tieGame = function(){
	for(i=0; i<totalPlayers; i++){
		if(players[i].score == highestScore){
			sameScore++;
		}
	}
	if(allPlayersClosedAllNumbers() && sameScore == totalPlayers){
		sameScore = 0;
		return true;
	} else {
		sameScore = 0;
		return false;
	}
}

var singlePlayerFinished = function(winner){
	var gameWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Game Finished',
	    message: 'You closed all the numbers!',
	    buttonNames: ['New Game', 'Quit'],
	    cancel: 0
	});
	gameWinnerAlert.show();
	gameWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var winnerAlert = function(winner){
	var gameWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Game Finished',
	    message: winner + ' wins!',
	    buttonNames: ['Next Game', 'Quit Set'],
	    cancel: 0
	});
	gameWinnerAlert.show();
	gameWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var tieAlert = function(){
	var gameTieAlert = Titanium.UI.createAlertDialog({
	    title: 'Tie Game!',
	    message: 'Wow... really? Ok well you\'ll have to play that game again. We need a winner!',
	    buttonNames: ['Next Game', 'Quit Set'],
	    cancel: 0
	});
	gameTieAlert.show();
	gameTieAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			start_new_game();
		} else if(e.index == 1) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var resetCounts = function(){
	throwsThisRound = 0;
	numberTracker.length = 0;
}

var winnerOfSets = function(winner){
	var setsWinnerAlert = Titanium.UI.createAlertDialog({
	    title: 'Set Finished',
	    message: winner + ' wins the set!',
	    buttonNames: ['OK', 'New Set', 'Change Players'],
	    cancel: 0
	});
	setsWinnerAlert.show();
	setsWinnerAlert.addEventListener('click',function(e){
		if(e.index == 0) {
			// if user presses OK, all buttons are made untouchable.
			for(numOfButtons=0;numOfButtons<7;numOfButtons++){
				for(var numOfViews=0;numOfViews<totalPlayers;numOfViews++){
					views[numOfViews].touchEnabled = false;
					miss.touchEnabled = false;
					undoPoints.touchEnabled = false;
				}
			}
		} else if(e.index == 1) {
			GameNumber = 0;
			start_new_game();
			for(var i=0;i<totalPlayers;i++){
				players[i].wins = 0;
			}
		} else if(e.index == 2) {
			win1.open();
			win2.close();
			end_set();
		}
	});
}

var resetGlobalVars = function(){
	currentPlayerIndex = 0;
	throwsThisRound = 0;
	totalThrows = 0;
	numberTracker.length = 0;
	players[0].turn = true;
	players[0].startedTurn = true;
	views[0].touchEnabled = true;
	miss.touchEnabled = true;
	undoPoints.touchEnabled = true;
	someoneFinished = false;
	indicatorsRemoved = false;
	lastTurn = false;
	firstPlayerToClose = null;
	for(i=0; i<totalPlayers; i++){
		players[i].startedTurn = false;
	}
}

// Start new game. This restarts current game. Does not resest Games Played.
// Do not set views to not touch enabled so names can be used to skip turns
// REVERSE THIS LOOP, RUN NUMBERS INSIDE OF PLAYERS TO NOT RUN THINGS TOO MANY TIMES WHEN I DONT NEED TO
var start_new_game = function(){
	for(var numOfViews=0;numOfViews<totalPlayers;numOfViews++){
		for(var numOfButtons=0;numOfButtons<7;numOfButtons++){
			players[numOfViews].buttons[numOfButtons].hits = 0;
			players[numOfViews].buttons[numOfButtons].animate(notSeeThru);
			// May be able to use Status and CLosed for the same thing and make this loop shorter
			players[numOfViews].buttons[numOfButtons].status = true;
			players[numOfViews].buttons[numOfButtons].touchEnabled = false;
			players[numOfViews].buttons[numOfButtons].closed = false;
			calculate_points(players[numOfViews].buttons[numOfButtons], 0, 0);
			availNums[numOfButtons].animate(notSeeThru);
		}
			printScore(views[numOfViews].children[8], 0);
			players[numOfViews].turn = false;
	}
	if(currentPlayerIndex>0){
		slideBanner(turnBanners[currentPlayerIndex],'up');
	}
	resetGlobalVars();
	currentPlayerStart(0);
}

// Try setting all arrays to 0 instead of removing each individual element.
var end_set = function(){
	GameView.animate(gameSlideDown);
	for(i=0;i<totalPlayers;i++){
		viewChildrenCount = views[i].children.length;
		for(var numOfButtons=0;numOfButtons<viewChildrenCount;numOfButtons++){
			viewChild = views[i].children[numOfButtons];
			if(viewChild != null){
				views[i].remove(views[i].children[numOfButtons]);
			}
		}
		players[i].buttons.length = 0;
		GameView.remove(views[i]);
	}
	views.length = 0;
	GameNumber = 0;
	playButtonCheck();
}
<|endoftext|>


<commit_before>var reload = (function () {

var exports = {};

var reload_in_progress = false;
var reload_pending = false;

exports.is_pending = function () {
    return reload_pending;
};

exports.is_in_progress = function () {
    return reload_in_progress;
};

function preserve_compose(send_after_reload) {
    if (send_after_reload === undefined) {
        send_after_reload = 0;
    }
    var url = "#reload:send_after_reload=" + Number(send_after_reload);
    if (compose.composing() === 'stream') {
        url += "+msg_type=stream";
        url += "+stream=" + encodeURIComponent(compose.stream_name());
        url += "+subject=" + encodeURIComponent(compose.subject());
    } else {
        url += "+msg_type=private";
        url += "+recipient=" + encodeURIComponent(compose.recipient());
    }
    url += "+msg="+ encodeURIComponent(compose.message_content());

    window.location.replace(url);
}

// Check if we're doing a compose-preserving reload.  This must be
// done before the first call to get_updates
$(function () {
    var location = window.location.toString();
    window.location = '#';
    var fragment = location.substring(location.indexOf('#') + 1);
    if (fragment.search("reload:") !== 0) {
        return;
    }

    fragment = fragment.replace(/^reload:/, "");
    var keyvals = fragment.split("+");
    var vars = {};
    $.each(keyvals, function (idx, str) {
        var pair = str.split("=");
        vars[pair[0]] = decodeURIComponent(pair[1]);
    });

    var tab;
    var send_now = parseInt(vars.send_after_reload, 10);

    // TODO: preserve focus
    compose.start(vars.msg_type, {stream: vars.stream,
                                 subject: vars.subject,
                                 private_message_recipient: vars.recipient,
                                 message: vars.msg});
    if (send_now) {
        compose.finish();
    }
});

function do_reload_app(send_after_reload) {
    // TODO: we should completely disable the UI here
    if (compose.composing()) {
        preserve_compose(send_after_reload);
    }
    // TODO: We need a better API for showing messages.
    report_message("The application has been updated; reloading!", $("#reloading-application"));
    reload_in_progress = true;
    window.location.reload(true);
}

exports.initiate = function (options) {
    var defaults = {immediate: false,
                    send_after_reload: false};
    options = $.extend(defaults, options);

    if (options.immediate) {
        do_reload_app(options.send_after_reload);
    }

    if (reload_pending) {
        return;
    }
    reload_pending = true;

    // Always reload after 30 minutes
    setTimeout(function () { do_reload_app(false); }, 1000 * 60 * 30);

    // If the user is composing a message, reload if they become idle
    // while composing.  If they finish or cancel the compose, wait
    // until they're idle again
    var idle_control;
    var composing_timeout = 1000*60*5;
    var home_timeout = 1000*60;
    var compose_done_handler, compose_started_handler;

    compose_done_handler = function () {
        idle_control.cancel();
        idle_control = $(document).idle({'idle': home_timeout,
                                         'onIdle': do_reload_app});
        $(document).off('compose_canceled.zephyr compose_finished.zephyr',
                        compose_done_handler);
        $(document).on('compose_started.zephyr', compose_started_handler);
    };
    compose_started_handler = function () {
        idle_control.cancel();
        idle_control = $(document).idle({'idle': composing_timeout,
                                         'onIdle': do_reload_app});
        $(document).off('compose_started.zephyr', compose_started_handler);
        $(document).on('compose_canceled.zephyr compose_finished.zephyr',
                       compose_done_handler);
    };

    if (compose.composing()) {
        idle_control = $(document).idle({'idle': composing_timeout,
                                         'onIdle': do_reload_app});
        $(document).on('compose_canceled.zephyr compose_finished.zephyr',
                       compose_done_handler);
    } else {
        idle_control = $(document).idle({'idle': home_timeout,
                                         'onIdle': do_reload_app});
        $(document).on('compose_started.zephyr', compose_started_handler);
    }
};

return exports;
}());
<commit_msg>Set and check csrf_token for #reload<commit_after>var reload = (function () {

var exports = {};

var reload_in_progress = false;
var reload_pending = false;

exports.is_pending = function () {
    return reload_pending;
};

exports.is_in_progress = function () {
    return reload_in_progress;
};

function preserve_compose(send_after_reload) {
    if (send_after_reload === undefined) {
        send_after_reload = 0;
    }
    var url = "#reload:send_after_reload=" + Number(send_after_reload);
    url += "+csrf_token=" + encodeURIComponent(csrf_token);
    if (compose.composing() === 'stream') {
        url += "+msg_type=stream";
        url += "+stream=" + encodeURIComponent(compose.stream_name());
        url += "+subject=" + encodeURIComponent(compose.subject());
    } else {
        url += "+msg_type=private";
        url += "+recipient=" + encodeURIComponent(compose.recipient());
    }
    url += "+msg="+ encodeURIComponent(compose.message_content());

    window.location.replace(url);
}

// Check if we're doing a compose-preserving reload.  This must be
// done before the first call to get_updates
$(function () {
    var location = window.location.toString();
    window.location = '#';
    var fragment = location.substring(location.indexOf('#') + 1);
    if (fragment.search("reload:") !== 0) {
        return;
    }

    fragment = fragment.replace(/^reload:/, "");
    var keyvals = fragment.split("+");
    var vars = {};
    $.each(keyvals, function (idx, str) {
        var pair = str.split("=");
        vars[pair[0]] = decodeURIComponent(pair[1]);
    });

    // Prevent random people on the Internet from constructing links
    // that make you send a message.
    if (vars.csrf_token !== csrf_token) {
        return;
    }

    var tab;
    var send_now = parseInt(vars.send_after_reload, 10);

    // TODO: preserve focus
    compose.start(vars.msg_type, {stream: vars.stream,
                                 subject: vars.subject,
                                 private_message_recipient: vars.recipient,
                                 message: vars.msg});
    if (send_now) {
        compose.finish();
    }
});

function do_reload_app(send_after_reload) {
    // TODO: we should completely disable the UI here
    if (compose.composing()) {
        preserve_compose(send_after_reload);
    }
    // TODO: We need a better API for showing messages.
    report_message("The application has been updated; reloading!", $("#reloading-application"));
    reload_in_progress = true;
    window.location.reload(true);
}

exports.initiate = function (options) {
    var defaults = {immediate: false,
                    send_after_reload: false};
    options = $.extend(defaults, options);

    if (options.immediate) {
        do_reload_app(options.send_after_reload);
    }

    if (reload_pending) {
        return;
    }
    reload_pending = true;

    // Always reload after 30 minutes
    setTimeout(function () { do_reload_app(false); }, 1000 * 60 * 30);

    // If the user is composing a message, reload if they become idle
    // while composing.  If they finish or cancel the compose, wait
    // until they're idle again
    var idle_control;
    var composing_timeout = 1000*60*5;
    var home_timeout = 1000*60;
    var compose_done_handler, compose_started_handler;

    compose_done_handler = function () {
        idle_control.cancel();
        idle_control = $(document).idle({'idle': home_timeout,
                                         'onIdle': do_reload_app});
        $(document).off('compose_canceled.zephyr compose_finished.zephyr',
                        compose_done_handler);
        $(document).on('compose_started.zephyr', compose_started_handler);
    };
    compose_started_handler = function () {
        idle_control.cancel();
        idle_control = $(document).idle({'idle': composing_timeout,
                                         'onIdle': do_reload_app});
        $(document).off('compose_started.zephyr', compose_started_handler);
        $(document).on('compose_canceled.zephyr compose_finished.zephyr',
                       compose_done_handler);
    };

    if (compose.composing()) {
        idle_control = $(document).idle({'idle': composing_timeout,
                                         'onIdle': do_reload_app});
        $(document).on('compose_canceled.zephyr compose_finished.zephyr',
                       compose_done_handler);
    } else {
        idle_control = $(document).idle({'idle': home_timeout,
                                         'onIdle': do_reload_app});
        $(document).on('compose_started.zephyr', compose_started_handler);
    }
};

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


<commit_before>function resize_main_div() {
    // Resize main_div to exactly take up remaining vertical space.
    var div = $('#main_div');
    div.height(Math.max(200, div.height() + $(window).height() - $('body').height()));
}
$(function () {
    resize_main_div();
    $(window).resize(resize_main_div);
    $('#zephyr-type-tabs a').on('shown', function (e) { resize_main_div(); });
});

$.ajaxSetup({
     beforeSend: function(xhr, settings) {
         function getCookie(name) {
             var cookieValue = null;
             if (document.cookie && document.cookie != '') {
                 var cookies = document.cookie.split(';');
                 for (var i = 0; i < cookies.length; i++) {
                     var cookie = jQuery.trim(cookies[i]);
                     // Does this cookie string begin with the name we want?
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     }
});

selected_tag = '
▶
'

function textarea_in_focus() {
    return $("#class").is(":focus") || $("#instance").is(":focus") || $("#new_zephyr").is(":focus") || $("#new_personal_zephyr").is(":focus") || $("#recipient").is(":focus");
}

$(document).keydown(function(event) {
    if (event.keyCode == 38 || event.keyCode == 40) { // down or up arrow
	// Remove focus from zephyr creation.
	$("#new_zephyr").blur();
	$("#new_personal_zephyr").blur();

        p = $("#selected");
        tr = $(p).closest("tr");
        td = $(p).closest("td");

        if (event.keyCode == 40) { // down arrow
            // There are probably more verbose but more efficient ways to do this.
            next_zephyr = tr.nextAll(":not(:hidden):first");
        } else { // up arrow
            next_zephyr = tr.prevAll(":not(:hidden):first");
        }
        if (next_zephyr.length != 0) { // We are not at the bottom or top of the zephyrs.
            next_zephyr.children("td:first").html(selected_tag);
            td.empty(); // Clear the previous arrow.
            $.post("update", {pointer: next_zephyr.attr("id")});

            if ($(next_zephyr).offset().top < $("#main_div").offset().top) {
                $("#main_div").scrollTop($("#main_div").scrollTop() - 75);
            }

            if ($(next_zephyr).offset().top + $(next_zephyr).height() > $("#main_div").offset().top + $("#main_div").height()) {
                $("#main_div").scrollTop($("#main_div").scrollTop() + 75);
            }
        }
    } else if ((event.keyCode == 82) && !textarea_in_focus()) { // 'r' keypress, for responding to a zephyr
        var parent = $("#selected").parents("tr");
        var zephyr_class = parent.find("span.zephyr_class").text();
	var instance = parent.find("span.zephyr_instance").text();
        $("#class").val(zephyr_class);
        $("#instance").val(instance);
        $("#new_zephyr").focus();
	event.preventDefault();
    }
});

function scroll_to_zephyr(target_zephyr, old_offset) {
    // target_zephyr is an id.
    // old_offset is how far from the top of the scroll area the
    // zephyr was before any narrowing or unnarrowing happened.
    var height_above_zephyr = 0;
    $("#table tr:lt(" + $("#" + target_zephyr).index() + ")").each(function() {
        if (!$(this).is(":hidden")) {
            height_above_zephyr += $(this).height();
        }
    });
    $("#main_div").scrollTop(height_above_zephyr + old_offset);
}

function hide_personals() {
    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").hide();
        }
    );
}

function narrow_personals(target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;

    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").show();
        }
    );
    $("span.zephyr_class").each(
        function() {
            $(this).parents("tr").hide();
        }
    );

    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing personals");
}

function narrow(class_name, target_zephyr) {
    // We want the zephyr on which the narrow happened to stay in the same place if possible.
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("span.zephyr_class").each(
        function() {
            if ($(this).text() != class_name) {
                $(this).parents("tr").hide();
            } else {
                // If you've narrowed on an instance and then click on the class, that should unhide the other instances on that class.
                $(this).parents("tr").show();
	    }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    // Try to keep the zephyr in the same place on the screen after narrowing.
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name + "");
}

function narrow_instance(class_name, instance, target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("tr").each(
        function() {
            if (($(this).find("span.zephyr_class").text() != class_name) ||
		($(this).find("span.zephyr_instance").text() != instance)) {
                $(this).hide();
	    }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    // Try to keep the zephyr in the same place on the screen after narrowing.
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name
      + " " + instance + "");
}

function prepare_personal(username) {
    $('#zephyr-type-tabs a[href="#personal-message"]').tab('show');
    $("#recipient").val(username);
    $("#new_personal_zephyr").focus();
}

function unhide() {
    $("tr").show();

    p = $("#selected");
    tr = $(p).closest("tr");
    scroll_to_zephyr(tr.attr("id"), 0);

    $("#unhide").attr("disabled", "disabled");
    $("#narrow_indicator").html("");
}

$(function() {
  setInterval(get_updates, 1000);
});

function newline2br(content) {
    return content.replace(/\n/g, '
');
}

function add_message(index, zephyr) {
    var new_str = "
" +
	"

	" +
	"
";
    if (zephyr.type == "class") {
        new_str += "" + zephyr.display_recipient + " "
                +  "" +
                   zephyr.instance + " ";
    } else {
        new_str += "" +
                   zephyr.display_recipient + ""
                   + " ← ";
    }
    new_str += ""
        + zephyr.sender + "
"
	+ newline2br(zephyr.content) +
	"
	" +
	"
";
    $("#table tr:last").after(new_str);
}

function get_updates() {
    var last_received = $("tr:last").attr("id");
    $.post("get_updates", {last_received: last_received},
           function(data) {
               $.each(data, add_message);
    }, "json");
}
<commit_msg>Focus first text field on tab switch<commit_after>function resize_main_div() {
    // Resize main_div to exactly take up remaining vertical space.
    var div = $('#main_div');
    div.height(Math.max(200, div.height() + $(window).height() - $('body').height()));
}
$(function () {
    resize_main_div();
    $(window).resize(resize_main_div);
    $('#zephyr-type-tabs a').on('shown', function (e) { resize_main_div(); });
});

$(function() {
    $('#zephyr-type-tabs a[href="#class-message"]').on('shown', function (e) {
        $('#class-message input:not(:hidden):first').focus().select();
    });
    $('#zephyr-type-tabs a[href="#personal-message"]').on('shown', function (e) {
        $('#personal-message input:not(:hidden):first').focus().select();
    });
});

$.ajaxSetup({
     beforeSend: function(xhr, settings) {
         function getCookie(name) {
             var cookieValue = null;
             if (document.cookie && document.cookie != '') {
                 var cookies = document.cookie.split(';');
                 for (var i = 0; i < cookies.length; i++) {
                     var cookie = jQuery.trim(cookies[i]);
                     // Does this cookie string begin with the name we want?
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     }
});

selected_tag = '
▶
'

function textarea_in_focus() {
    return $("#class").is(":focus") || $("#instance").is(":focus") || $("#new_zephyr").is(":focus") || $("#new_personal_zephyr").is(":focus") || $("#recipient").is(":focus");
}

$(document).keydown(function(event) {
    if (event.keyCode == 38 || event.keyCode == 40) { // down or up arrow
	// Remove focus from zephyr creation.
	$("#new_zephyr").blur();
	$("#new_personal_zephyr").blur();

        p = $("#selected");
        tr = $(p).closest("tr");
        td = $(p).closest("td");

        if (event.keyCode == 40) { // down arrow
            // There are probably more verbose but more efficient ways to do this.
            next_zephyr = tr.nextAll(":not(:hidden):first");
        } else { // up arrow
            next_zephyr = tr.prevAll(":not(:hidden):first");
        }
        if (next_zephyr.length != 0) { // We are not at the bottom or top of the zephyrs.
            next_zephyr.children("td:first").html(selected_tag);
            td.empty(); // Clear the previous arrow.
            $.post("update", {pointer: next_zephyr.attr("id")});

            if ($(next_zephyr).offset().top < $("#main_div").offset().top) {
                $("#main_div").scrollTop($("#main_div").scrollTop() - 75);
            }

            if ($(next_zephyr).offset().top + $(next_zephyr).height() > $("#main_div").offset().top + $("#main_div").height()) {
                $("#main_div").scrollTop($("#main_div").scrollTop() + 75);
            }
        }
    } else if ((event.keyCode == 82) && !textarea_in_focus()) { // 'r' keypress, for responding to a zephyr
        var parent = $("#selected").parents("tr");
        var zephyr_class = parent.find("span.zephyr_class").text();
	var instance = parent.find("span.zephyr_instance").text();
        $("#class").val(zephyr_class);
        $("#instance").val(instance);
        $("#new_zephyr").focus();
	event.preventDefault();
    }
});

function scroll_to_zephyr(target_zephyr, old_offset) {
    // target_zephyr is an id.
    // old_offset is how far from the top of the scroll area the
    // zephyr was before any narrowing or unnarrowing happened.
    var height_above_zephyr = 0;
    $("#table tr:lt(" + $("#" + target_zephyr).index() + ")").each(function() {
        if (!$(this).is(":hidden")) {
            height_above_zephyr += $(this).height();
        }
    });
    $("#main_div").scrollTop(height_above_zephyr + old_offset);
}

function hide_personals() {
    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").hide();
        }
    );
}

function narrow_personals(target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;

    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").show();
        }
    );
    $("span.zephyr_class").each(
        function() {
            $(this).parents("tr").hide();
        }
    );

    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing personals");
}

function narrow(class_name, target_zephyr) {
    // We want the zephyr on which the narrow happened to stay in the same place if possible.
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("span.zephyr_class").each(
        function() {
            if ($(this).text() != class_name) {
                $(this).parents("tr").hide();
            } else {
                // If you've narrowed on an instance and then click on the class, that should unhide the other instances on that class.
                $(this).parents("tr").show();
	    }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    // Try to keep the zephyr in the same place on the screen after narrowing.
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name + "");
}

function narrow_instance(class_name, instance, target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("tr").each(
        function() {
            if (($(this).find("span.zephyr_class").text() != class_name) ||
		($(this).find("span.zephyr_instance").text() != instance)) {
                $(this).hide();
	    }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    // Try to keep the zephyr in the same place on the screen after narrowing.
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name
      + " " + instance + "");
}

function prepare_personal(username) {
    $('#zephyr-type-tabs a[href="#personal-message"]').tab('show');
    $("#recipient").val(username);
    $("#new_personal_zephyr").focus();
}

function unhide() {
    $("tr").show();

    p = $("#selected");
    tr = $(p).closest("tr");
    scroll_to_zephyr(tr.attr("id"), 0);

    $("#unhide").attr("disabled", "disabled");
    $("#narrow_indicator").html("");
}

$(function() {
  setInterval(get_updates, 1000);
});

function newline2br(content) {
    return content.replace(/\n/g, '
');
}

function add_message(index, zephyr) {
    var new_str = "
" +
	"

	" +
	"
";
    if (zephyr.type == "class") {
        new_str += "" + zephyr.display_recipient + " "
                +  "" +
                   zephyr.instance + " ";
    } else {
        new_str += "" +
                   zephyr.display_recipient + ""
                   + " ← ";
    }
    new_str += ""
        + zephyr.sender + "
"
	+ newline2br(zephyr.content) +
	"
	" +
	"
";
    $("#table tr:last").after(new_str);
}

function get_updates() {
    var last_received = $("tr:last").attr("id");
    $.post("get_updates", {last_received: last_received},
           function(data) {
               $.each(data, add_message);
    }, "json");
}
<|endoftext|>


<commit_before>/* jshint node: true */
/* jshint esnext: true */
'use strict';
const crypto = require('crypto');
const config = require('config');

const editUrlHelper = () => {

  return {
    generateUrl: (value) => {
      return `${config.get('pace-url')}/editparticipant/` + encodeURIComponent(value);
    },
    generateUrlForAdmin: (value) => {
      return `${config.get('pace-url')}/admin/editparticipant/` + encodeURIComponent(value);
    },
    generateSecureID: () => {
      return crypto.randomBytes(32).toString('hex');
    }
  };
}();

module.exports = editUrlHelper;
<commit_msg>@codergolem & @sreedhap & @cz8s | Fixes a syntax to work with node6<commit_after>/* jshint node: true */
/* jshint esnext: true */
'use strict';
const crypto = require('crypto');
const config = require('config');

const editUrlHelper = (() => {

  return {
    generateUrl: (value) => {
      return `${config.get('pace-url')}/editparticipant/` + encodeURIComponent(value);
    },
    generateUrlForAdmin: (value) => {
      return `${config.get('pace-url')}/admin/editparticipant/` + encodeURIComponent(value);
    },
    generateSecureID: () => {
      return crypto.randomBytes(32).toString('hex');
    }
  };
})();

module.exports = editUrlHelper;
<|endoftext|>


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

var userSchema = mongoose.Schema({
  username: { type: String, required: true },
  endpoints: {}
});

var User = mongoose.model('User', userSchema);

module.exports = User;

<commit_msg>add userID to db<commit_after>var mongoose = require('mongoose');
var db = require('../../db');

var userSchema = mongoose.Schema({
  username: { type: String, required: true },
  userID: { type: Number, required: true},
  endpoints: {}
});

var User = mongoose.model('User', userSchema);

module.exports = User;

<|endoftext|>