<commit_before>/*
 * Copyright (c) 2015-2016 PointSource, LLC.
 * MIT Licensed
 */

var path = require('path');
var fs = require('fs');
var debug = require('debug')('swagger');
var async = require('async');
var parser = require('swagger-parser');
var deref = require('json-schema-deref');

var specs = {
    dereferenced: {},
    bundled: {}
};

exports.init = function(logger, callback) {

    var swaggerDir = null;
    if (isBlueoakProject()) {
        swaggerDir = path.resolve(global.__appDir, '../common/swagger');
    } else {
        swaggerDir = path.resolve(global.__appDir, 'swagger');
    }

    debug('Loading swagger files from %s', swaggerDir);

    var files = [];

    try {
        fs.readdirSync(swaggerDir).forEach(function (fileName) {
            //look for json and yaml
            if (path.extname(fileName) === '.json') {
                files.push(path.resolve(swaggerDir, fileName));
            } else if (path.extname(fileName) === '.yaml') {
                files.push(path.resolve(swaggerDir, fileName));
            }
        });
    } catch (err) {
        //swagger dir probably doesn't exist
        return callback();
    }

    //Loop through all our swagger models
    //For each model, parse it, and automatically hook up the routes to the appropriate handler
    async.eachSeries(files, function parseSwagger(file, swagCallback) {

        parser.bundle(file, function (err, api, metadata) {

            if (err && path.extname(file) === '.yaml') {
                return swagCallback(err);
            }

            if (err) {
                //Was this an actual swagger file?  Could just be a partial swagger pointed to by a $ref
                try {
                    var json = JSON.parse(fs.readFileSync(file));

                    //valid JSON
                    if (isSwaggerFile(json)) {
                        //this must be a swagger file, but it doesn't validate. fail
                        return swagCallback(err);
                    }
                } catch (err) {
                    //wasn't even valid JSON, error out
                    return swagCallback(err);
                }

                logger.warn('Skipping %s', file);
                return swagCallback();
            }

            //no error
            var handlerName = path.basename(file); //use the swagger filename as our handler module id
            handlerName = handlerName.substring(0, handlerName.lastIndexOf('.')); //strip extensions

            specs.bundled[handlerName] = api;
            deref(api, function (err, apiAsPlainJson) {
                if (err) {
                    logger.error('Failed dereferencing swagger spec: ' + file);
                    return swagCallback(err);
                }
                specs.dereferenced[handlerName] = apiAsPlainJson;
            });

            return swagCallback();
        });
    }, function(err) {
        callback(err);
    });

};

exports.getSimpleSpecs = function() {
    return specs.dereferenced;
};

exports.getPrettySpecs = function () {
    return specs.bundled;
};

//Try to determine if this is supposed to be a swagger file
//For now look for the required "swagger" field, which contains the version
function isSwaggerFile(json) {
    return json.swagger;
}

//There are two possible places for loading swagger.
//If we're part of a broader blueoak client-server project, blueoak is running
//from a 'server' directory, and there's a sibling directory named 'common' which contains the swagger directory.
//Otherwise we just look in the normal swagger folder within the project
function isBlueoakProject() {
    try {
        return path.basename(global.__appDir) === 'server'
            && fs.statSync(path.resolve(global.__appDir, '../common/swagger'));
    } catch (err) {
        //the fs.statSync will return false if dir doesn't exist
        return false;
    }

}<commit_msg>Call the swagger callback once deref completes<commit_after>/*
 * Copyright (c) 2015-2016 PointSource, LLC.
 * MIT Licensed
 */

var path = require('path');
var fs = require('fs');
var debug = require('debug')('swagger');
var async = require('async');
var parser = require('swagger-parser');
var deref = require('json-schema-deref');

var specs = {
    dereferenced: {},
    bundled: {}
};

exports.init = function(logger, callback) {

    var swaggerDir = null;
    if (isBlueoakProject()) {
        swaggerDir = path.resolve(global.__appDir, '../common/swagger');
    } else {
        swaggerDir = path.resolve(global.__appDir, 'swagger');
    }

    debug('Loading swagger files from %s', swaggerDir);

    var files = [];

    try {
        fs.readdirSync(swaggerDir).forEach(function (fileName) {
            //look for json and yaml
            if (path.extname(fileName) === '.json') {
                files.push(path.resolve(swaggerDir, fileName));
            } else if (path.extname(fileName) === '.yaml') {
                files.push(path.resolve(swaggerDir, fileName));
            }
        });
    } catch (err) {
        //swagger dir probably doesn't exist
        return callback();
    }

    //Loop through all our swagger models
    //For each model, parse it, and automatically hook up the routes to the appropriate handler
    async.eachSeries(files, function parseSwagger(file, swagCallback) {

        parser.bundle(file, function (err, api, metadata) {

            if (err && path.extname(file) === '.yaml') {
                return swagCallback(err);
            }

            if (err) {
                //Was this an actual swagger file?  Could just be a partial swagger pointed to by a $ref
                try {
                    var json = JSON.parse(fs.readFileSync(file));

                    //valid JSON
                    if (isSwaggerFile(json)) {
                        //this must be a swagger file, but it doesn't validate. fail
                        return swagCallback(err);
                    }
                } catch (err) {
                    //wasn't even valid JSON, error out
                    return swagCallback(err);
                }

                logger.warn('Skipping %s', file);
                return swagCallback();
            }

            //no error
            var handlerName = path.basename(file); //use the swagger filename as our handler module id
            handlerName = handlerName.substring(0, handlerName.lastIndexOf('.')); //strip extensions

            specs.bundled[handlerName] = api;
            deref(api, function (err, apiAsPlainJson) {
                if (err) {
                    logger.error('Failed dereferencing swagger spec: ' + file);
                    return swagCallback(err);
                }
                specs.dereferenced[handlerName] = apiAsPlainJson;
                return swagCallback();
            });
        });
    }, function(err) {
        callback(err);
    });

};

exports.getSimpleSpecs = function() {
    return specs.dereferenced;
};

exports.getPrettySpecs = function () {
    return specs.bundled;
};

//Try to determine if this is supposed to be a swagger file
//For now look for the required "swagger" field, which contains the version
function isSwaggerFile(json) {
    return json.swagger;
}

//There are two possible places for loading swagger.
//If we're part of a broader blueoak client-server project, blueoak is running
//from a 'server' directory, and there's a sibling directory named 'common' which contains the swagger directory.
//Otherwise we just look in the normal swagger folder within the project
function isBlueoakProject() {
    try {
        return path.basename(global.__appDir) === 'server'
            && fs.statSync(path.resolve(global.__appDir, '../common/swagger'));
    } catch (err) {
        //the fs.statSync will return false if dir doesn't exist
        return false;
    }

}<|endoftext|>


<commit_before>var jsonResume = (function() {
    var json = null;
    $.ajax({
        'async': false,
        'global': false,
        'url': "./resume-data/resume.json",
        'dataType': "json",
        'success': function (data) {
            json = data;
        }
    });
    return json;
})();

var bio = jsonResume.bio;
var education = jsonResume.education;
var work = jsonResume.work;
var projects = jsonResume.projects;

work.display = function() {
	work.jobs.forEach(function importWork(job) {
		$("#workExperience").append(HTMLworkStart);
		var employer = HTMLworkEmployer.replace("%data%",job.employer);
		var title = HTMLworkTitle.replace("%data%",job.title);
		// Other implementations may use dateObj in the future
		var dates = job.dateString ? HTMLworkDates.replace("%data%",job.dateString) : "";
		var location = HTMLworkLocation.replace("%data%",job.location);
		var description = HTMLworkDescription.replace("%data%",job.description);
		$(".work-entry:last").append(employer + title + dates + location + description);
	});
}

projects.display = function() {
	this.projects.forEach(function(project) {
		$("#projects").append(HTMLprojectStart);
		var title = HTMLprojectTitle.replace("%data%",project.title);
		var dates = HTMLprojectDates.replace("%data%",project.dates);
		var description = HTMLprojectDescription.replace("%data%",project.description);
		var imagesURL = [];
		project.images.forEach(function(url) {
			imagesURL.push(HTMLprojectImage.replace("%data%",url));
		});
		$(".project-entry:last").append(title + dates + description + imagesURL.join(""));
	});
}

work.display();
projects.display();

$("#header").append(HTMLheaderName.replace("%data%",bio.name));
$("#header").append(HTMLheaderRole.replace("%data%",bio.role));

if (bio.skills.length > 0) {
	console.log("skills exist");
	$("#header").append(HTMLskillsStart);
	bio.skills.forEach(function(skill) {
		$("#skills").append(HTMLskills.replace("%data%",skill));
	});
}

$(document).click(function(loc) {
	logClicks(loc.pageX, loc.pageY);
})

$("#main").append(internationalizeButton);

function inName(name) {
	var nameArray = name.split(" ");
	nameArray[1] = nameArray[1].toUpperCase();
	nameArray[0] = nameArray[0].charAt(0).toUpperCase() + nameArray[0].slice(1,nameArray[0].length).toLowerCase();
	return nameArray.join(" ");
}<commit_msg>adjust date.string formatting<commit_after>var jsonResume = (function() {
    var json = null;
    $.ajax({
        'async': false,
        'global': false,
        'url': "./resume-data/resume.json",
        'dataType': "json",
        'success': function (data) {
            json = data;
        }
    });
    return json;
})();

var bio = jsonResume.bio;
var education = jsonResume.education;
var work = jsonResume.work;
var projects = jsonResume.projects;

work.display = function() {
	work.jobs.forEach(function importWork(job) {
		$("#workExperience").append(HTMLworkStart);
		var employer = HTMLworkEmployer.replace("%data%",job.employer);
		var title = HTMLworkTitle.replace("%data%",job.title);
		// Other implementations may use dateObj in the future
		var dates = job.date.string ? HTMLworkDates.replace("%data%",job.date.string) : "";
		var location = HTMLworkLocation.replace("%data%",job.location);
		var description = HTMLworkDescription.replace("%data%",job.description);
		$(".work-entry:last").append(employer + title + dates + location + description);
	});
}

projects.display = function() {
	this.projects.forEach(function(project) {
		$("#projects").append(HTMLprojectStart);
		var title = HTMLprojectTitle.replace("%data%",project.title);
		var dates = HTMLprojectDates.replace("%data%",project.dates);
		var description = HTMLprojectDescription.replace("%data%",project.description);
		var imagesURL = [];
		project.images.forEach(function(url) {
			imagesURL.push(HTMLprojectImage.replace("%data%",url));
		});
		$(".project-entry:last").append(title + dates + description + imagesURL.join(""));
	});
}

work.display();
projects.display();

$("#header").append(HTMLheaderName.replace("%data%",bio.name));
$("#header").append(HTMLheaderRole.replace("%data%",bio.role));

if (bio.skills.length > 0) {
	console.log("skills exist");
	$("#header").append(HTMLskillsStart);
	bio.skills.forEach(function(skill) {
		$("#skills").append(HTMLskills.replace("%data%",skill));
	});
}

$(document).click(function(loc) {
	logClicks(loc.pageX, loc.pageY);
})

$("#main").append(internationalizeButton);

function inName(name) {
	var nameArray = name.split(" ");
	nameArray[1] = nameArray[1].toUpperCase();
	nameArray[0] = nameArray[0].charAt(0).toUpperCase() + nameArray[0].slice(1,nameArray[0].length).toLowerCase();
	return nameArray.join(" ");
}<|endoftext|>


<commit_before>jQuery(document).ready(function(){
	jQuery('.skillbar').each(function(){
		jQuery(this).find('.skillbar-bar').animate({
			width:jQuery(this).attr('data-percent')
		},6000);
	});
});
<commit_msg>Update sara_skillbar.js<commit_after> $(document).ready(function() {
      $('.progress .progress-bar').css("width",
                function() {
                    return $(this).attr("aria-valuenow") + "%";
                }
        )
    });
<|endoftext|>


<commit_before>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

	me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10);
	me.input.bindKey(me.input.KEY.ENTER, "start");

	me.game.world.addChild(new (me.Renderable.extend({

		init: function() {
			this._super(me.Renderable, 'init', [510, 30,  me.game.viewport.width, me.game.viewport.height]);
			this.font = new me.Font("Arial", 46, "white");
		},

	draw: function(renderer) {
			this.font.draw(renderer.getContext(), "Awsomenauts", 450, 130);
			this.font.draw(renderer.getContext(), "Press Enter", 250, 530);
	},

	})));

	this.handler = me.event.subscribe(me.event.KEYDOWN, function(action, keyCode, edge) {
	if (action === "start") {
			me.state.change(me.state.PLAY);
			}
		})
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		 me.input.unbindKey(me.input.KEY.ENTER);
		 me.event.unsubscribe(this.handler);
	}
});
<commit_msg> 39 Start New: -Added Start New Option - Able To Choose Start New Option By Clicking "Start New"<commit_after>game.TitleScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

	me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage('title-screen')), -10);

	me.game.world.addChild(new (me.Renderable.extend({

		init: function() {
			this._super(me.Renderable, 'init', [270, 240,  300, 50]);
			this.font = new me.Font("Arial", 46, "white");
			me.input.registerPointerEvent('pointerdown', this, this.newGame.bind(this), true);
		},

	draw: function(renderer) {
			this.font.draw(renderer.getContext(), "Awsomenauts", 450, 130);
			this.font.draw(renderer.getContext(), "Start A New Game", this.pos.x, this.pos.y);
	},

	update: function(dt) {
		return true;
	},

	newGame: function() {
		me.input.releasePointerEvent('pointerdown', this);
		me.save.remove('exp');
		me.save.remove('exp1');
		me.save.remove('exp3');
		me.save.remove('exp4');
		me.state.change(me.state.PLAY);
	}

	})));

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
<|endoftext|>


<commit_before>// Copyright 2020, University of Colorado Boulder

import joist from './joist.js';

/**
 * Given an array of all possible screens that a sim can have, select and order them according to the relevant query
 * parameters. This also will create a homeScreen if needed, and specify the initialScreen for startup.
 *
 * Parameters suffixed with "Provided" will be true if the that query parameter was actually in the URL, as opposed to
 * the value of the query parameter being the default.
 *
 * @author Chris Klusendorf (PhET Interactive Simulations)
 * @author Michael Kauzmann (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 *
 * @param {Screen[]} allSimScreens - all of the screens declared by the sim, duck-typed for tests
 * @param {boolean} homeScreenQueryParameter - from phet.chipper.queryParameters.homeScreen
 * @param {boolean} homeScreenQueryParameterProvided
 * @param {number} initialScreenIndex - from phet.chipper.queryParameters.initialScreen
 * @param {boolean} initialScreenQueryParameterProvided
 * @param {number[]} screensQueryParameter - from phet.chipper.queryParameters.screens
 * @param {boolean} screensQueryParameterProvided
 * @param {function( selectedSimScreens ):HomeScreen} createHomeScreen
 * @returns {{homeScreen:HomeScreen|null, initialScreen:Screen, selectedSimScreens:Screen[], screens:Screen[]}} - duck-typed for tests
 * @throws Error if incompatible data is provided
 */
const selectScreens = ( allSimScreens,
                        homeScreenQueryParameter,
                        homeScreenQueryParameterProvided,
                        initialScreenIndex,
                        initialScreenQueryParameterProvided,
                        screensQueryParameter,
                        screensQueryParameterProvided,
                        createHomeScreen ) => {

  if ( allSimScreens.length === 1 && homeScreenQueryParameterProvided && homeScreenQueryParameter ) {
    const errorMessage = 'cannot specify homeScreen=true for single-screen sims';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'homeScreen', homeScreenQueryParameter, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  // the ordered list of sim screens for this runtime
  let selectedSimScreens = [];

  // If a subset of screens was specified with the `screens` query parameter, add them to selectedSimScreens. Otherwise,
  // use all of the available sim screens as the default. Note that if the value of `screens` did not pass validation
  // in QueryStringMachine, it will be reverted to its default value of `null`, so it also needs to be checked for
  // truthiness before attempting to use it. For `screens` documentation, see the schema at
  // phet.chipper.queryParameters.screens in initialize-globals.js.
  if ( screensQueryParameterProvided && screensQueryParameter ) {
    assert && assert( screensQueryParameter.length > 0, 'Screens query parameter should have at least one value' );

    for ( let i = 0; i < screensQueryParameter.length; i++ ) {

      const userIndex = screensQueryParameter[ i ];
      const screenIndex = userIndex - 1; // screens query parameter uses 1-based indices, so convert to 0-based index

      if ( screenIndex >= 0 && screenIndex < allSimScreens.length ) {

        // index is valid, add screen
        selectedSimScreens.push( allSimScreens[ screenIndex ] );
      }
      else {

        // index is invalid, handle gracefully when running without ?ea and set selectedSimScreens to default values,
        // see https://github.com/phetsims/joist/issues/599
        const errorMessage = `invalid value in screens query parameter: ${userIndex}`;
        QueryStringMachine.addWarning( 'screens', screensQueryParameter, errorMessage );
        assert && assert( false, errorMessage );
        selectedSimScreens = allSimScreens;
        break;
      }
    }
  }
  else {
    selectedSimScreens = allSimScreens;
  }

  // Specifying ?homeScreen=false creates a simulation with no HomeScreen, and hence is incompatible with
  // ?initialScreen=0, which specifies to show the home screen. Note that the default value of initialScreen:0 is
  // ignored when there is no HomeScreen.
  if ( initialScreenQueryParameterProvided && initialScreenIndex === 0 && homeScreenQueryParameter === false ) {
    const errorMessage = 'cannot specify initialScreen=0 when home screen is disabled with homeScreen=false';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'initialScreen', initialScreenIndex, errorMessage );
    QueryStringMachine.addWarning( 'homeScreen', homeScreenQueryParameter, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  // For a single screen simulation (whether the simulation only declares one screen, or whether the user has specified
  // a single screen via ?screens), there is no HomeScreen, and hence ?initialScreen=0 which requests to show the
  // HomeScreen on startup should fail.
  if ( initialScreenQueryParameterProvided && initialScreenIndex === 0 && selectedSimScreens.length === 1 ) {
    const errorMessage = 'cannot specify initialScreen=0 for single-screen sims or when only one screen is loaded with screens=n';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'initialScreen', initialScreenIndex, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  const screens = selectedSimScreens.slice();

  let homeScreen = null;

  // If a sim has multiple screens and the query parameter homeScreen=false is not provided, add a HomeScreen
  if ( selectedSimScreens.length > 1 && homeScreenQueryParameter ) {
    homeScreen = createHomeScreen( selectedSimScreens );
    screens.unshift( homeScreen );
  }

  // The first screen for the sim, can be the HomeScreen if applicable
  let initialScreen;
  if ( homeScreen && initialScreenIndex === 0 ) {

    // If the home screen is supplied, then it is at index 0, so use the query parameter value directly (because the
    // query parameter is 1-based). If `?initialScreen` is 0 then there is no offset to apply.
    initialScreen = homeScreen;
  }
  else if ( initialScreenIndex === 0 ) {

    // There is no home screen and the initialScreen query parameter was not supplied, so we select the first sim screen.
    initialScreen = selectedSimScreens[ 0 ];
  }
  else {

    // If the home screen is not supplied, then the first sim screen is at index 0, so subtract 1 from the query parameter.
    initialScreen = allSimScreens[ initialScreenIndex - 1 ];
  }

  if ( screens.indexOf( initialScreen ) === -1 ) {
    throw new Error( 'screen not found: ' + initialScreenIndex );
  }

  return {
    homeScreen: homeScreen,
    initialScreen: initialScreen,
    selectedSimScreens: selectedSimScreens,
    screens: screens
  };
};

joist.register( 'selectScreens', selectScreens );
export default selectScreens;<commit_msg>Flags with values are handle gracefully and the flag type has a default value of true, add tests, see https://github.com/phetsims/query-string-machine/issues/44<commit_after>// Copyright 2020, University of Colorado Boulder

import joist from './joist.js';

/**
 * Given an array of all possible screens that a sim can have, select and order them according to the relevant query
 * parameters. This also will create a homeScreen if needed, and specify the initialScreen for startup.
 *
 * Parameters suffixed with "Provided" will be true if the that query parameter was actually in the URL, as opposed to
 * the value of the query parameter being the default.
 *
 * @author Chris Klusendorf (PhET Interactive Simulations)
 * @author Michael Kauzmann (PhET Interactive Simulations)
 * @author Sam Reid (PhET Interactive Simulations)
 *
 * @param {Screen[]} allSimScreens - all of the screens declared by the sim, duck-typed for tests
 * @param {boolean} homeScreenQueryParameter - from phet.chipper.queryParameters.homeScreen
 * @param {boolean} homeScreenQueryParameterProvided
 * @param {number} initialScreenIndex - from phet.chipper.queryParameters.initialScreen
 * @param {boolean} initialScreenQueryParameterProvided
 * @param {number[]} screensQueryParameter - from phet.chipper.queryParameters.screens
 * @param {boolean} screensQueryParameterProvided
 * @param {function( selectedSimScreens ):HomeScreen} createHomeScreen
 * @returns {{homeScreen:HomeScreen|null, initialScreen:Screen, selectedSimScreens:Screen[], screens:Screen[]}} - duck-typed for tests
 * @throws Error if incompatible data is provided
 */
const selectScreens = ( allSimScreens,
                        homeScreenQueryParameter,
                        homeScreenQueryParameterProvided,
                        initialScreenIndex,
                        initialScreenQueryParameterProvided,
                        screensQueryParameter,
                        screensQueryParameterProvided,
                        createHomeScreen ) => {

  if ( allSimScreens.length === 1 && homeScreenQueryParameterProvided && homeScreenQueryParameter ) {
    const errorMessage = 'cannot specify homeScreen=true for single-screen sims';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'homeScreen', homeScreenQueryParameter, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  // the ordered list of sim screens for this runtime
  let selectedSimScreens = [];

  // If a subset of screens was specified with the `screens` query parameter, add them to selectedSimScreens. Otherwise,
  // use all of the available sim screens as the default. Note that if the value of `screens` did not pass validation
  // in QueryStringMachine, it will be reverted to its default value of `null`, so it also needs to be checked for
  // truthiness before attempting to use it. For `screens` documentation, see the schema at
  // phet.chipper.queryParameters.screens in initialize-globals.js.
  if ( screensQueryParameterProvided && screensQueryParameter ) {
  assert && assert( screensQueryParameter.length > 0, 'Screens query parameter should have at least one value' );

    for ( let i = 0; i < screensQueryParameter.length; i++ ) {

      const userIndex = screensQueryParameter[ i ];
      const screenIndex = userIndex - 1; // screens query parameter uses 1-based indices, so convert to 0-based index

      if ( screenIndex >= 0 && screenIndex < allSimScreens.length ) {

        // index is valid, add screen
        selectedSimScreens.push( allSimScreens[ screenIndex ] );
      }
      else {

        // index is invalid, handle gracefully when running without ?ea and set selectedSimScreens to default values,
        // see https://github.com/phetsims/joist/issues/599
        const errorMessage = `invalid value in screens query parameter: ${userIndex}`;
        QueryStringMachine.addWarning( 'screens', screensQueryParameter, errorMessage );
        assert && assert( false, errorMessage );
        selectedSimScreens = allSimScreens;
        break;
      }
    }
  }
  else {
    selectedSimScreens = allSimScreens;
  }

  // Specifying ?homeScreen=false creates a simulation with no HomeScreen, and hence is incompatible with
  // ?initialScreen=0, which specifies to show the home screen. Note that the default value of initialScreen:0 is
  // ignored when there is no HomeScreen.
  if ( initialScreenQueryParameterProvided && initialScreenIndex === 0 && homeScreenQueryParameter === false ) {
    const errorMessage = 'cannot specify initialScreen=0 when home screen is disabled with homeScreen=false';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'initialScreen', initialScreenIndex, errorMessage );
    QueryStringMachine.addWarning( 'homeScreen', homeScreenQueryParameter, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  // For a single screen simulation (whether the simulation only declares one screen, or whether the user has specified
  // a single screen via ?screens), there is no HomeScreen, and hence ?initialScreen=0 which requests to show the
  // HomeScreen on startup should fail.
  if ( initialScreenQueryParameterProvided && initialScreenIndex === 0 && selectedSimScreens.length === 1 ) {
    const errorMessage = 'cannot specify initialScreen=0 for single-screen sims or when only one screen is loaded with screens=n';

    // handle gracefully when running without ?ea
    QueryStringMachine.addWarning( 'initialScreen', initialScreenIndex, errorMessage );

    // to support expected failures in selectScreensTests.js unit tests
    assert && assert( false, errorMessage );
  }

  const screens = selectedSimScreens.slice();

  let homeScreen = null;

  // If a sim has multiple screens and the query parameter homeScreen=false is not provided, add a HomeScreen
  if ( selectedSimScreens.length > 1 && homeScreenQueryParameter ) {
    homeScreen = createHomeScreen( selectedSimScreens );
    screens.unshift( homeScreen );
  }

  // The first screen for the sim, can be the HomeScreen if applicable
  let initialScreen;
  if ( homeScreen && initialScreenIndex === 0 ) {

    // If the home screen is supplied, then it is at index 0, so use the query parameter value directly (because the
    // query parameter is 1-based). If `?initialScreen` is 0 then there is no offset to apply.
    initialScreen = homeScreen;
  }
  else if ( initialScreenIndex === 0 ) {

    // There is no home screen and the initialScreen query parameter was not supplied, so we select the first sim screen.
    initialScreen = selectedSimScreens[ 0 ];
  }
  else {

    // If the home screen is not supplied, then the first sim screen is at index 0, so subtract 1 from the query parameter.
    initialScreen = allSimScreens[ initialScreenIndex - 1 ];
  }

  if ( screens.indexOf( initialScreen ) === -1 ) {
    throw new Error( 'screen not found: ' + initialScreenIndex );
  }

  return {
    homeScreen: homeScreen,
    initialScreen: initialScreen,
    selectedSimScreens: selectedSimScreens,
    screens: screens
  };
};

joist.register( 'selectScreens', selectScreens );
export default selectScreens;<|endoftext|>


<commit_before>var Sheets2sqlite = function(db, workbookId, tablesToProcess) {
    this.db = db;
    this.tablesToProcess = tablesToProcess;
    this.tables = [];
    this.control = {
        reqs: 0,
        reqOk: false,
        resps: 0,

        ok: function() {
            return (this.reqOk && (this.reqs == this.resps));
        },

        reset: function() {
            this.reqs = 0;
            this.resps = 0;
            this.reqOk = false;
        }
    };

    this.url = '//spreadsheets.google.com/feeds/worksheets/' + workbookId + '/public/values?alt=json';
};

Sheets2sqlite.prototype.start = function(done) {
    this.done = done;
    var that = this;

    $.ajax({
        url: this.url
    }).done(function(workbookData) {
        for(var i=0; i<workbookData.feed.entry.length; i++) {
            var entry = workbookData.feed.entry[i];
            var item = { name : entry.title.$t, link : entry.link[1].href.replace('https:', '') + '?alt=json' };

            that.control.reqs++;
            (function(name, link) {
                $.ajax({
                    url: link
                }).done(function(worksheetData) {
                    that.processWorksheetData(name, worksheetData);
                });
            }) (item.name, item.link);
        }
        that.control.reqOk = true;
    });
};

Sheets2sqlite.prototype.processWorksheetData = function(tableName, worksheetData) {
    this.control.resps++;
    if($.inArray(tableName, this.tablesToProcess) >= 0) {
        var table = this.createTable(tableName, worksheetData);
        this.insertData(table, worksheetData);
        this.tables.push(table);
    }

    if(this.control.ok()) {
        this.loadData(this.tables);
        this.done();
        this.control.reset();
    }
};

Sheets2sqlite.prototype.createTable = function(tableName, worksheetData) {
    var columns = [];
    var table = {
        name: tableName,
        fkCount: false,
        validColumns: [],
        regularIndexes: [],
        uniqueIndexes: [],
        createSQL: function() {
            var sSQL = 'CREATE TABLE ' + this.name + ' (';
            for(var i=0; i<this.columns.length; i++) {
                var column = this.columns[i];
                sSQL += column.name + ' ' + column.type;
                if(column.name == 'id') sSQL += ' primary key';
                if(i+1 != this.columns.length || this.fkCount > 0) {
                    sSQL += ', ';
                }
            }

            var tempFkCount = 0;
            if(this.fkCount > 0) {
                for(var i=0; i<this.columns.length; i++) {
                    var column = this.columns[i];
                    if(column.fk !== '') {
                        tempFkCount++;
                        sSQL += 'FOREIGN KEY(' + column.name + ') REFERENCES ' + column.fk;
                        if(tempFkCount != this.fkCount) {
                            sSQL += ', ';
                        } else {
                            break;
                        }
                    }
                }
            }

            sSQL += ');';

            for(var i=0; i<this.regularIndexes.length; i++) {
                var index = this.regularIndexes[i];
                sSQL += this.indexSQL(index, false);
            }

            for(var i=0; i<this.uniqueIndexes.length; i++) {
                var index = this.uniqueIndexes[i];
                sSQL += this.indexSQL(index, true);
            }

            return sSQL;
        },
        indexSQL: function(index, unique) {
            var temp = 'CREATE ' + (unique ? 'UNIQUE ' : '') + 'INDEX IF NOT EXISTS ';
            temp += index.name;
            temp += ' ON ';
            temp += this.name;

            var indexNames = [];
            for(var i=0; i<index.columns.length; i++) {
                indexNames.push(index.columns[i].name);
            }

            temp += ' (' + indexNames.join(', ') + ');';

            return temp;
        },
        insertSQL: function() {
            var sSQL = '';
            for(var j=0; j<this.rows.length; j++) {
                var row = this.rows[j];
                var sSQLData = '';

                sSQL += 'INSERT INTO ' + this.name + '(';
                for(var i=0; i<this.columns.length; i++) {
                    var col = this.columns[i];
                    sSQL += col.name;

                    var value = escape(row.cells[i]);
                    if(value === '') {
                        sSQLData += 'NULL';
                    } else if(col.type.toLowerCase() == 'text') {
                        sSQLData += '\'' + value + '\'';
                    } else {
                        sSQLData += value;
                    }

                    if(i+1 != this.columns.length) {
                        sSQL += ', ';
                        sSQLData += ', ';
                    }
                }
                sSQL += ') VALUES (' + sSQLData + ');';
            }

            return sSQL;
        },
        getRegularIndex: function(indexName) {
            return this.getIndex(this.regularIndexes, indexName);
        },
        getUniqueIndex: function(indexName) {
            return this.getIndex(this.uniqueIndexes, indexName);
        },
        getIndex: function(indexes, indexName) {
            for(var i=0; i<indexes; i++) {
                var index = indexes[i];
                if(index.name == indexName) {
                    return index;
                }
            }
            return null;
        }
    };

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];

        if(item.gs$cell.row == '1') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var value = item.gs$cell.$t;
            var name = value.substring(0, value.indexOf('(')).trim();
            var type = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim();

            var column = {
                pos: pos,
                name: name,
                type: type,
                fk: ''
            };

            columns.push(column);
            table.validColumns.push(pos);
        } else if(item.gs$cell.row == '2') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var column = columns[table.validColumns.indexOf(pos)];
            var value = item.gs$cell.$t;

            if(value !== '') {
                var indexes = value.split(',');
                for(var j=0; j<indexes.length; j++) {
                    var index = indexes[j].trim();
                    if(index.toLowerCase().indexOf('fk_') >= 0) {
                        table.fkCount++;
                        //column.fk = index.substring(3, index.length);
                        column.fk = index.substring(index.indexOf('(') + 1, index.indexOf(')')).replace('.', '(') + ')';
                    } else if(index.toLowerCase().indexOf('in_') >= 0) {
                        var regularIndex = table.getRegularIndex(index.toLowerCase());

                        if(regularIndex === null) {
                            regularIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.regularIndexes.push(regularIndex);
                        }

                        regularIndex.columns.push(column);
                    } else if(index.toLowerCase().indexOf('un_') >= 0) {
                        var uniqueIndex = table.getUniqueIndex(index.toLowerCase());

                        if(uniqueIndex === null) {
                            uniqueIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.uniqueIndexes.push(uniqueIndex);
                        }

                        uniqueIndex.columns.push(column);
                    }
                }
            }
        } else {
            break;
        }
    }

    table.columns = columns;

    return table;
};

Sheets2sqlite.prototype.insertData = function(table, worksheetData) {
    var rows = [];

    var linhaInicial = 3;

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];
        var col = parseInt(item.gs$cell.col, 10) - 1;
        var row = parseInt(item.gs$cell.row, 10) - linhaInicial;

        if(row < 0) {
            continue;
        }

        if(col === 0) {
            rows.push({
                row: row,
                cells: []
            });
        }

        if(table.validColumns.indexOf(col) >= 0) {
            var line = rows[row];
            line.cells.push(item.gs$cell.$t);
        }
    }

    table.rows = rows;
};

Sheets2sqlite.prototype.loadData = function(tables) {
    for(var i=0; i<tables.length; i++) {
        var table = tables[i];

        console.log('createSQL:', table.createSQL());
        console.log('insertSQL:', table.insertSQL());

        this.db.exec(table.createSQL());
        var inserts = table.insertSQL().split(';');
        for(var i=0; i<inserts.length; i++) {
            var insert = inserts[i].trim();
            if(insert !== '') {
                this.db.exec(insert);
            }
        }
    }
};

var escape = function(text) {
    if(text === '' || typeof text == 'undefined') {
        return '';
    }

    var temp = text.replace(/'/g, '\'\'');
    temp = temp.replace('"', '""');
    return temp;
};

var tableCreate = function () {
    function valconcat(vals, tagName) {
        if (vals.length === 0) return '';
        var open = '<'+tagName+'>', close='</'+tagName+'>';
        return open + vals.join(close + open) + close;
    }

    return function (columns, values) {
        var tbl  = document.createElement('table');
        var html = '
' + valconcat(columns, 'th') + '
';
        var rows = values.map(function(v){ return valconcat(v, 'td'); });
        html += '
' + valconcat(rows, 'tr') + '
';
        tbl.innerHTML = html;
        return tbl;
    };
};<commit_msg>removing log<commit_after>var Sheets2sqlite = function(db, workbookId, tablesToProcess) {
    this.db = db;
    this.tablesToProcess = tablesToProcess;
    this.tables = [];
    this.control = {
        reqs: 0,
        reqOk: false,
        resps: 0,

        ok: function() {
            return (this.reqOk && (this.reqs == this.resps));
        },

        reset: function() {
            this.reqs = 0;
            this.resps = 0;
            this.reqOk = false;
        }
    };

    this.url = '//spreadsheets.google.com/feeds/worksheets/' + workbookId + '/public/values?alt=json';
};

Sheets2sqlite.prototype.start = function(done) {
    this.done = done;
    var that = this;

    $.ajax({
        url: this.url
    }).done(function(workbookData) {
        for(var i=0; i<workbookData.feed.entry.length; i++) {
            var entry = workbookData.feed.entry[i];
            var item = { name : entry.title.$t, link : entry.link[1].href.replace('https:', '') + '?alt=json' };

            that.control.reqs++;
            (function(name, link) {
                $.ajax({
                    url: link
                }).done(function(worksheetData) {
                    that.processWorksheetData(name, worksheetData);
                });
            }) (item.name, item.link);
        }
        that.control.reqOk = true;
    });
};

Sheets2sqlite.prototype.processWorksheetData = function(tableName, worksheetData) {
    this.control.resps++;
    if($.inArray(tableName, this.tablesToProcess) >= 0) {
        var table = this.createTable(tableName, worksheetData);
        this.insertData(table, worksheetData);
        this.tables.push(table);
    }

    if(this.control.ok()) {
        this.loadData(this.tables);
        this.done();
        this.control.reset();
    }
};

Sheets2sqlite.prototype.createTable = function(tableName, worksheetData) {
    var columns = [];
    var table = {
        name: tableName,
        fkCount: false,
        validColumns: [],
        regularIndexes: [],
        uniqueIndexes: [],
        createSQL: function() {
            var sSQL = 'CREATE TABLE ' + this.name + ' (';
            for(var i=0; i<this.columns.length; i++) {
                var column = this.columns[i];
                sSQL += column.name + ' ' + column.type;
                if(column.name == 'id') sSQL += ' primary key';
                if(i+1 != this.columns.length || this.fkCount > 0) {
                    sSQL += ', ';
                }
            }

            var tempFkCount = 0;
            if(this.fkCount > 0) {
                for(var i=0; i<this.columns.length; i++) {
                    var column = this.columns[i];
                    if(column.fk !== '') {
                        tempFkCount++;
                        sSQL += 'FOREIGN KEY(' + column.name + ') REFERENCES ' + column.fk;
                        if(tempFkCount != this.fkCount) {
                            sSQL += ', ';
                        } else {
                            break;
                        }
                    }
                }
            }

            sSQL += ');';

            for(var i=0; i<this.regularIndexes.length; i++) {
                var index = this.regularIndexes[i];
                sSQL += this.indexSQL(index, false);
            }

            for(var i=0; i<this.uniqueIndexes.length; i++) {
                var index = this.uniqueIndexes[i];
                sSQL += this.indexSQL(index, true);
            }

            return sSQL;
        },
        indexSQL: function(index, unique) {
            var temp = 'CREATE ' + (unique ? 'UNIQUE ' : '') + 'INDEX IF NOT EXISTS ';
            temp += index.name;
            temp += ' ON ';
            temp += this.name;

            var indexNames = [];
            for(var i=0; i<index.columns.length; i++) {
                indexNames.push(index.columns[i].name);
            }

            temp += ' (' + indexNames.join(', ') + ');';

            return temp;
        },
        insertSQL: function() {
            var sSQL = '';
            for(var j=0; j<this.rows.length; j++) {
                var row = this.rows[j];
                var sSQLData = '';

                sSQL += 'INSERT INTO ' + this.name + '(';
                for(var i=0; i<this.columns.length; i++) {
                    var col = this.columns[i];
                    sSQL += col.name;

                    var value = escape(row.cells[i]);
                    if(value === '') {
                        sSQLData += 'NULL';
                    } else if(col.type.toLowerCase() == 'text') {
                        sSQLData += '\'' + value + '\'';
                    } else {
                        sSQLData += value;
                    }

                    if(i+1 != this.columns.length) {
                        sSQL += ', ';
                        sSQLData += ', ';
                    }
                }
                sSQL += ') VALUES (' + sSQLData + ');';
            }

            return sSQL;
        },
        getRegularIndex: function(indexName) {
            return this.getIndex(this.regularIndexes, indexName);
        },
        getUniqueIndex: function(indexName) {
            return this.getIndex(this.uniqueIndexes, indexName);
        },
        getIndex: function(indexes, indexName) {
            for(var i=0; i<indexes; i++) {
                var index = indexes[i];
                if(index.name == indexName) {
                    return index;
                }
            }
            return null;
        }
    };

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];

        if(item.gs$cell.row == '1') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var value = item.gs$cell.$t;
            var name = value.substring(0, value.indexOf('(')).trim();
            var type = value.substring(value.indexOf('(') + 1, value.indexOf(')')).trim();

            var column = {
                pos: pos,
                name: name,
                type: type,
                fk: ''
            };

            columns.push(column);
            table.validColumns.push(pos);
        } else if(item.gs$cell.row == '2') {
            var pos = parseInt(item.gs$cell.col, 10) - 1;
            var column = columns[table.validColumns.indexOf(pos)];
            var value = item.gs$cell.$t;

            if(value !== '') {
                var indexes = value.split(',');
                for(var j=0; j<indexes.length; j++) {
                    var index = indexes[j].trim();
                    if(index.toLowerCase().indexOf('fk_') >= 0) {
                        table.fkCount++;
                        //column.fk = index.substring(3, index.length);
                        column.fk = index.substring(index.indexOf('(') + 1, index.indexOf(')')).replace('.', '(') + ')';
                    } else if(index.toLowerCase().indexOf('in_') >= 0) {
                        var regularIndex = table.getRegularIndex(index.toLowerCase());

                        if(regularIndex === null) {
                            regularIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.regularIndexes.push(regularIndex);
                        }

                        regularIndex.columns.push(column);
                    } else if(index.toLowerCase().indexOf('un_') >= 0) {
                        var uniqueIndex = table.getUniqueIndex(index.toLowerCase());

                        if(uniqueIndex === null) {
                            uniqueIndex = {
                                name: index.toLowerCase(),
                                columns: []
                            };

                            table.uniqueIndexes.push(uniqueIndex);
                        }

                        uniqueIndex.columns.push(column);
                    }
                }
            }
        } else {
            break;
        }
    }

    table.columns = columns;

    return table;
};

Sheets2sqlite.prototype.insertData = function(table, worksheetData) {
    var rows = [];

    var linhaInicial = 3;

    for(var i=0; i<worksheetData.feed.entry.length; i++) {
        var item = worksheetData.feed.entry[i];
        var col = parseInt(item.gs$cell.col, 10) - 1;
        var row = parseInt(item.gs$cell.row, 10) - linhaInicial;

        if(row < 0) {
            continue;
        }

        if(col === 0) {
            rows.push({
                row: row,
                cells: []
            });
        }

        if(table.validColumns.indexOf(col) >= 0) {
            var line = rows[row];
            line.cells.push(item.gs$cell.$t);
        }
    }

    table.rows = rows;
};

Sheets2sqlite.prototype.loadData = function(tables) {
    for(var i=0; i<tables.length; i++) {
        var table = tables[i];

        console.log('createSQL:', table.createSQL());
        //console.log('insertSQL:', table.insertSQL());

        this.db.exec(table.createSQL());
        var inserts = table.insertSQL().split(';');
        for(var i=0; i<inserts.length; i++) {
            var insert = inserts[i].trim();
            if(insert !== '') {
                this.db.exec(insert);
            }
        }
    }
};

var escape = function(text) {
    if(text === '' || typeof text == 'undefined') {
        return '';
    }

    var temp = text.replace(/'/g, '\'\'');
    temp = temp.replace('"', '""');
    return temp;
};

var tableCreate = function () {
    function valconcat(vals, tagName) {
        if (vals.length === 0) return '';
        var open = '<'+tagName+'>', close='</'+tagName+'>';
        return open + vals.join(close + open) + close;
    }

    return function (columns, values) {
        var tbl  = document.createElement('table');
        var html = '
' + valconcat(columns, 'th') + '
';
        var rows = values.map(function(v){ return valconcat(v, 'td'); });
        html += '
' + valconcat(rows, 'tr') + '
';
        tbl.innerHTML = html;
        return tbl;
    };
};<|endoftext|>


<commit_before>/// <reference path="../lib/jquery-2.1.1.min.js" />
/// <reference path="../lib/qunit-git.js" />
/// <reference path="../project/zen-query.js" />

$Q = QUnit;

var classes = ['','.dropdown', '.menu.dropdown','.dropdown-menu'];
var ids = ['','#menu'];
var elements = ['', 'div', 'p'];
var attributes = [
    '', '[data-attribute]', '[for=""]', '[href="github.com/#"]', '[title="Something about ZenQuery\'s Awesomeness"]',
    '[filter][title="Something about ZenQuery\'s Awesomeness"]', '[filter title="Something about ZenQuery\'s Awesomeness"]'
];
var attributesObjects = [
    {}, { 'data-attribute': '' }, { 'for': '' }, { href: 'github.com/#' }, { title: "Something about ZenQuery\'s Awesomeness" },
    { filter: '', title: "Something about ZenQuery\'s Awesomeness" }, { filter: '', title: "Something about ZenQuery\'s Awesomeness" }
];

var selectors = [];
for (var i in elements)
    for (var j in ids)
        for (var k in classes)
            for (var l in attributes) {
                var classArray = $Z.trim(classes[k].replace(/\./g, ' ')).split(' ');
                if (classArray.length === 1 && classArray[0] === '')
                    classArray = [];
                selectors.push({
                    string: elements[i] + ids[j] + classes[k] + attributes[l],
                    name: elements[i] == '' ? 'div' : elements[i],
                    id: ids[j].replace('#', ''),
                    classes: classArray,
                    attributes: attributesObjects[l],
                    element: {
                        name: elements[i] == '' ? 'div' : elements[i],
                        id: ids[j].replace('#', ''),
                        classes: classArray,
                        attributes: attributesObjects[l],
                        children: [],
                    }
                }); // Correct Order
                selectors.push({
                    string: elements[i] + attributes[l] + classes[k] + ids[j],
                    name: elements[i] == '' ? 'div' : elements[i],
                    id: ids[j].replace('#', ''),
                    classes: classArray,
                    attributes: attributesObjects[l],
                    element: {
                        name: elements[i] == '' ? 'div' : elements[i],
                        id: ids[j].replace('#', ''),
                        classes: classArray,
                        attributes: attributesObjects[l],
                        children: [],
                    }
                }); // Random Order
            }<commit_msg>Modified helpers to accomodate html()<commit_after>/// <reference path="../lib/jquery-2.1.1.min.js" />
/// <reference path="../lib/qunit-git.js" />
/// <reference path="../project/zen-query.js" />

$Q = QUnit;

var classes = ['','.dropdown', '.menu.dropdown','.dropdown-menu'];
var ids = ['','#menu'];
var elements = ['', 'div', 'p'];
var attributes = [
    '', '[data-attribute]', '[for=""]', '[href="github.com/#"]', '[title="Something about ZenQuery\'s Awesomeness"]',
    '[filter][title="Something about ZenQuery\'s Awesomeness"]', '[filter title="Something about ZenQuery\'s Awesomeness" class="haha" id="hehe"]'
];
var attributesObjects = [
    {}, { 'data-attribute': '' }, { 'for': '' }, { href: 'github.com/#' }, { title: "Something about ZenQuery\'s Awesomeness" },
    { filter: '', title: "Something about ZenQuery\'s Awesomeness" }, { filter: '', title: "Something about ZenQuery\'s Awesomeness", 'class':'haha', id: 'hehe' }
];

var selectors = [];
for (var i in elements)
    for (var j in ids)
        for (var k in classes)
            for (var l in attributes) {
                var classArray = $Z.trim(classes[k].replace(/\./g, ' ')).split(' '),
                    attributesObject = ZenQuery.extend(true, {}, attributesObjects[l]),
                    id = ids[j].replace('#', '');
                if (classArray.length === 1 && classArray[0] === '') {
                    classArray = [];
                } else {
                    if (!attributesObject['class']) {
                        attributesObject['class'] = classArray.join(' ');
                    } else {
                        attributesObject['class'] += ' ' + classArray.join(' ');
                    }
                }
                if (id) {
                    ZenQuery.extend(true, attributesObject, { id: id });
                }
                var element = {
                    parent: null,
                    name: elements[i] == '' ? 'div' : elements[i],
                    attributes: attributesObject,
                    children: [],
                },
                    html = '',
                    sortedkeys = [];
                html += '<' + element.name;
                for (var key in element.attributes)
                    sortedkeys.push(key);
                sortedkeys.sort();
                for (var m in sortedkeys)
                    html += ' ' + sortedkeys[m] + '="' + element.attributes[sortedkeys[m]] + '"';
                html += '></' + element.name + '>';
                selectors.push({
                    string: elements[i] + ids[j] + classes[k] + attributes[l],
                    name: elements[i] == '' ? 'div' : elements[i],
                    id: id,
                    classes: classArray,
                    attributes: attributesObjects[l],
                    element: element,
                    html: html,
                }); // Correct Order
                selectors.push({
                    string: elements[i] + attributes[l] + classes[k] + ids[j],
                    name: elements[i] == '' ? 'div' : elements[i],
                    id: id,
                    classes: classArray,
                    attributes: attributesObjects[l],
                    element: element,
                    html: html,
                }); // Random Order
            }<|endoftext|>


<commit_before>"use strict";

/**
 * TODO: Throw out layers, have a camera?
 */
var GameView = function(model) {
	this.model = model;
	Panel.call(this, 0, 0, window.innerWidth, window.innerHeight);
  this.backgroundZ = 10000;
  this.explosionFrames = getExplosionFrames();
  this.backgroundImage = getBackgroundImage();

  this.camera = {position: Vector.fromComponents(0, 0), z: window.innerWidth / 2}
  this.FOV = 90;

	this.scalingFactor = 1.1;

	this.music = new Audio("assets/one_sly_move.mp3");
	//this.music.play();

	this.name = "I am a GameView." // Placeholder name.
	this.mouseState = null;
	this.mousedownTime = null;
	this.mousedownLocation = null;
	this.mouseLocation = null;
	this.lastMouseLocation = null;
	this.GROW_MOVE_STOP_DIST = 10;
	this.newBodyTime = null;
	this.rand = null;
	this.ghostObject = null;

  this.touchCache = [];

	/**
	 * This function will draw everything!
	 */
	this.drawPanel = function(ctx, windowX, windowY) {

    // Start by drawing the background (and clearing the screen!);
		this.drawBackground(ctx);

    // Draw each object.
		myModel.getBodies().forEach(function(obj) {
      obj.accept(DrawAlgo, [ctx, this]);
    }, this);

    // Draw each explosion
    myModel.explosions.forEach(function(obj) {
      var screenVector = this.modelToViewCoordinate(obj.positionVector);
      var explosionRadius = 50 / this.getScale();
      GameView.drawImageAt(ctx, this.explosionFrames[obj.getSkinID()], screenVector, explosionRadius);
    }, this);

    /*
    If the mouse has been down past the panning threshold, then the user is trying
    to create a new Body. Check for this, and draw the ghost body as needed.
    */
		var t = new Date();
		t -= this.mousedownTime;
		t /= 1000;
		if (t > 0.25) {
      if (this.mouseState == "MOVE" || this.mouseState == "DOWN") {
        if (this.mouseState == "MOVE") {
    			ctx.strokeStyle = "#FFFFFF";
    			ctx.beginPath();
    			ctx.moveTo(this.mousedownLocation.x, this.mousedownLocation.y);
    			ctx.lineTo(this.mouseLocation.x, this.mouseLocation.y);
    			ctx.stroke();
  		  } else if (this.mouseState == "DOWN") {
          this.newBodyTime = t;
  			}
        var modelVector = this.viewToModelCoordinate(this.mousedownLocation);
        var ghostObject = GameView.createBody(modelVector, Vector.ZERO, this.newBodyTime, this.rand);
        ghostObject.accept(DrawAlgo, [ctx, this]);
      }
		}

  }

  this.drawBackground = function(ctx) {

    ctx.globalAlpha = 1;

    var pictureSize = 20000 / this.getZScale(this.backgroundZ);
    var screenVector = this.zToViewCoordinate(this.backgroundZ, Vector.fromComponents(0, 0));

    for (var i = -10; i < 11; i++) {
      for (var j = -10; j < 11; j++) {
        GameView.drawImageAt(ctx, this.backgroundImage, screenVector.add(Vector.fromComponents(i, j).scMult(pictureSize)), pictureSize / 2);
      }
    }

    ctx.globalAlpha = 0.6;

    var pictureSize = 10000 / this.getZScale(this.backgroundZ / 2);
    var screenVector = this.zToViewCoordinate(this.backgroundZ / 2, Vector.fromComponents(pictureSize / 4, pictureSize / 10));

    for (var i = -10; i < 11; i++) {
      for (var j = -10; j < 11; j++) {
        GameView.drawImageAt(ctx, this.backgroundImage, screenVector.add(Vector.fromComponents(i, j).scMult(pictureSize)), pictureSize / 2);
      }
    }
    ctx.globalAlpha = 1;
	}

	/**
	 * Adjusts GameView center and scale s.t. screenVector will stay
	 * consistent with planeVector, but scale will change by
	 * scalingFactor.
	 */
	this.zoomAt = function(screenVector, zoom) {
    if (this.camera.z * zoom < 10)
      return;
    if (this.camera.z * zoom > 25000)
      return;
    var mouseCoordinate = this.viewToModelCoordinate(screenVector);
    var mouseOffset = mouseCoordinate.subtract(this.getCenter());
    var scaledOffset = mouseOffset.scMult(zoom);
    this.setCenter(mouseCoordinate.subtract(scaledOffset));
    this.setScale(this.getScale() * zoom);
	}

	this.keyToFunctionMap = {
		"&" : function(gameView) { gameView.scale /= 1.1; },
		"(" : function(gameView) { gameView.scale *= 1.1; },
		" " : function(gameView) { gameView.model.running = !(gameView.model.running); },
		"S" : function(gameView) { gameView.center.y -= gameView.scale * 100; },
		"W" : function(gameView) { gameView.center.y += gameView.scale * 100; },
		"A" : function(gameView) { gameView.center.x -= gameView.scale * 100; },
		"D" : function(gameView) { gameView.center.x += gameView.scale * 100; }
	}
}

GameView.prototype = Object.create(Panel.prototype);

GameView.prototype.draw = function(ctx, offsetX, offsetY) {
  Panel.prototype.draw.call(this, ctx, 0, 0);
}

GameView.prototype.pan = function(deltaVector) {
  this.setCenter(this.getCenter().subtract(deltaVector));
}

GameView.prototype.getScale = function() {
  return this.camera.z / (window.innerWidth / 2);
}

GameView.prototype.setScale = function(value) {
  this.camera.z = value * (window.innerWidth / 2);
}

GameView.prototype.getCenter = function() {
  return this.camera.position;
}

GameView.prototype.setCenter = function(value) {
  this.camera.position = value;
}

GameView.prototype.getBackgroundCenter = function() {
  return this.camera.position;
}

GameView.prototype.getBackgroundScale = function() {
  return (this.camera.z + this.backgroundZ) / (window.innerWidth / 2);
}

GameView.prototype.getZScale = function(z) {
  return (z + this.camera.z) / (window.innerWidth / 2);
}

GameView.prototype.mousedownHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  this.mouseState = "DOWN";
  this.mousedownTime = new Date();

  this.mousedownLocation = event;
  this.mouseLocation = event;

  this.rand = Math.random();
}

GameView.prototype.keydownHandler = function(keyEvent) {
  var keynum = window.event ? keyEvent.keyCode : keyEvent.which; // window.event = userIsIE
  var key = String.fromCharCode(keynum);
  this.keyToFunctionMap[key](this);
}

GameView.prototype.clickHandler = function(event) {
  // Used to be a link to the about page!
}

GameView.prototype.mouseupHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  if (this.mouseState == "DOWN") {
    this.newBodyTime = (new Date() - this.mousedownTime) / 1000;
    var vector = this.viewToModelCoordinate(event);
    var newBody = GameView.createBody(vector, Vector.ZERO, this.newBodyTime, this.rand);
    myModel.addBody(newBody);
  } else if (this.mouseState == "MOVE") {
    var posVector_1 = this.viewToModelCoordinate(this.mousedownLocation);
    var posVector_2 = this.viewToModelCoordinate(event);
    var deltaVector = posVector_2.subtract(posVector_1);
    var newBody = GameView.createBody(posVector_1, deltaVector, this.newBodyTime, this.rand);
    myModel.addBody(newBody);

  }
  this.mouseState = "UP";

}

GameView.prototype.mousemoveHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  var timeSinceMouseDown = (new Date() - this.mousedownTime) / 1000;

  if (this.mouseState == "DOWN" || this.mouseState == "PAN") {
    var mouseDelta = event.subtract(this.mousedownLocation);
    var dist = mouseDelta.norm();
    if (timeSinceMouseDown > 0.25 && this.mouseState != "PAN") {
      if (dist > this.GROW_MOVE_STOP_DIST) {
        this.mouseState = "MOVE";
        this.newBodyTime = (new Date() - this.mousedownTime) / 1000;
      }
    } else if (this.mouseState == "PAN" || (timeSinceMouseDown <= 0.25 && dist > this.GROW_MOVE_STOP_DIST)) {
      // var coordinateShift = this.viewToModelCoordinate(event).subtract(this.viewToModelCoordinate(this.mouseLocation))
      //
      var coordinateShift = event.subtract(this.mouseLocation).scMult(this.getScale());
      this.pan(coordinateShift);
      this.mouseState = "PAN";
    }
  }
  this.mouseLocation = event;
}

GameView.prototype.mousewheelHandler = function(event) {
  if (event.wheelDelta > 0) {
    this.zoomAt(Vector.fromComponents(event.clientX, event.clientY), 1 / this.scalingFactor);
  } else {
    this.zoomAt(Vector.fromComponents(event.clientX, event.clientY), this.scalingFactor);
  }
}

GameView.prototype.touchstartHandler = function(event) {
  if (this.touchCache.length == 0) {
    this.mousedownHandler(event);
  }
  this.touchCache.push(event);
  console.log(this.touchCache);
}

GameView.prototype.touchmoveHandler = function(event) {
  if (this.touchCache.length == 1) {
    var identifier = event.identifier;
    if (identifier == 0) {
      this.mousemoveHandler(event);
      this.touchCache[0] = event;
    }
  } else if (this.touchCache.length > 1) {
    var identifier = event.identifier;
    var oldVec0 = Vector.fromComponents(this.touchCache[0].clientX, this.touchCache[0].clientY);
    var oldVec1 = Vector.fromComponents(this.touchCache[1].clientX, this.touchCache[1].clientY);
    var oldDist = Vector.distance(oldVec0, oldVec1);
    if (identifier == 0) {
      var newVec0 = Vector.fromComponents(event.clientX, event.clientY);
      var newDist = Vector.distance(newVec0, oldVec1);
      this.zoomAt(oldVec1, oldDist / newDist);
      this.touchCache[0] = event;
    } else if (identifier == 1) {
      var newVec1 = Vector.fromComponents(event.clientX, event.clientY);
      var newDist = Vector.distance(oldVec0, newVec1);
      this.zoomAt(oldVec0, oldDist / newDist);
      this.touchCache[1] = event;
    }

  }
}

GameView.prototype.touchendHandler = function(event) {
  if (this.touchCache.length == 1) {
    this.mouseupHandler(event);
  }
  this.touchCache = this.touchCache.filter(function(touchEvent) {
    return touchEvent.identifier != event.identifier
  }, this);
  console.log(this.touchCache);
}

GameView.prototype.modelToViewCoordinate = function(modelVector) {
	/**
	 * ScreenVec = (PlaneVec - ViewCenter) / Scale + ScreenCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var viewVector = modelVector.subtract(this.getCenter()).scMult(1 / this.getScale()).add(viewCenter);
	return viewVector;
}

GameView.prototype.viewToModelCoordinate = function(viewVector) {
	/**
	 * PlaneVec = (ScreenVec - ScreenCenter) * Scale + ViewCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var modelVector = viewVector.subtract(viewCenter).scMult(this.getScale()).add(this.getCenter());
	return modelVector;
}

GameView.prototype.zToViewCoordinate = function(z, backgroundVector) {
	/**
	 * ScreenVec = (PlaneVec - ViewCenter) / Scale + ScreenCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var viewVector = backgroundVector.subtract(this.getBackgroundCenter()).scMult(1 / this.getZScale(z)).add(viewCenter);
	return viewVector;
}

GameView.timeToRadius = function(t) {
	if (t < 1) {
		return 2 * t + 2;
	} else if (t < 2) {
		return 10 * t;
	} else if (t < 2.5) {
		var myIteration = (t - 2) / (2.5 - 2) * 30;
		return easeOutBack(myIteration, 20, 105, 30);
	} else {
		return 50 * t;
	}
}

GameView.createBody = function(positionVector, velocityVector, t, rand) { // Remind Kevin to edit values
	velocityVector = velocityVector.scMult(2);
	var radius = GameView.timeToRadius(t);
	if (t > 2) {
		var newBody = new Star(positionVector, velocityVector, radius); // Remind Kevin to put stars.
	} else if (t < 1) {
		var newBody = new Moon(positionVector, velocityVector, radius, rand);
	} else {
		var newBody = new Planet(positionVector, velocityVector, radius, rand);
	}
	return newBody;
}

GameView.drawImageAt = function(ctx, image, viewPosition, viewRadius) {
  ctx.drawImage(
    image,
    viewPosition.x - viewRadius,
    viewPosition.y - viewRadius,
    2 * viewRadius,
    2 * viewRadius);
}
<commit_msg>Touch Zoom Attempt #5?<commit_after>"use strict";

/**
 * TODO: Throw out layers, have a camera?
 */
var GameView = function(model) {
	this.model = model;
	Panel.call(this, 0, 0, window.innerWidth, window.innerHeight);
  this.backgroundZ = 10000;
  this.explosionFrames = getExplosionFrames();
  this.backgroundImage = getBackgroundImage();

  this.camera = {position: Vector.fromComponents(0, 0), z: window.innerWidth / 2}
  this.FOV = 90;

	this.scalingFactor = 1.1;

	this.music = new Audio("assets/one_sly_move.mp3");
	//this.music.play();

	this.name = "I am a GameView." // Placeholder name.
	this.mouseState = null;
	this.mousedownTime = null;
	this.mousedownLocation = null;
	this.mouseLocation = null;
	this.lastMouseLocation = null;
	this.GROW_MOVE_STOP_DIST = 10;
	this.newBodyTime = null;
	this.rand = null;
	this.ghostObject = null;

  this.touchCache = [];

	/**
	 * This function will draw everything!
	 */
	this.drawPanel = function(ctx, windowX, windowY) {

    // Start by drawing the background (and clearing the screen!);
		this.drawBackground(ctx);

    // Draw each object.
		myModel.getBodies().forEach(function(obj) {
      obj.accept(DrawAlgo, [ctx, this]);
    }, this);

    // Draw each explosion
    myModel.explosions.forEach(function(obj) {
      var screenVector = this.modelToViewCoordinate(obj.positionVector);
      var explosionRadius = 50 / this.getScale();
      GameView.drawImageAt(ctx, this.explosionFrames[obj.getSkinID()], screenVector, explosionRadius);
    }, this);

    /*
    If the mouse has been down past the panning threshold, then the user is trying
    to create a new Body. Check for this, and draw the ghost body as needed.
    */
		var t = new Date();
		t -= this.mousedownTime;
		t /= 1000;
		if (t > 0.25) {
      if (this.mouseState == "MOVE" || this.mouseState == "DOWN") {
        if (this.mouseState == "MOVE") {
    			ctx.strokeStyle = "#FFFFFF";
    			ctx.beginPath();
    			ctx.moveTo(this.mousedownLocation.x, this.mousedownLocation.y);
    			ctx.lineTo(this.mouseLocation.x, this.mouseLocation.y);
    			ctx.stroke();
  		  } else if (this.mouseState == "DOWN") {
          this.newBodyTime = t;
  			}
        var modelVector = this.viewToModelCoordinate(this.mousedownLocation);
        var ghostObject = GameView.createBody(modelVector, Vector.ZERO, this.newBodyTime, this.rand);
        ghostObject.accept(DrawAlgo, [ctx, this]);
      }
		}

  }

  this.drawBackground = function(ctx) {

    ctx.globalAlpha = 1;

    var pictureSize = 20000 / this.getZScale(this.backgroundZ);
    var screenVector = this.zToViewCoordinate(this.backgroundZ, Vector.fromComponents(0, 0));

    for (var i = -10; i < 11; i++) {
      for (var j = -10; j < 11; j++) {
        GameView.drawImageAt(ctx, this.backgroundImage, screenVector.add(Vector.fromComponents(i, j).scMult(pictureSize)), pictureSize / 2);
      }
    }

    ctx.globalAlpha = 0.6;

    var pictureSize = 10000 / this.getZScale(this.backgroundZ / 2);
    var screenVector = this.zToViewCoordinate(this.backgroundZ / 2, Vector.fromComponents(pictureSize / 4, pictureSize / 10));

    for (var i = -10; i < 11; i++) {
      for (var j = -10; j < 11; j++) {
        GameView.drawImageAt(ctx, this.backgroundImage, screenVector.add(Vector.fromComponents(i, j).scMult(pictureSize)), pictureSize / 2);
      }
    }
    ctx.globalAlpha = 1;
	}

	/**
	 * Adjusts GameView center and scale s.t. screenVector will stay
	 * consistent with planeVector, but scale will change by
	 * scalingFactor.
	 */
	this.zoomAt = function(screenVector, zoom) {
    if (this.camera.z * zoom < 10)
      return;
    if (this.camera.z * zoom > 25000)
      return;
    var mouseCoordinate = this.viewToModelCoordinate(screenVector);
    var mouseOffset = mouseCoordinate.subtract(this.getCenter());
    var scaledOffset = mouseOffset.scMult(zoom);
    this.setCenter(mouseCoordinate.subtract(scaledOffset));
    this.setScale(this.getScale() * zoom);
	}

	this.keyToFunctionMap = {
		"&" : function(gameView) { gameView.scale /= 1.1; },
		"(" : function(gameView) { gameView.scale *= 1.1; },
		" " : function(gameView) { gameView.model.running = !(gameView.model.running); },
		"S" : function(gameView) { gameView.center.y -= gameView.scale * 100; },
		"W" : function(gameView) { gameView.center.y += gameView.scale * 100; },
		"A" : function(gameView) { gameView.center.x -= gameView.scale * 100; },
		"D" : function(gameView) { gameView.center.x += gameView.scale * 100; }
	}
}

GameView.prototype = Object.create(Panel.prototype);

GameView.prototype.draw = function(ctx, offsetX, offsetY) {
  Panel.prototype.draw.call(this, ctx, 0, 0);
}

GameView.prototype.pan = function(deltaVector) {
  this.setCenter(this.getCenter().subtract(deltaVector));
}

GameView.prototype.getScale = function() {
  return this.camera.z / (window.innerWidth / 2);
}

GameView.prototype.setScale = function(value) {
  this.camera.z = value * (window.innerWidth / 2);
}

GameView.prototype.getCenter = function() {
  return this.camera.position;
}

GameView.prototype.setCenter = function(value) {
  this.camera.position = value;
}

GameView.prototype.getBackgroundCenter = function() {
  return this.camera.position;
}

GameView.prototype.getBackgroundScale = function() {
  return (this.camera.z + this.backgroundZ) / (window.innerWidth / 2);
}

GameView.prototype.getZScale = function(z) {
  return (z + this.camera.z) / (window.innerWidth / 2);
}

GameView.prototype.mousedownHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  this.mouseState = "DOWN";
  this.mousedownTime = new Date();

  this.mousedownLocation = event;
  this.mouseLocation = event;

  this.rand = Math.random();
}

GameView.prototype.keydownHandler = function(keyEvent) {
  var keynum = window.event ? keyEvent.keyCode : keyEvent.which; // window.event = userIsIE
  var key = String.fromCharCode(keynum);
  this.keyToFunctionMap[key](this);
}

GameView.prototype.clickHandler = function(event) {
  // Used to be a link to the about page!
}

GameView.prototype.mouseupHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  if (this.mouseState == "DOWN") {
    this.newBodyTime = (new Date() - this.mousedownTime) / 1000;
    var vector = this.viewToModelCoordinate(event);
    var newBody = GameView.createBody(vector, Vector.ZERO, this.newBodyTime, this.rand);
    myModel.addBody(newBody);
  } else if (this.mouseState == "MOVE") {
    var posVector_1 = this.viewToModelCoordinate(this.mousedownLocation);
    var posVector_2 = this.viewToModelCoordinate(event);
    var deltaVector = posVector_2.subtract(posVector_1);
    var newBody = GameView.createBody(posVector_1, deltaVector, this.newBodyTime, this.rand);
    myModel.addBody(newBody);

  }
  this.mouseState = "UP";

}

GameView.prototype.mousemoveHandler = function(event) {
  event = new Vector({x : event.clientX, y : event.clientY});
  var timeSinceMouseDown = (new Date() - this.mousedownTime) / 1000;

  if (this.mouseState == "DOWN" || this.mouseState == "PAN") {
    var mouseDelta = event.subtract(this.mousedownLocation);
    var dist = mouseDelta.norm();
    if (timeSinceMouseDown > 0.25 && this.mouseState != "PAN") {
      if (dist > this.GROW_MOVE_STOP_DIST) {
        this.mouseState = "MOVE";
        this.newBodyTime = (new Date() - this.mousedownTime) / 1000;
      }
    } else if (this.mouseState == "PAN" || (timeSinceMouseDown <= 0.25 && dist > this.GROW_MOVE_STOP_DIST)) {
      // var coordinateShift = this.viewToModelCoordinate(event).subtract(this.viewToModelCoordinate(this.mouseLocation))
      //
      var coordinateShift = event.subtract(this.mouseLocation).scMult(this.getScale());
      this.pan(coordinateShift);
      this.mouseState = "PAN";
    }
  }
  this.mouseLocation = event;
}

GameView.prototype.mousewheelHandler = function(event) {
  if (event.wheelDelta > 0) {
    this.zoomAt(Vector.fromComponents(event.clientX, event.clientY), 1 / this.scalingFactor);
  } else {
    this.zoomAt(Vector.fromComponents(event.clientX, event.clientY), this.scalingFactor);
  }
}

GameView.prototype.touchstartHandler = function(event) {
  if (this.touchCache.length == 0) {
    this.mousedownHandler(event);
  }
  this.touchCache.push(event);
  console.log(this.touchCache);
}

GameView.prototype.touchmoveHandler = function(event) {
  if (this.touchCache.length == 1) {
    var identifier = event.identifier;
    if (identifier == 0) {
      this.mousemoveHandler(event);
      this.touchCache[0] = event;
    }
  } else if (this.touchCache.length > 1) {
    this.mouseState = "ZOOM";
    var identifier = event.identifier;
    var oldVec0 = Vector.fromComponents(this.touchCache[0].clientX, this.touchCache[0].clientY);
    var oldVec1 = Vector.fromComponents(this.touchCache[1].clientX, this.touchCache[1].clientY);
    var oldDist = Vector.distance(oldVec0, oldVec1);
    if (identifier == 0) {
      var newVec0 = Vector.fromComponents(event.clientX, event.clientY);
      var newDist = Vector.distance(newVec0, oldVec1);
      this.zoomAt(oldVec1, oldDist / newDist);
      this.touchCache[0] = event;
    } else if (identifier == 1) {
      var newVec1 = Vector.fromComponents(event.clientX, event.clientY);
      var newDist = Vector.distance(oldVec0, newVec1);
      this.zoomAt(oldVec0, oldDist / newDist);
      this.touchCache[1] = event;
    }

  }
}

GameView.prototype.touchendHandler = function(event) {
  if (this.touchCache.length == 1) {
    this.mouseupHandler(event);
  }
  this.touchCache = this.touchCache.filter(function(touchEvent) {
    return touchEvent.identifier != event.identifier
  }, this);
  if (this.touchCache.length == 0) {
    this.mouseState = "UP";
  }
  console.log(this.touchCache);
}

GameView.prototype.modelToViewCoordinate = function(modelVector) {
	/**
	 * ScreenVec = (PlaneVec - ViewCenter) / Scale + ScreenCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var viewVector = modelVector.subtract(this.getCenter()).scMult(1 / this.getScale()).add(viewCenter);
	return viewVector;
}

GameView.prototype.viewToModelCoordinate = function(viewVector) {
	/**
	 * PlaneVec = (ScreenVec - ScreenCenter) * Scale + ViewCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var modelVector = viewVector.subtract(viewCenter).scMult(this.getScale()).add(this.getCenter());
	return modelVector;
}

GameView.prototype.zToViewCoordinate = function(z, backgroundVector) {
	/**
	 * ScreenVec = (PlaneVec - ViewCenter) / Scale + ScreenCenter
	 */
	var viewCenter = Vector.fromComponents(window.innerWidth / 2, window.innerHeight / 2);
	var viewVector = backgroundVector.subtract(this.getBackgroundCenter()).scMult(1 / this.getZScale(z)).add(viewCenter);
	return viewVector;
}

GameView.timeToRadius = function(t) {
	if (t < 1) {
		return 2 * t + 2;
	} else if (t < 2) {
		return 10 * t;
	} else if (t < 2.5) {
		var myIteration = (t - 2) / (2.5 - 2) * 30;
		return easeOutBack(myIteration, 20, 105, 30);
	} else {
		return 50 * t;
	}
}

GameView.createBody = function(positionVector, velocityVector, t, rand) { // Remind Kevin to edit values
	velocityVector = velocityVector.scMult(2);
	var radius = GameView.timeToRadius(t);
	if (t > 2) {
		var newBody = new Star(positionVector, velocityVector, radius); // Remind Kevin to put stars.
	} else if (t < 1) {
		var newBody = new Moon(positionVector, velocityVector, radius, rand);
	} else {
		var newBody = new Planet(positionVector, velocityVector, radius, rand);
	}
	return newBody;
}

GameView.drawImageAt = function(ctx, image, viewPosition, viewRadius) {
  ctx.drawImage(
    image,
    viewPosition.x - viewRadius,
    viewPosition.y - viewRadius,
    2 * viewRadius,
    2 * viewRadius);
}
<|endoftext|>