<commit_before>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure and Initial Settings.

var version = '2.0 Beta';
var SCBversion = '3.021'; //Last SandCastle Builder version tested

//Declare and Initialize Variables
var AudioAlertsStatus = 3;
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume = 1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume = 1;
var BorderAlertStatus = 1;
var description = "Error";
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var Logicat = 0;
var LCAutoClickStatus = 0;
var LCSolution = 'blank';
var NinjaAutoClickStatus = 1;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

var start = -1;
var content = "empty";
var length = 0;
var RKLevel = '-1';
var RKLocation = 'null';
var lootBoxes = new Array();
	lootBoxes[0] = 'boosts';
	lootBoxes[1] = 'ninj';
	lootBoxes[2] = 'cyb';
	lootBoxes[3] = 'hpt';
	lootBoxes[4] = 'bean';
	lootBoxes[5] = 'chron';

//Ninja AutoClicker and Border Warnings
function Ninja() {
    if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0 && BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
				Molpy.Notify('Ninja Auto Click', 1);
				if (BorderAlertStatus == 1) {
					$("#beach").css("border","1px solid white");
				}
            }
            else if (BorderAlertStatus == 1) {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
		if (BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid yellow");
		}
        if (incoming_ONG == 0 && (AudioAlertsStatus == 3 || AudioAlertsStatus == 4)) {
			audio_Chime.play();
			incoming_ONG = 1;
        }
    }
    else if (BorderAlertStatus == 1) {
        $("#beach").css("border","1px solid white");
	}
}

function FindRK() {
	/*
	RV of 1 is Sand Tools
	RV of 2 is Castle Tools
	RV of 3 is Boosts Main Page
	RV of 4 is Boosts Menus, Hill People Tech, etc.
	RV of 5 is Badges Earned
	RV of 6 is Badges Available
	*/

	//Determines RK location
	if (Molpy.redactedVisible == 1 || Molpy.redactedVisible == 2 || Molpy.redactedVisible == 3) {
		//Do Nothing
	}
	else if (Molpy.redactedVisible == 4) {
		location = 'null'
		i = 0;
		while (location = 'null' || i < 6) {
			Molpy.Notify(lootBoxes[i], 1)
			if ($('#' + lootboxes[i]).length) {
				showhideToggle(lootBoxes[i]);
				if ($('#redacteditem').length) {
					location = lootBoxes[i];
				}
				else {
					showhideToggle(lootBoxes[i]);
				}
			}
			i++;
			Molpy.Notify(i, 1);
		}
	}
	else if (Molpy.redactedVisible == 5) {
		location = 'badges';
	}
	else if (Molpy.redactedVisible == 6) {
		location = 'badgesav';
	}
	return location;
}
function RedundaKitty() {
	//Refresh Timer Variable
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	//If RedundaKitty is available
	if (Molpy.redactedVisible > 0) {
		RKLocation = FindRK();

		if (RKLocation != 'null' && RKLocation != '4' && !Molpy.options.showhide[RKLocation]) {
			showhideToggle(RKLocation);
		}

		//Determines if it is a Logicat or RK
		//if (RKLocation  != '4') {
			content = $('#redacteditem').html();
			if (content.indexOf("statement") !== -1) {
				Logicat = 1;
				//Molpy.Notify("Logicat Found",0);
			}
			else {
				Logicat = 0;
				//Molpy.Notify("Redundakitty Found",0);
				start = content.indexOf("ClickRedacted");
				content = content.substring(start,start+17);
				content = content.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
				var length = content.length;
				RKLevel = content.substring(13,length);
				Molpy.Notify('RedundaKitty Level is: ' + RKLevel, 1);
			}

			//Highlights RK/LC Border to make it easier to find
			$('#redacteditem').css("border","2px solid red");
		//}

		//Clicks if RedundaKitty AutoClicker Enabled and Not a Logicat
		if (RKAutoClickStatus == 1 && Logicat == 0 ) {
			Molpy.ClickRedacted(RKLevel);
			if (RKLocation != 'null') {
				showhideToggle(RKLocation);
				RKLocation = 'null';
			}
		}
		else if (LCAutoClickStatus == 1 && Logicat == 1) {
			Logicat();
			if (RKLocation != 'null') {
				showhideToggle(RKLocation);
				RKLocation = 'null';
			}
		}
		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % RKAlertFrequency) == 0 && (AudioAlertsStatus == 1 || AudioAlertsStatus == 3)) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

function Logicat() {
	i = 65;
	do
		{LCSolution = String.fromCharCode(i);
		i++;}
	while (Molpy.redactedPuzzleTarget != Molpy.redactedSGen.StatementValue(LCSolution));
	Molpy.ClickRedactedPuzzle(LCSolution);

	/*while (Molpy.redactedPuzzleTarget != undefined) {
		LCSolution = String.fromCharCode(i);
		if (Molpy.redactedPuzzleTarget == Molpy.redactedSGen.StatementValue(LCSolution)) {
			Molpy.ClickRedactedPuzzle(LCSolution);
			Molpy.redactedPuzzleTarget = undefined;
		}
		else {i++;}
	}*/
}

function SwitchOption(option) {
	switch (option) {
		case 'RKAutoClick':
			RKAutoClickStatus++;
			if (RKAutoClickStatus > 1) {RKAutoClickStatus = 0;}
			status = RKAutoClickStatus;
			break;
		case 'LCAutoClick':
			LCAutoClickStatus++;
			if (LCAutoClickStatus > 1) {LCAutoClickStatus = 0;}
			status = LCAutoClickStatus;
			break;
		case 'NinjaAutoClick':
			NinjaAutoClickStatus++;
			if (NinjaAutoClickStatus > 1) {NinjaAutoClickStatus = 0;}
			status = NinjaAutoClickStatus;
			break;
		case 'BorderAlert':
			BorderAlertStatus++;
			if (BorderAlertStatus > 1) {
				BorderAlertStatus = 0;
				$("#beach").css("border","1px solid white");
			}
			status = BorderAlertStatus;
			break;
		case 'AudioAlerts':
			AudioAlertsStatus++;
			if (AudioAlertsStatus > 3) {AudioAlertsStatus = 0;}
			status = AudioAlertsStatus;
			break;
	}
	DisplayDescription(option, status);
}

function DisplayDescription(option, status) {
	error = 0;
	if (option == 'RKAutoClick' || option == 'LCAutoClick' || option == 'NinjaAutoClick' || option == 'BorderAlert') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'On';}
		else {Molpy.Notify('Display Description Error',1);}
	}
	else if (option == 'AudioAlerts') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'RK Only';}
		else if (status == 2) {description = 'ONG Only';}
		else if (status == 3) {description = 'RK and ONG';}
		else {Molpy.Notify('Display Description Error - Audio Alerts: ' + status,1);}
	}
	else {
		Molpy.Notify(option + ' is not a valid option', 1);
		error = 1;
	}

	if (error == 0) {g(option + 'Desc').innerHTML = '
' + description;}
}

//Beach Ball Startup
//Set Settings
if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}

//Create Menu
$('#optionsItems').append('

BeachBall Settings

');
$('#optionsItems').append('

Redundakitty Auto Click

');
$('#optionsItems').append('

Logicat Auto Click

');
$('#optionsItems').append('

Ninja Auto Click

');
$('#optionsItems').append('

Ninja Visual Alert

');
$('#optionsItems').append('

Audio Alerts

');
$('#optionsItems').append('

Spawn RK

');
DisplayDescription('RKAutoClick', RKAutoClickStatus);
DisplayDescription('LCAutoClick', LCAutoClickStatus);
DisplayDescription('NinjaAutoClick', NinjaAutoClickStatus);
DisplayDescription('BorderAlert', BorderAlertStatus);
DisplayDescription('AudioAlerts', AudioAlertsStatus);

function MainLoop() {
	Molpy.Notify('BeachBall version ' + version + ' loaded for SandCastle Builder version ' + SCBversion, 1);
	setInterval(function() {
		//Molpy.Notify('1 mNP', 0);
		Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
		RedundaKitty();
		Ninja();
	}, 1800);
}

//Run Main Loop after 3 second startup delay
setTimeout(MainLoop, 3000);

function SpawnRK() {
	Molpy.redactedCountup = Molpy.redactedToggle - 5;
}

<commit_msg>RK Location 4 work Bug Fixing<commit_after>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure and Initial Settings.

var version = '2.0 Beta';
var SCBversion = '3.021'; //Last SandCastle Builder version tested

//Declare and Initialize Variables
var AudioAlertsStatus = 3;
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume = 1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume = 1;
var BorderAlertStatus = 1;
var description = "Error";
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var Logicat = 0;
var LCAutoClickStatus = 0;
var LCSolution = 'blank';
var NinjaAutoClickStatus = 1;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

var start = -1;
var content = "empty";
var length = 0;
var RKLevel = '-1';
var RKLocation = 'null';
var lootBoxes = new Array();
	lootBoxes[0] = 'boosts';
	lootBoxes[1] = 'ninj';
	lootBoxes[2] = 'cyb';
	lootBoxes[3] = 'hpt';
	lootBoxes[4] = 'bean';
	lootBoxes[5] = 'chron';

//Ninja AutoClicker and Border Warnings
function Ninja() {
    if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0 && BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
				Molpy.Notify('Ninja Auto Click', 1);
				if (BorderAlertStatus == 1) {
					$("#beach").css("border","1px solid white");
				}
            }
            else if (BorderAlertStatus == 1) {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
		if (BorderAlertStatus == 1) {
			$("#beach").css("border","4px solid yellow");
		}
        if (incoming_ONG == 0 && (AudioAlertsStatus == 3 || AudioAlertsStatus == 4)) {
			audio_Chime.play();
			incoming_ONG = 1;
        }
    }
    else if (BorderAlertStatus == 1) {
        $("#beach").css("border","1px solid white");
	}
}

function FindRK() {
	/*
	RV of 1 is Sand Tools
	RV of 2 is Castle Tools
	RV of 3 is Boosts Main Page
	RV of 4 is Boosts Menus, Hill People Tech, etc.
	RV of 5 is Badges Earned
	RV of 6 is Badges Available
	*/

	//Determines RK location
	if (Molpy.redactedVisible == 1 || Molpy.redactedVisible == 2 || Molpy.redactedVisible == 3) {
		//Do Nothing
	}
	else if (Molpy.redactedVisible == 4) {
		location = 'null'
		i = 0;
		while (location = 'null' || i < 6) {
			Molpy.Notify(lootBoxes[i], 1)
			if ($('#' + lootboxes[i]).length) {
				showhideToggle(lootBoxes[i]);
				if ($('#redacteditem').length) {
					location = lootBoxes[i];
				}
				else {
					showhideToggle(lootBoxes[i]);
				}
			}
			i++;
			Molpy.Notify(i, 1);
		}
	}
	else if (Molpy.redactedVisible == 5) {
		location = 'badges';
	}
	else if (Molpy.redactedVisible == 6) {
		location = 'badgesav';
	}
	return location;
}

function RedundaKitty() {
	//Refresh Timer Variable
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	//If RedundaKitty is available
	if (Molpy.redactedVisible > 0) {
		Molpy.notify('Got Here', 0);
		RKLocation = FindRK();

		if (RKLocation != 'null' && RKLocation != '4' && !Molpy.options.showhide[RKLocation]) {
			showhideToggle(RKLocation);
		}

		//Determines if it is a Logicat or RK
		//if (RKLocation  != '4') {
			content = $('#redacteditem').html();
			if (content.indexOf("statement") !== -1) {
				Logicat = 1;
				//Molpy.Notify("Logicat Found",0);
			}
			else {
				Logicat = 0;
				//Molpy.Notify("Redundakitty Found",0);
				start = content.indexOf("ClickRedacted");
				content = content.substring(start,start+17);
				content = content.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
				var length = content.length;
				RKLevel = content.substring(13,length);
				Molpy.Notify('RedundaKitty Level is: ' + RKLevel, 1);
			}

			//Highlights RK/LC Border to make it easier to find
			$('#redacteditem').css("border","2px solid red");
		//}

		//Clicks if RedundaKitty AutoClicker Enabled and Not a Logicat
		if (RKAutoClickStatus == 1 && Logicat == 0 ) {
			Molpy.ClickRedacted(RKLevel);
			if (RKLocation != 'null') {
				showhideToggle(RKLocation);
				RKLocation = 'null';
			}
		}
		else if (LCAutoClickStatus == 1 && Logicat == 1) {
			Logicat();
			if (RKLocation != 'null') {
				showhideToggle(RKLocation);
				RKLocation = 'null';
			}
		}
		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % RKAlertFrequency) == 0 && (AudioAlertsStatus == 1 || AudioAlertsStatus == 3)) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

function Logicat() {
	i = 65;
	do
		{LCSolution = String.fromCharCode(i);
		i++;}
	while (Molpy.redactedPuzzleTarget != Molpy.redactedSGen.StatementValue(LCSolution));
	Molpy.ClickRedactedPuzzle(LCSolution);

	/*while (Molpy.redactedPuzzleTarget != undefined) {
		LCSolution = String.fromCharCode(i);
		if (Molpy.redactedPuzzleTarget == Molpy.redactedSGen.StatementValue(LCSolution)) {
			Molpy.ClickRedactedPuzzle(LCSolution);
			Molpy.redactedPuzzleTarget = undefined;
		}
		else {i++;}
	}*/
}

function SwitchOption(option) {
	switch (option) {
		case 'RKAutoClick':
			RKAutoClickStatus++;
			if (RKAutoClickStatus > 1) {RKAutoClickStatus = 0;}
			status = RKAutoClickStatus;
			break;
		case 'LCAutoClick':
			LCAutoClickStatus++;
			if (LCAutoClickStatus > 1) {LCAutoClickStatus = 0;}
			status = LCAutoClickStatus;
			break;
		case 'NinjaAutoClick':
			NinjaAutoClickStatus++;
			if (NinjaAutoClickStatus > 1) {NinjaAutoClickStatus = 0;}
			status = NinjaAutoClickStatus;
			break;
		case 'BorderAlert':
			BorderAlertStatus++;
			if (BorderAlertStatus > 1) {
				BorderAlertStatus = 0;
				$("#beach").css("border","1px solid white");
			}
			status = BorderAlertStatus;
			break;
		case 'AudioAlerts':
			AudioAlertsStatus++;
			if (AudioAlertsStatus > 3) {AudioAlertsStatus = 0;}
			status = AudioAlertsStatus;
			break;
	}
	DisplayDescription(option, status);
}

function DisplayDescription(option, status) {
	error = 0;
	if (option == 'RKAutoClick' || option == 'LCAutoClick' || option == 'NinjaAutoClick' || option == 'BorderAlert') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'On';}
		else {Molpy.Notify('Display Description Error',1);}
	}
	else if (option == 'AudioAlerts') {
		if (status == 0) {description = 'Off';}
		else if (status == 1) {description = 'RK Only';}
		else if (status == 2) {description = 'ONG Only';}
		else if (status == 3) {description = 'RK and ONG';}
		else {Molpy.Notify('Display Description Error - Audio Alerts: ' + status,1);}
	}
	else {
		Molpy.Notify(option + ' is not a valid option', 1);
		error = 1;
	}

	if (error == 0) {g(option + 'Desc').innerHTML = '
' + description;}
}

//Beach Ball Startup
//Set Settings
if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}

//Create Menu
$('#optionsItems').append('

BeachBall Settings

');
$('#optionsItems').append('

Redundakitty Auto Click

');
$('#optionsItems').append('

Logicat Auto Click

');
$('#optionsItems').append('

Ninja Auto Click

');
$('#optionsItems').append('

Ninja Visual Alert

');
$('#optionsItems').append('

Audio Alerts

');
$('#optionsItems').append('

Spawn RK

');
DisplayDescription('RKAutoClick', RKAutoClickStatus);
DisplayDescription('LCAutoClick', LCAutoClickStatus);
DisplayDescription('NinjaAutoClick', NinjaAutoClickStatus);
DisplayDescription('BorderAlert', BorderAlertStatus);
DisplayDescription('AudioAlerts', AudioAlertsStatus);

function MainLoop() {
	Molpy.Notify('BeachBall version ' + version + ' loaded for SandCastle Builder version ' + SCBversion, 1);
	setInterval(function() {
		//Molpy.Notify('1 mNP', 0);
		Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
		RedundaKitty();
		Ninja();
	}, 1800);
}

//Run Main Loop after 3 second startup delay
setTimeout(MainLoop, 3000);

function SpawnRK() {
	Molpy.redactedCountup = Molpy.redactedToggle - 5;
}

<|endoftext|>


<commit_before>// Node packages
const ncp = require('ncp').ncp;
const rimraf = require('rimraf');

// Custom config files
const config = require('../config');

const exit = (message = '') => {
  console.log(message);
  return process.exit(1);
};

module.exports.exit = exit;

module.exports.removeFiles = (files = [], callback) => {
  const fileAmount = files.length;
  let index = 0;
  let file = files[index];

  const nextFile = () => {

    index += 1;

    if (index != fileAmount) {
      file = files[index];
      removeFile(file);
    } else {
      callback();
    }
  };

  const removeFile = (file) => {
    if (typeof file === 'undefined') {
      return;
    }

    if (file != config.tempDirectoryName) {
      rimraf(file, () => {
        nextFile();
      });
    } else {
      nextFile();
    }
  };

  removeFile(file);
};

module.exports.moveTempFiles = (callback) => {
  ncp(`./${config.tempDirectoryName}`, `.`, (err) => {
    if (err) {
      exit(err);
    }

    callback();
  });
};
<commit_msg>Cleaning up message<commit_after>// Node packages
const ncp = require('ncp').ncp;
const rimraf = require('rimraf');

// Custom config files
const config = require('../config');

const exit = (message = '') => {
  console.log(message);
  return process.exit(1);
};

module.exports.exit = exit;

module.exports.removeFiles = (files = [], callback) => {
  console.log('Cleaning up...')
  const fileAmount = files.length;
  let index = 0;
  let file = files[index];

  const nextFile = () => {

    index += 1;

    if (index != fileAmount) {
      file = files[index];
      removeFile(file);
    } else {
      callback();
    }
  };

  const removeFile = (file) => {
    if (typeof file === 'undefined') {
      return;
    }

    if (file != config.tempDirectoryName) {
      rimraf(file, () => {
        nextFile();
      });
    } else {
      nextFile();
    }
  };

  removeFile(file);
};

module.exports.moveTempFiles = (callback) => {
  ncp(`./${config.tempDirectoryName}`, `.`, (err) => {
    if (err) {
      exit(err);
    }

    callback();
  });
};
<|endoftext|>


<commit_before>import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import Stats from 'stats.js';
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { MeshBVH } from '..';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js';

let renderer, camera, scene, gui, stats, outputContainer;
let bvh, model, voxels, controls, boxHelper;
let needsUpdate = false;
let voxelTask = null;

const params = {
	scale: 3,
	resolution: 50,
	solid: true,
	displayMesh: true,
	displayBounds: false,
	insideOnly: false,
	rebuild: () => needsUpdate = true,
};

init();
render();

// TODO: afford use of materials on the final model to validate

function init() {

	const bgColor = 0x111111;

	outputContainer = document.getElementById( 'output' );

	// renderer setup
	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setClearColor( bgColor, 1 );
	renderer.outputEncoding = THREE.sRGBEncoding;
	document.body.appendChild( renderer.domElement );

	// scene setup
	scene = new THREE.Scene();

	const light = new THREE.DirectionalLight( 0xffffff, 1 );
	light.position.set( 3, 6, 9 );
	scene.add( light );

	const revLight = new THREE.DirectionalLight( 0xffffff, 0.1 );
	revLight.position.set( - 3, - 6, - 9 );
	scene.add( revLight );

	const ambient = new THREE.AmbientLight( 0xffffff, 0.25 );
	scene.add( ambient );

	// camera setup
	camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 50 );
	camera.position.set( 10, 0, 0 );
	camera.far = 100;
	camera.updateProjectionMatrix();

	controls = new OrbitControls( camera, renderer.domElement );

	clock = new THREE.Clock();

	// stats setup
	stats = new Stats();
	document.body.appendChild( stats.dom );

	// load the model
	setTimeout( () => {

		model = new THREE.Mesh( new THREE.TorusKnotBufferGeometry( 1, 0.3, 200, 30 ), new THREE.MeshBasicMaterial( {

			transparent: true,
			wireframe: true,
			depthWrite: false,
			opacity: 0.1,

		} ) );
		scene.add( model );

		bvh = new MeshBVH( model.geometry );

		const boxHelperMesh = new THREE.Mesh( new THREE.BoxBufferGeometry() );
		boxHelper = new THREE.BoxHelper( boxHelperMesh, 0xffffff );
		scene.add( boxHelper );

		needsUpdate = true;

	}, 100 );

	gui = new GUI();
	const computeFolder = gui.addFolder( 'voxelize' );
	computeFolder.add( params, 'resolution', 5, 75, 1 ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'scale', 1, 10 ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'solid' ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'insideOnly' ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'rebuild' );

	const helpersFolder = gui.addFolder( 'helpers' );
	helpersFolder.add( params, 'displayMesh' );
	helpersFolder.add( params, 'displayBounds' );

	window.addEventListener( 'resize', function () {

		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();

		renderer.setSize( window.innerWidth, window.innerHeight );

	}, false );

}

// regenerate the mesh and bvh
function* rebuildVoxels() {

	const resolution = params.resolution;
	const totalCount = resolution ** 3;
	const dimensions = params.scale;
	const step = dimensions / resolution;
	const color = new THREE.Color( 0xffffff );
	if ( voxels && voxels.instanceMatrix.count !== totalCount ) {

		voxels.material.dispose();
		voxels.dispose();
		voxels.parent.remove( voxels );
		voxels = null;

	}

	if ( ! voxels ) {

		// set color here to force a color buffer to initialize
		voxels = new THREE.InstancedMesh( new RoundedBoxGeometry( 1, 1, 1, 4, 0.1 ), new THREE.MeshStandardMaterial(), totalCount );
		voxels.setColorAt( 0, color );
		scene.add( voxels );

	}

	const minStart = ( - dimensions / 2.0 ) + step * 0.5;
	const position = new THREE.Vector3();
	const quaternion = new THREE.Quaternion();
	const scale = new THREE.Vector3().setScalar( step );
	const worldMatrix = new THREE.Matrix4();
	const boxMat = new THREE.Matrix4();
	const box = new THREE.Box3();
	const ray = new THREE.Ray();
	ray.direction.set( 0, 0, 1 );
	let voxelCount = 0;

	// TODO: add animation
	for ( let y = 0; y < resolution; y ++ ) {

		for ( let x = 0; x < resolution; x ++ ) {

			for ( let z = 0; z < resolution; z ++ ) {

				position.set(
					minStart + x * step,
					minStart + y * step,
					minStart + z * step,
				);

				box.min.setScalar( - 0.5 * step ).add( position );
				box.max.setScalar( 0.5 * step ).add( position );

				const res = bvh.intersectsBox( box, boxMat );
				if ( res ) {

					if ( ! params.insideOnly ) {

						color.set( 0xffffff );
						worldMatrix.compose( position, quaternion, scale );
						voxels.setMatrixAt( voxelCount, worldMatrix );
						voxels.setColorAt( voxelCount, color );
						voxels.instanceMatrix.needsUpdate = true;
						voxels.instanceColor.needsUpdate = true;

						voxelCount ++;

					}

				} else if ( params.solid ) {

					ray.origin.copy( position );

					// TODO: this would be faster if we could detect a backface hit
					// If we hit an odd number of surfaces then we must be inside a mesh
					const res = bvh.raycast( ray, 2 );
					if ( res.length % 2 === 1 ) {

						color.set( 0xFFC107 ).convertSRGBToLinear();
						worldMatrix.compose( position, quaternion, scale );
						voxels.setMatrixAt( voxelCount, worldMatrix );
						voxels.setColorAt( voxelCount, color );
						voxels.instanceMatrix.needsUpdate = true;
						voxels.instanceColor.needsUpdate = true;

						voxelCount ++;

					}

				}

				voxels.count = voxelCount;
				yield;

			}

		}

	}

	voxels.count = voxelCount;

}

function render() {

	stats.update();
	requestAnimationFrame( render );

	scene.updateMatrixWorld( true );

	if ( needsUpdate ) {

		voxelTask = rebuildVoxels();
		needsUpdate = false;

	}

	if ( voxelTask ) {

		let startTime = window.performance.now();
		while ( window.performance.now() - startTime < 16 ) {

			const res = voxelTask.next();
			if ( res.done ) {

				voxelTask = null;
				break;

			}

		}

	}

	if ( boxHelper ) {

		boxHelper.object.scale.setScalar( params.scale );
		boxHelper.object.updateMatrixWorld( true );
		boxHelper.update();

		model.visible = params.displayMesh;
		boxHelper.visible = params.displayBounds;

	}

	renderer.render( scene, camera );

}
<commit_msg>use raycast first<commit_after>import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import Stats from 'stats.js';
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { MeshBVH } from '..';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js';

let renderer, camera, scene, gui, stats, outputContainer;
let bvh, model, voxels, controls, boxHelper;
let needsUpdate = false;
let voxelTask = null;

const params = {
	scale: 3,
	resolution: 50,
	solid: true,
	displayMesh: true,
	displayBounds: false,
	insideOnly: false,
	rebuild: () => needsUpdate = true,
};

init();
render();

// TODO: afford use of materials on the final model to validate

function init() {

	const bgColor = 0x111111;

	outputContainer = document.getElementById( 'output' );

	// renderer setup
	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setClearColor( bgColor, 1 );
	renderer.outputEncoding = THREE.sRGBEncoding;
	document.body.appendChild( renderer.domElement );

	// scene setup
	scene = new THREE.Scene();

	const light = new THREE.DirectionalLight( 0xffffff, 1 );
	light.position.set( 3, 6, 9 );
	scene.add( light );

	const revLight = new THREE.DirectionalLight( 0xffffff, 0.1 );
	revLight.position.set( - 3, - 6, - 9 );
	scene.add( revLight );

	const ambient = new THREE.AmbientLight( 0xffffff, 0.25 );
	scene.add( ambient );

	// camera setup
	camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 50 );
	camera.position.set( 2, 2, 2 );
	camera.far = 100;
	camera.updateProjectionMatrix();

	controls = new OrbitControls( camera, renderer.domElement );

	// stats setup
	stats = new Stats();
	document.body.appendChild( stats.dom );

	// load the model
	setTimeout( () => {

		model = new THREE.Mesh( new THREE.TorusKnotBufferGeometry( 1, 0.3, 200, 30 ), new THREE.MeshBasicMaterial( {

			transparent: true,
			wireframe: true,
			depthWrite: false,
			opacity: 0.1,

		} ) );
		scene.add( model );

		bvh = new MeshBVH( model.geometry );

		const boxHelperMesh = new THREE.Mesh( new THREE.BoxBufferGeometry() );
		boxHelper = new THREE.BoxHelper( boxHelperMesh, 0xffffff );
		scene.add( boxHelper );

		needsUpdate = true;

	}, 100 );

	gui = new GUI();
	const computeFolder = gui.addFolder( 'voxelize' );
	computeFolder.add( params, 'resolution', 5, 75, 1 ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'scale', 1, 10 ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'solid' ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'insideOnly' ).onChange( () => {

		needsUpdate = true;

	} );
	computeFolder.add( params, 'rebuild' );

	const helpersFolder = gui.addFolder( 'helpers' );
	helpersFolder.add( params, 'displayMesh' );
	helpersFolder.add( params, 'displayBounds' );

	window.addEventListener( 'resize', function () {

		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();

		renderer.setSize( window.innerWidth, window.innerHeight );

	}, false );

}

// regenerate the mesh and bvh
function* rebuildVoxels() {

	const resolution = params.resolution;
	const totalCount = resolution ** 3;
	const dimensions = params.scale;
	const step = dimensions / resolution;
	const color = new THREE.Color( 0xffffff );
	if ( voxels && voxels.instanceMatrix.count !== totalCount ) {

		voxels.material.dispose();
		voxels.dispose();
		voxels.parent.remove( voxels );
		voxels = null;

	}

	if ( ! voxels ) {

		// set color here to force a color buffer to initialize
		voxels = new THREE.InstancedMesh( new RoundedBoxGeometry( 1, 1, 1, 4, 0.1 ), new THREE.MeshStandardMaterial(), totalCount );
		voxels.setColorAt( 0, color );
		scene.add( voxels );

	}

	const minStart = ( - dimensions / 2.0 ) + step * 0.5;
	const position = new THREE.Vector3();
	const quaternion = new THREE.Quaternion();
	const scale = new THREE.Vector3().setScalar( step );
	const worldMatrix = new THREE.Matrix4();
	const boxMat = new THREE.Matrix4();
	const box = new THREE.Box3();
	const ray = new THREE.Ray();
	ray.direction.set( 0, 0, 1 );
	let voxelCount = 0;

	// TODO: add animation
	for ( let y = 0; y < resolution; y ++ ) {

		for ( let x = 0; x < resolution; x ++ ) {

			for ( let z = 0; z < resolution; z ++ ) {

				position.set(
					minStart + x * step,
					minStart + y * step,
					minStart + z * step,
				);

				box.min.setScalar( - 0.5 * step ).add( position );
				box.max.setScalar( 0.5 * step ).add( position );

				const res = bvh.intersectsBox( box, boxMat );
				if ( res ) {

					if ( ! params.insideOnly ) {

						color.set( 0xffffff );
						worldMatrix.compose( position, quaternion, scale );
						voxels.setMatrixAt( voxelCount, worldMatrix );
						voxels.setColorAt( voxelCount, color );
						voxels.instanceMatrix.needsUpdate = true;
						voxels.instanceColor.needsUpdate = true;

						voxelCount ++;

					}

				} else if ( params.solid ) {

					ray.origin.copy( position );

					// If we hit a face backside we know we're inside the mesh. Alternatively we
					// could check if we jot an odd number of faces when checking all intersections.
					const res = bvh.raycastFirst( ray, 2 );
					if ( res && res.face.normal.dot( ray.direction ) > 0.0 ) {

						color.set( 0xFFC107 ).convertSRGBToLinear();
						worldMatrix.compose( position, quaternion, scale );
						voxels.setMatrixAt( voxelCount, worldMatrix );
						voxels.setColorAt( voxelCount, color );
						voxels.instanceMatrix.needsUpdate = true;
						voxels.instanceColor.needsUpdate = true;

						voxelCount ++;

					}

				}

				voxels.count = voxelCount;
				yield;

			}

		}

	}

	voxels.count = voxelCount;

}

function render() {

	stats.update();
	requestAnimationFrame( render );

	scene.updateMatrixWorld( true );

	if ( needsUpdate ) {

		voxelTask = rebuildVoxels();
		needsUpdate = false;

	}

	if ( voxelTask ) {

		let startTime = window.performance.now();
		while ( window.performance.now() - startTime < 16 ) {

			const res = voxelTask.next();
			if ( res.done ) {

				voxelTask = null;
				break;

			}

		}

	}

	if ( boxHelper ) {

		boxHelper.object.scale.setScalar( params.scale );
		boxHelper.object.updateMatrixWorld( true );
		boxHelper.update();

		model.visible = params.displayMesh;
		boxHelper.visible = params.displayBounds;

	}

	renderer.render( scene, camera );

}
<|endoftext|>


<commit_before>var loadedImages = {};
var centerZoomBased;
var staticMapOptions;
var mapWidth;
var mapHeight;
var apiURL;

function hideMapTabChildren() {
    var mapTab = document.getElementById("mapTab");
    for (var i = 0; i < mapTab.childNodes.length; i++) {
        var node = mapTab.childNodes[i];
        if (node.className == "image") {
            mapTab.removeChild(node);
            break;
        }
    }
    for (var i = 0; i < mapTab.childNodes.length; i++) {
        var node = mapTab.childNodes[i];
        if (node.className == "scrollers") {
            mapTab.removeChild(node);
            break;
        }
    }
}

function loadImage(imageURL,imageID) {
    if (!loadedImages[imageID]) {
        // Loads an image from the given URL into the image with the specified ID
        var img = document.getElementById(imageID);
        if (img) {
            if (imageURL != "") {
                img.src = imageURL;
            } else {
                img.src = "/common/images/blank.png";
            }
        }
        loadedImages[imageID] = true;
    }
}

function loadMapImage(newSrc) {
    var mapImage = document.getElementById("staticmapimage");
    var oldSrc = mapImage.src;
    mapImage.src = newSrc;
    if (oldSrc != mapImage.src) {
        show("loadingimage");
    }
    mapImage.src = newSrc; // guarentee onload handler gets called at least
                           // once after showing the loading image (even for cached images)
}

function pixelsFromString(aString) {
    if (aString.substring(aString.length - 2, aString.length) == "px") {
        return aString.substring(0, aString.length - 2);
    } else if (aString.substring(aString.length - 1, aString.length) == "%") {
        return aString.substring(0, aString.length - 1);
    }
    return aString;
}

function zoomInFromCenter() {
    staticMapOptions['zoom'] = parseInt(staticMapOptions['zoom']) + 1;
    updateMapImage();
}

function zoomOutFromCenter() {
    staticMapOptions['zoom'] = parseInt(staticMapOptions['zoom']) - 1;
    updateMapImage();
}

function zoomInFromBBox() {
    var bbox = staticMapOptions['bbox'];
    var dLat = (bbox['ymax'] - bbox['ymin']) / 4;
    var dLon = (bbox['xmax'] - bbox['xmin']) / 4;
    bbox['ymax'] = bbox['ymax'] - dLat;
    bbox['xmax'] = bbox['xmax'] - dLon;
    bbox['ymin'] = bbox['ymin'] + dLat;
    bbox['xmin'] = bbox['xmin'] + dLon;
    staticMapOptions['bbox'] = bbox;
    updateMapImage();
}

function zoomOutFromBBox() {
    var bbox = staticMapOptions['bbox'];
    var dLat = (bbox['ymax'] - bbox['ymin']) / 2;
    var dLon = (bbox['xmax'] - bbox['xmin']) / 2;
    bbox['ymax'] = bbox['ymax'] + dLat;
    bbox['xmax'] = bbox['xmax'] + dLon;
    bbox['ymin'] = bbox['ymin'] - dLat;
    bbox['xmin'] = bbox['xmin'] - dLon;
    staticMapOptions['bbox'] = bbox;
    updateMapImage();
}

function addStaticMapControls() {
    if (!staticMapOptions) {
        return;
    }

    var objMap = document.getElementById("staticmapimage");
    mapWidth = objMap.clientWidth;
    mapHeight = objMap.clientHeight;

    var zoomIn = document.getElementById("zoomin");
    var zoomOut = document.getElementById("zoomout");
    var recenter = document.getElementById("recenter");

    centerZoomBased = ("center" in staticMapOptions);

    if (centerZoomBased) {
        zoomIn.onclick = zoomInFromCenter;
        zoomOut.onclick = zoomOutFromCenter;

        var initCenterLat = staticMapOptions['center']['lat'];
        var initCenterLon = staticMapOptions['center']['lon'];
        var initZoom = staticMapOptions['zoom'];
        recenter.onclick = function() {
            staticMapOptions['center'] = {'lat': initCenterLat, 'lon': initCenterLon};
            staticMapOptions['zoom'] = initZoom;
            updateMapImage();
        }

    } else {
        zoomIn.onclick = zoomInFromBBox;
        zoomOut.onclick = zoomOutFromBBox;

        var initBBox = staticMapOptions['bbox'];
        recenter.onclick = function() {
            staticMapOptions['bbox'] = initBBox;
            updateMapImage();
        }
    }
}

// north and east are sign arguments, e.g.:
// northeast is (1, 1)
// northwest is (1, -1)
// south is (-1, 0)
function scrollMap(north, east) {

    if (centerZoomBased) {
        var zoom = staticMapOptions['zoom'];
        var lat = staticMapOptions['center']['lat'];
        var lon = staticMapOptions['center']['lon'];
        var degreesCovered = 360 / Math.pow(2, parseInt(zoom) + 1);

        lat = parseFloat(lat) + degreesCovered * north;
        lon = parseFloat(lon) + degreesCovered * east;

        // round to 4 decimal places (roughly 10 meters)
        staticMapOptions['center']['lat'] = Math.round(lat * 10000) / 10000;
        staticMapOptions['center']['lon'] = Math.round(lon * 10000) / 10000;

    } else {
        var bbox = staticMapOptions['bbox'];
        var dLat = (bbox['ymax'] - bbox['ymin']) / 2;
        var dLon = (bbox['xmax'] - bbox['xmin']) / 2;
        bbox['ymax'] = bbox['ymax'] + dLat * north;
        bbox['ymin'] = bbox['ymin'] + dLat * north;
        bbox['xmax'] = bbox['xmax'] + dLon * east;
        bbox['xmin'] = bbox['xmin'] + dLon * east;
        staticMapOptions['bbox'] = bbox;
    }
    updateMapImage();
}

function updateMapImage() {
    var httpRequest = new XMLHttpRequest();
    var baseURL = staticMapOptions['baseURL'];
    var mapClass = staticMapOptions['mapClass'];
    var objMap = document.getElementById("staticmapimage");
    var url = apiURL + "?baseURL=" + baseURL + "&mapClass=" + mapClass + "&width=" + mapWidth + "&height=" + mapHeight;
    if (centerZoomBased) {
        var lat = staticMapOptions['center']['lat'];
        var lon = staticMapOptions['center']['lon'];
        var zoom = staticMapOptions['zoom'];
        url = url + "&lat=" + lat + "&lon=" + lon + "&zoom=" + zoom;
    } else {
        var bbox = staticMapOptions['bbox'];
        var bboxStr = bbox['xmin'] + "," + bbox['ymin'] + "," + bbox['xmax'] + "," + bbox['ymax'];
        url = url + "&bbox=" + bboxStr;
    }

    if ("projection" in staticMapOptions) {
        url = url + "&projection=" + staticMapOptions['projection'];
    }
    if ('markers' in staticMapOptions && staticMapOptions['markers']) {
        url += '&markers=' + staticMapOptions['markers'];
    }
    if ('polygons' in staticMapOptions) {
        for (arg in staticMapOptions['polygons']) {
            url += '&'+arg+'='+staticMapOptions['polygons'][arg];
        }
    }
    if ('paths' in staticMapOptions) {
        for (arg in staticMapOptions['paths']) {
            url += '&'+arg+'='+staticMapOptions['paths'][arg];
        }
    }
    // code snippet from http://en.wikipedia.org/wiki/JSON#Use_in_Ajax
    httpRequest.open("GET", url, true);
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
            var obj;
            if(window.JSON) {
                obj = JSON.parse(httpRequest.responseText);
            } else {
                obj = eval('(' + httpRequest.responseText + ')');
            }
            var newSrc = obj['response'];
            loadMapImage(newSrc);
        }
    }
    httpRequest.send(null);
}

// assuming only one of updateMapDimensions or updateContainerDimensions
// gets used so they can reference the same id
var updateMapDimensionsTimeoutId;

// Prevent firebombing the browser with Ajax calls on browsers which fire lots
// of resize events
function updateMapDimensions() {
    window.clearTimeout(updateMapDimensionsTimeoutId);
    updateMapDimensionsTimeoutId = window.setTimeout(doUpdateMapDimensions, 200);
}

function doUpdateMapDimensions() {
    if (!centerZoomBased) {
        // if width and height proprotions changed, we need to update the bbox
        var oldHeight = mapHeight;
        var oldWidth = mapWidth;
    }

    if (window.innerHeight !== undefined) {
        mapHeight = window.innerHeight;
    } else {
        mapHeight = document.documentElement.clientHeight; // ie7
    }

    if (window.innerWidth !== undefined) {
        mapWidth = window.innerWidth;
    } else {
        mapWidth = document.documentElement.clientWidth; // ie7
    }

    if (!centerZoomBased) {
        // if width and height changed, we need to update the bbox
        if ((oldWidth && oldWidth != mapWidth) || (oldHeight && oldHeight != mapHeight)) {
            var bbox = staticMapOptions['bbox'];
            var bboxWidth = bbox['xmax'] - bbox['xmin'];
            var bboxHeight = bbox['ymax'] - bbox['ymin'];
            var newBBoxWidth = bboxWidth * mapWidth / oldWidth;
            var newBBoxHeight = bboxHeight * mapHeight / oldHeight;

            var dWidth = (newBBoxWidth - bboxWidth) / 2;
            var dHeight = (newBBoxHeight - bboxHeight) / 2;

            bbox['xmax'] += dWidth;
            bbox['xmin'] -= dWidth;
            bbox['ymax'] += dHeight;
            bbox['ymin'] -= dHeight;

            staticMapOptions['bbox'] = bbox;
        }
    }

    var objMap = document.getElementById("mapimage");
	var objContainer = document.getElementById("container");
	var objScrollers = document.getElementById("mapscrollers");
    if (objContainer && objMap.className == "fullmap") {
        objContainer.style.width = mapWidth+"px";
        objContainer.style.height = mapHeight+"px";
        objMap.style.width = mapWidth+"px";
        objMap.style.height = mapHeight+"px";
    }
    if (objScrollers) {
        switch (getOrientation()) {
            case 'portrait':
              objScrollers.style.height = (mapHeight-42)+"px";
              objScrollers.style.width = mapWidth+"px";
            break;

            case 'landscape':
              objScrollers.style.height = mapHeight+"px";
              objScrollers.style.width = (mapWidth-42)+"px";
            break;
        }
    }

    updateMapImage();
}

// resizing counterpart for dynamic maps
function updateContainerDimensions() {
    window.clearTimeout(updateMapDimensionsTimeoutId);
    updateMapDimensionsTimeoutId = window.setTimeout(doUpdateContainerDimensions, 250);
}

function doUpdateContainerDimensions() {
    var container = document.getElementById("container");
    if (container) {
        if (window.innerWidth !== undefined) {
            container.style.width = window.innerWidth + "px";
        } else {
            container.style.width = document.documentElement.clientWidth + "px"; // ie7
        }
        if (window.innerHeight !== undefined) {
            container.style.height = window.innerHeight + "px";
        } else {
            container.style.height = document.documentElement.clientHeight + "px"; // ie7
        }
        if (typeof resizeMapOnContainerResize == 'function') {
            resizeMapOnContainerResize();
        }
    }
}

/*
function disable(strID) {
// Visually dims and disables the anchor whose id is strID
	var objA = document.getElementById(strID);
	if(objA) {
		if(objA.className.indexOf("disabled") == -1) { // only disable if it's not already disabled!
			objA.className = objA.className + " disabled";
		}
	}
}

function enable(strID) {
// Visually undims and re-enables the anchor whose id is strID
	var objA = document.getElementById(strID);
	if(objA) {
		objA.className = objA.className.replace("disabled","");
	}
}

function cancelOptions(strFormID) {
// Should cancel map-option changes and hide the form; this is just a stub for future real function
	var objForm = document.getElementById(strFormID);
	if(objForm) { objForm.reset() }
	hide("options");
}
*/

<commit_msg>make sure to call update the map dimensions after the address bar has scrolled into place for iPod touches and iOS simulator (basically call the update dimension function a second time, just in case the first call was too quick)<commit_after>var loadedImages = {};
var centerZoomBased;
var staticMapOptions;
var mapWidth;
var mapHeight;
var apiURL;

function hideMapTabChildren() {
    var mapTab = document.getElementById("mapTab");
    for (var i = 0; i < mapTab.childNodes.length; i++) {
        var node = mapTab.childNodes[i];
        if (node.className == "image") {
            mapTab.removeChild(node);
            break;
        }
    }
    for (var i = 0; i < mapTab.childNodes.length; i++) {
        var node = mapTab.childNodes[i];
        if (node.className == "scrollers") {
            mapTab.removeChild(node);
            break;
        }
    }
}

function loadImage(imageURL,imageID) {
    if (!loadedImages[imageID]) {
        // Loads an image from the given URL into the image with the specified ID
        var img = document.getElementById(imageID);
        if (img) {
            if (imageURL != "") {
                img.src = imageURL;
            } else {
                img.src = "/common/images/blank.png";
            }
        }
        loadedImages[imageID] = true;
    }
}

function loadMapImage(newSrc) {
    var mapImage = document.getElementById("staticmapimage");
    var oldSrc = mapImage.src;
    mapImage.src = newSrc;
    if (oldSrc != mapImage.src) {
        show("loadingimage");
    }
    mapImage.src = newSrc; // guarentee onload handler gets called at least
                           // once after showing the loading image (even for cached images)
}

function pixelsFromString(aString) {
    if (aString.substring(aString.length - 2, aString.length) == "px") {
        return aString.substring(0, aString.length - 2);
    } else if (aString.substring(aString.length - 1, aString.length) == "%") {
        return aString.substring(0, aString.length - 1);
    }
    return aString;
}

function zoomInFromCenter() {
    staticMapOptions['zoom'] = parseInt(staticMapOptions['zoom']) + 1;
    updateMapImage();
}

function zoomOutFromCenter() {
    staticMapOptions['zoom'] = parseInt(staticMapOptions['zoom']) - 1;
    updateMapImage();
}

function zoomInFromBBox() {
    var bbox = staticMapOptions['bbox'];
    var dLat = (bbox['ymax'] - bbox['ymin']) / 4;
    var dLon = (bbox['xmax'] - bbox['xmin']) / 4;
    bbox['ymax'] = bbox['ymax'] - dLat;
    bbox['xmax'] = bbox['xmax'] - dLon;
    bbox['ymin'] = bbox['ymin'] + dLat;
    bbox['xmin'] = bbox['xmin'] + dLon;
    staticMapOptions['bbox'] = bbox;
    updateMapImage();
}

function zoomOutFromBBox() {
    var bbox = staticMapOptions['bbox'];
    var dLat = (bbox['ymax'] - bbox['ymin']) / 2;
    var dLon = (bbox['xmax'] - bbox['xmin']) / 2;
    bbox['ymax'] = bbox['ymax'] + dLat;
    bbox['xmax'] = bbox['xmax'] + dLon;
    bbox['ymin'] = bbox['ymin'] - dLat;
    bbox['xmin'] = bbox['xmin'] - dLon;
    staticMapOptions['bbox'] = bbox;
    updateMapImage();
}

function addStaticMapControls() {
    if (!staticMapOptions) {
        return;
    }

    var objMap = document.getElementById("staticmapimage");
    mapWidth = objMap.clientWidth;
    mapHeight = objMap.clientHeight;

    var zoomIn = document.getElementById("zoomin");
    var zoomOut = document.getElementById("zoomout");
    var recenter = document.getElementById("recenter");

    centerZoomBased = ("center" in staticMapOptions);

    if (centerZoomBased) {
        zoomIn.onclick = zoomInFromCenter;
        zoomOut.onclick = zoomOutFromCenter;

        var initCenterLat = staticMapOptions['center']['lat'];
        var initCenterLon = staticMapOptions['center']['lon'];
        var initZoom = staticMapOptions['zoom'];
        recenter.onclick = function() {
            staticMapOptions['center'] = {'lat': initCenterLat, 'lon': initCenterLon};
            staticMapOptions['zoom'] = initZoom;
            updateMapImage();
        }

    } else {
        zoomIn.onclick = zoomInFromBBox;
        zoomOut.onclick = zoomOutFromBBox;

        var initBBox = staticMapOptions['bbox'];
        recenter.onclick = function() {
            staticMapOptions['bbox'] = initBBox;
            updateMapImage();
        }
    }
}

// north and east are sign arguments, e.g.:
// northeast is (1, 1)
// northwest is (1, -1)
// south is (-1, 0)
function scrollMap(north, east) {

    if (centerZoomBased) {
        var zoom = staticMapOptions['zoom'];
        var lat = staticMapOptions['center']['lat'];
        var lon = staticMapOptions['center']['lon'];
        var degreesCovered = 360 / Math.pow(2, parseInt(zoom) + 1);

        lat = parseFloat(lat) + degreesCovered * north;
        lon = parseFloat(lon) + degreesCovered * east;

        // round to 4 decimal places (roughly 10 meters)
        staticMapOptions['center']['lat'] = Math.round(lat * 10000) / 10000;
        staticMapOptions['center']['lon'] = Math.round(lon * 10000) / 10000;

    } else {
        var bbox = staticMapOptions['bbox'];
        var dLat = (bbox['ymax'] - bbox['ymin']) / 2;
        var dLon = (bbox['xmax'] - bbox['xmin']) / 2;
        bbox['ymax'] = bbox['ymax'] + dLat * north;
        bbox['ymin'] = bbox['ymin'] + dLat * north;
        bbox['xmax'] = bbox['xmax'] + dLon * east;
        bbox['xmin'] = bbox['xmin'] + dLon * east;
        staticMapOptions['bbox'] = bbox;
    }
    updateMapImage();
}

function updateMapImage() {
    var httpRequest = new XMLHttpRequest();
    var baseURL = staticMapOptions['baseURL'];
    var mapClass = staticMapOptions['mapClass'];
    var objMap = document.getElementById("staticmapimage");
    var url = apiURL + "?baseURL=" + baseURL + "&mapClass=" + mapClass + "&width=" + mapWidth + "&height=" + mapHeight;
    if (centerZoomBased) {
        var lat = staticMapOptions['center']['lat'];
        var lon = staticMapOptions['center']['lon'];
        var zoom = staticMapOptions['zoom'];
        url = url + "&lat=" + lat + "&lon=" + lon + "&zoom=" + zoom;
    } else {
        var bbox = staticMapOptions['bbox'];
        var bboxStr = bbox['xmin'] + "," + bbox['ymin'] + "," + bbox['xmax'] + "," + bbox['ymax'];
        url = url + "&bbox=" + bboxStr;
    }

    if ("projection" in staticMapOptions) {
        url = url + "&projection=" + staticMapOptions['projection'];
    }
    if ('markers' in staticMapOptions && staticMapOptions['markers']) {
        url += '&markers=' + staticMapOptions['markers'];
    }
    if ('polygons' in staticMapOptions) {
        for (arg in staticMapOptions['polygons']) {
            url += '&'+arg+'='+staticMapOptions['polygons'][arg];
        }
    }
    if ('paths' in staticMapOptions) {
        for (arg in staticMapOptions['paths']) {
            url += '&'+arg+'='+staticMapOptions['paths'][arg];
        }
    }
    // code snippet from http://en.wikipedia.org/wiki/JSON#Use_in_Ajax
    httpRequest.open("GET", url, true);
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState == 4 && httpRequest.status == 200) {
            var obj;
            if(window.JSON) {
                obj = JSON.parse(httpRequest.responseText);
            } else {
                obj = eval('(' + httpRequest.responseText + ')');
            }
            var newSrc = obj['response'];
            loadMapImage(newSrc);
        }
    }
    httpRequest.send(null);
}

// assuming only one of updateMapDimensions or updateContainerDimensions
// gets used so they can reference the same ids
var updateMapDimensionsTimeoutIds = [];
function clearUpdateMapDimensionsTimeouts() {
    for(var i = 0; i < updateMapDimensionsTimeoutIds.length; i++) {
        window.clearTimeout(updateMapDimensionsTimeoutIds[i]);
    }
    updateMapDimensionsTimeoutIds = [];
}

// Prevent firebombing the browser with Ajax calls on browsers which fire lots
// of resize events
function updateMapDimensions() {
    clearUpdateMapDimensionsTimeouts();
    var timeoutId = window.setTimeout(doUpdateMapDimensions, 200);
    updateMapDimensionsTimeoutIds.push(timeoutId);
    timeoutId = window.setTimeout(doUpdateMapDimensions, 500);
    updateMapDimensionsTimeoutIds.push(timeoutId);
}

function doUpdateMapDimensions() {
    if (!centerZoomBased) {
        // if width and height proprotions changed, we need to update the bbox
        var oldHeight = mapHeight;
        var oldWidth = mapWidth;
    }

    if (window.innerHeight !== undefined) {
        mapHeight = window.innerHeight;
    } else {
        mapHeight = document.documentElement.clientHeight; // ie7
    }

    if (window.innerWidth !== undefined) {
        mapWidth = window.innerWidth;
    } else {
        mapWidth = document.documentElement.clientWidth; // ie7
    }

    if (!centerZoomBased) {
        // if width and height changed, we need to update the bbox
        if ((oldWidth && oldWidth != mapWidth) || (oldHeight && oldHeight != mapHeight)) {
            var bbox = staticMapOptions['bbox'];
            var bboxWidth = bbox['xmax'] - bbox['xmin'];
            var bboxHeight = bbox['ymax'] - bbox['ymin'];
            var newBBoxWidth = bboxWidth * mapWidth / oldWidth;
            var newBBoxHeight = bboxHeight * mapHeight / oldHeight;

            var dWidth = (newBBoxWidth - bboxWidth) / 2;
            var dHeight = (newBBoxHeight - bboxHeight) / 2;

            bbox['xmax'] += dWidth;
            bbox['xmin'] -= dWidth;
            bbox['ymax'] += dHeight;
            bbox['ymin'] -= dHeight;

            staticMapOptions['bbox'] = bbox;
        }
    }

    var objMap = document.getElementById("mapimage");
	var objContainer = document.getElementById("container");
	var objScrollers = document.getElementById("mapscrollers");
    if (objContainer && objMap.className == "fullmap") {
        objContainer.style.width = mapWidth+"px";
        objContainer.style.height = mapHeight+"px";
        objMap.style.width = mapWidth+"px";
        objMap.style.height = mapHeight+"px";
    }
    if (objScrollers) {
        switch (getOrientation()) {
            case 'portrait':
              objScrollers.style.height = (mapHeight-42)+"px";
              objScrollers.style.width = mapWidth+"px";
            break;

            case 'landscape':
              objScrollers.style.height = mapHeight+"px";
              objScrollers.style.width = (mapWidth-42)+"px";
            break;
        }
    }

    updateMapImage();
}

// resizing counterpart for dynamic maps
function updateContainerDimensions() {
    clearUpdateMapDimensionsTimeouts();
    var timeoutId = window.setTimeout(doUpdateContainerDimensions, 200);
    updateMapDimensionsTimeoutIds.push(timeoutId);
    timeoutId = window.setTimeout(doUpdateContainerDimensions, 500);
    updateMapDimensionsTimeoutIds.push(timeoutId);
}

function doUpdateContainerDimensions() {
    var container = document.getElementById("container");
    if (container) {
        var newWidth;
        if (window.innerWidth !== undefined) {
            newWidth = window.innerWidth + "px";
        } else {
            newWidth = document.documentElement.clientWidth + "px"; // ie7
        }
        var newHeight;
        if (window.innerHeight !== undefined) {
            newHeight = window.innerHeight + "px";
        } else {
            newHeight = document.documentElement.clientHeight + "px"; // ie7
        }

        // check to see if the container height and width actually changed
        if (container.style && container.style.width && container.style.width == newWidth
                            && container.style.height && container.style.height == newHeight) {

           // nothing changed so exit early
           return;
        }

        container.style.width = newWidth;
        container.style.height = newHeight;

        if (typeof resizeMapOnContainerResize == 'function') {
            resizeMapOnContainerResize();
        }
    }
}

/*
function disable(strID) {
// Visually dims and disables the anchor whose id is strID
	var objA = document.getElementById(strID);
	if(objA) {
		if(objA.className.indexOf("disabled") == -1) { // only disable if it's not already disabled!
			objA.className = objA.className + " disabled";
		}
	}
}

function enable(strID) {
// Visually undims and re-enables the anchor whose id is strID
	var objA = document.getElementById(strID);
	if(objA) {
		objA.className = objA.className.replace("disabled","");
	}
}

function cancelOptions(strFormID) {
// Should cancel map-option changes and hide the form; this is just a stub for future real function
	var objForm = document.getElementById(strFormID);
	if(objForm) { objForm.reset() }
	hide("options");
}
*/

<|endoftext|>


<commit_before>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure

//Declare and Initialize Variables
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume=1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume=1;
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var KeepBlue = 0;
var NinjaAutoClickStatus = 0;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

//Beach Ball Startup
StartUp();

//Main Loop
setInterval(function() {
    RedundaKitty();
    Ninja();
}, 1800);

function StartUp() {
	//Create Menu
	$('#sectionControls').append('
BeachBall
');

	//Set Settings
	IdleStatus = prompt("Set to idle? (1 = Yes, 0 = No)");
	RKAutoClickStatus = IdleStatus;
	NinjaAutoClickStatus = IdleStatus;
	if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}
}

function Ninja() {
	//Ninja Warnings and Incoming ONG Warning
    Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
	if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
                $("#beach").css("border","4px solid blue");
                KeepBlue = 1;
            }
            else {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
        $("#beach").css("border","4px solid yellow");
            if (incoming_ONG == 0) {
                audio_Chime.play();
                incoming_ONG = 1;
            }
    }
    else if (KeepBlue == 0) {
        $("#beach").css("border","1px solid white");
	}
}

function RedundaKitty() {
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	if (Molpy.redactedVisible > 0) {
		//Clicks if AutoClicker Enabled
		if (RKAutoClickStatus == 1) {
			Molpy.ClickRedacted();
		}

		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % Kitty_Audio_Frequency) == 0) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

<commit_msg>Fixed Audio Bug<commit_after>//v1.0 as Starting Point
//v2.0 Cleaning up code. Setting up Menu Structure

//Declare and Initialize Variables
var audio_Bell = new Audio("http://xenko.comxa.com/Ship_Bell.mp3");
	audio_Bell.volume=1;
var audio_Chime = new Audio("http://xenko.comxa.com/Chime.mp3");
	audio_Chime.volume=1;
var i = 0;
var IdleStatus = 0;
var incoming_ONG = 0;
var KeepBlue = 0;
var NinjaAutoClickStatus = 0;
var RKAutoClickStatus = 0;
var RKAlertFrequency = 8;
var Time_to_ONG = 1800000;

//Beach Ball Startup
StartUp();

//Main Loop
setInterval(function() {
    RedundaKitty();
    Ninja();
}, 1800);

function StartUp() {
	//Create Menu
	$('#sectionControls').append('
BeachBall
');

	//Set Settings
	IdleStatus = prompt("Set to idle? (1 = Yes, 0 = No)");
	RKAutoClickStatus = IdleStatus;
	NinjaAutoClickStatus = IdleStatus;
	if (Molpy.Got('Kitnip') == 1){RKAlertFrequency = 10;}
}

function Ninja() {
	//Ninja Warnings and Incoming ONG Warning
    Time_to_ONG = (Molpy.NPlength * 1000) - Molpy.ONGelapsed;
	if (Molpy.ninjad == 0) {
        if (Molpy.npbONG == 0) {
			$("#beach").css("border","4px solid red");
        }
        else {
            incoming_ONG = 0;
            if (NinjaAutoClickStatus == 1) {
                Molpy.ClickBeach();
                $("#beach").css("border","4px solid blue");
                KeepBlue = 1;
            }
            else {
            $("#beach").css("border","4px solid green");
            }

        }
	}
    else if (Time_to_ONG <= 15000) {
        $("#beach").css("border","4px solid yellow");
            if (incoming_ONG == 0) {
                audio_Chime.play();
                incoming_ONG = 1;
            }
    }
    else if (KeepBlue == 0) {
        $("#beach").css("border","1px solid white");
	}
}

function RedundaKitty() {
	i = Molpy.redactedToggle - Molpy.redactedCountup;

	if (Molpy.redactedVisible > 0) {
		//Clicks if AutoClicker Enabled
		if (RKAutoClickStatus == 1) {
			Molpy.ClickRedacted();
		}

		else {
			//Redundakitty Notifications (Title Bar and Audio)
			document.title = "! kitten !";
			if (Math.floor(i % RKAlertFrequency) == 0) {
				audio_Bell.play();
			}
		}
	}
	else {
		document.title = Molpy.redactedToggle-Molpy.redactedCountup;
		if (i != 0) { i = 0; }
	}
}

<|endoftext|>


<commit_before>

// from http://stackoverflow.com/a/20463021/1435042
function fileSizeSI(a,b,c,d,e){
    return (b=Math,c=b.log,d=1e3,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
        +String.fromCharCode(160)+(e?'kMGTPEZY'[--e]+'B':'Bytes')
}

function formatMilliseconds( ms ){
	var l = [];
	var seconds = Math.floor( ms / 1000 );
	var minutes = Math.floor( seconds / 60 );
	if( minutes >= 1 ){
		l.push( minutes + "m" );
		ms -= seconds * 1000;
		seconds -= minutes * 60;
	}
	if( seconds >= 1 ){
		l.push( seconds + "s" );
		if( minutes < 1 ) ms -= seconds * 1000;
	}
	if( ms !== 0 ){
		l.push( ms.toFixed( 2 ) + "ms" );
	}
	return l.join( " " );
}

function getMmtfUrl( pdbid, cAlphaOnly ){
    pdbid = pdbid.toUpperCase();
    var baseUrl;
    if( cAlphaOnly ){
        baseUrl = "http://132.249.213.68:8080/servemessagecalpha/";
    }else{
        baseUrl = "http://132.249.213.68:8080/servemessagepack/";
    }
    return baseUrl + pdbid;
}

function getStoreByteLength( store ){
    var bytes = 0;
    for( var name in store ){
        var field = store[ name ];
        if( field ) bytes += field.buffer.byteLength;
    }
    return bytes;
}

function getStats( structureHelper, info ){

    var sh = structureHelper;
    var unpackedBytes = (
        getStoreByteLength( sh.bondStore ) +
        getStoreByteLength( sh.atomStore ) +
        getStoreByteLength( sh.groupStore ) +
        getStoreByteLength( sh.chainStore ) +
        getStoreByteLength( sh.modelStore )
    );
    return {
        pdbId: sh.pdbCode,

        msgpackByteLength: info.msgpackByteLength,
        decodeTimeMs: info.decodeTimeMs,

        numBonds: sh.numBonds,
        numAtoms: sh.numAtoms,
        numGroups: sh.numGroups,
        numChains: sh.numChains,
        numModels: sh.numModels,
    };
}

function getAtomInfo( structureHelper, index ){
    var sh = structureHelper;
    var atom = sh.getAtom( index );
    var group = sh.getGroup( atom[ 0 ] );
    var chain = sh.getChain( group[ 0 ] );
    var model = sh.getModel( chain[ 0 ] );
    return {
        index: index,
        xCoord: atom[ 1 ],
        yCoord: atom[ 2 ],
        zCoord: atom[ 3 ],
        bFactor: atom[ 4 ],
        element: atom[ 5 ],
        atomId: atom[ 6 ],
        hetFlag: atom[ 7 ],
        altLabel: atom[ 8 ],
        atomName: atom[ 9 ],
        insCode: atom[ 10 ],
        occupancy: atom[ 11 ],
        //
        groupNum: group[ 3 ],
        resName: group[ 4 ],
        secStruct: group[ 5 ],
        //
        model: chain[ 0 ],
        chainName: chain[ 3 ],
    };
}

function printObject( obj, id ){
    var elm = document.getElementById( id );
    var html = "";
    for( var name in obj ){
        html += name + ": " + obj[ name ] + "
";
    }
    elm.innerHTML = html;
}

function showRandomAtomInfo( sh, id ){
    var atomInfo = getAtomInfo( sh, Math.floor( Math.random() * sh.numAtoms ) );
    printObject( atomInfo, id );
}

function showStats( stats, id ){
    stats.fileSize = fileSizeSI( stats.msgpackByteLength ),
    stats.decodeTime = formatMilliseconds( stats.decodeTimeMs ),
    delete stats.msgpackByteLength;
    delete stats.decodeTimeMs;
    printObject( stats, id );
}

//

function StructureHelper( d ){

    console.log( d )

    function getBond( index ){
        return [
            d.bondStore.atomIndex1[ index ],
            d.bondStore.atomIndex2[ index ],
            d.bondStore.bondOrder[ index ]
        ];
    }

    function getAtom( index ){
        var groupIndex = d.atomStore.groupIndex[ index ];
        var group = d.groupMap[ d.groupStore.groupTypeId[ groupIndex ] ];
        var groupAtomOffset = d.groupStore.atomOffset[ groupIndex ];
        var groupAtomIndex = index - groupAtomOffset;
        return [
            groupIndex,
            d.atomStore.xCoord[ index ],
            d.atomStore.yCoord[ index ],
            d.atomStore.zCoord[ index ],
            d.atomStore.bFactor ? d.atomStore.bFactor[ index ] : null,
            group.atomInfo[ groupAtomIndex * 2 ],
            d.atomStore.atomId ? d.atomStore.atomId[ index ] : null,
            group.hetFlag,
            d.atomStore.altLabel ? String.fromCharCode( d.atomStore.altLabel[ index ] ) : null,
            group.atomInfo[ groupAtomIndex * 2 + 1 ],
            d.atomStore.insCode ? d.atomStore.insCode[ index ] : null,
            d.atomStore.occupancy ? d.atomStore.occupancy[ index ] : null
        ];
    }

    function getGroup( index ){
        var group = d.groupMap[ d.groupStore.groupTypeId[ index ] ];
        return [
            d.groupStore.chainIndex[ index ],
            d.groupStore.atomOffset[ index ],
            d.groupStore.atomCount[ index ],
            d.groupStore.groupNum[ index ],
            group.resName,
            String.fromCharCode( d.groupStore.secStruct[ index ] ),
        ];
    }

    function getChain( index ){
        var chainName = "";
        for( var k = 0; k < 4; ++k ){
            var code = d.chainStore.chainName[ 4 * index + k ];
            if( code ){
                chainName += String.fromCharCode( code );
            }else{
                break;
            }
        }
        return [
            d.chainStore.modelIndex[ index ],
            d.chainStore.groupOffset[ index ],
            d.chainStore.groupCount[ index ],
            chainName,
        ];
    }

    function getModel( index ){
        return [
            d.modelStore.chainOffset[ index ],
            d.modelStore.chainCount[ index ]
        ];
    }

    function eachBond( callback ){
        for( var i = 0; i < d.numBonds; ++i ){
            callback.apply( null, getBond( i ) );
        }
    }

    function eachAtom( callback ){
        for( var i = 0; i < d.numAtoms; ++i ){
            callback.apply( null, getAtom( i ) );
        }
    }

    function eachGroup( callback ){
        for( var i = 0; i < d.numGroups; ++i ){
            callback.apply( null, getGroup( i ) );
        }
    }

    function eachChain( callback ){
        for( var i = 0; i < d.numChains; ++i ){
            callback.apply( null, getChain( i ) );
        }
    }

    function eachModel( callback ){
        for( var i = 0; i < d.numModels; ++i ){
            callback.apply( null, getModel( i ) );
        }
    }

    // API

    this.unitCell = d.unitCell;
    this.spaceGroup = d.spaceGroup;
    this.bioAssembly = d.bioAssembly;
    this.pdbCode = d.pdbCode;
    this.title = d.title;

    this.numBonds = d.numBonds;
    this.numAtoms = d.numAtoms;
    this.numGroups = d.numGroups;
    this.numChains = d.numChains;
    this.numModels = d.numModels;

    this.bondStore = d.bondStore;
    this.atomStore = d.atomStore;
    this.groupStore = d.groupStore;
    this.chainStore = d.chainStore;
    this.modelStore = d.modelStore;

    this.groupMap = d.groupMap;

    this.getBond = getBond;
    this.getAtom = getAtom;
    this.getGroup = getGroup;
    this.getChain = getChain;
    this.getModel = getModel;

    this.eachBond = eachBond;
    this.eachAtom = eachAtom;
    this.eachGroup = eachGroup;
    this.eachChain = eachChain;
    this.eachModel = eachModel;

}
<commit_msg>tweaked insertion code handling in getAtom<commit_after>

// from http://stackoverflow.com/a/20463021/1435042
function fileSizeSI(a,b,c,d,e){
    return (b=Math,c=b.log,d=1e3,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
        +String.fromCharCode(160)+(e?'kMGTPEZY'[--e]+'B':'Bytes')
}

function formatMilliseconds( ms ){
	var l = [];
	var seconds = Math.floor( ms / 1000 );
	var minutes = Math.floor( seconds / 60 );
	if( minutes >= 1 ){
		l.push( minutes + "m" );
		ms -= seconds * 1000;
		seconds -= minutes * 60;
	}
	if( seconds >= 1 ){
		l.push( seconds + "s" );
		if( minutes < 1 ) ms -= seconds * 1000;
	}
	if( ms !== 0 ){
		l.push( ms.toFixed( 2 ) + "ms" );
	}
	return l.join( " " );
}

function getMmtfUrl( pdbid, cAlphaOnly ){
    pdbid = pdbid.toUpperCase();
    var baseUrl;
    if( cAlphaOnly ){
        baseUrl = "http://132.249.213.68:8080/servemessagecalpha/";
    }else{
        baseUrl = "http://132.249.213.68:8080/servemessagepack/";
    }
    return baseUrl + pdbid;
}

function getStoreByteLength( store ){
    var bytes = 0;
    for( var name in store ){
        var field = store[ name ];
        if( field ) bytes += field.buffer.byteLength;
    }
    return bytes;
}

function getStats( structureHelper, info ){

    var sh = structureHelper;
    var unpackedBytes = (
        getStoreByteLength( sh.bondStore ) +
        getStoreByteLength( sh.atomStore ) +
        getStoreByteLength( sh.groupStore ) +
        getStoreByteLength( sh.chainStore ) +
        getStoreByteLength( sh.modelStore )
    );
    return {
        pdbId: sh.pdbCode,

        msgpackByteLength: info.msgpackByteLength,
        decodeTimeMs: info.decodeTimeMs,

        numBonds: sh.numBonds,
        numAtoms: sh.numAtoms,
        numGroups: sh.numGroups,
        numChains: sh.numChains,
        numModels: sh.numModels,
    };
}

function getAtomInfo( structureHelper, index ){
    var sh = structureHelper;
    var atom = sh.getAtom( index );
    var group = sh.getGroup( atom[ 0 ] );
    var chain = sh.getChain( group[ 0 ] );
    var model = sh.getModel( chain[ 0 ] );
    return {
        index: index,
        xCoord: atom[ 1 ],
        yCoord: atom[ 2 ],
        zCoord: atom[ 3 ],
        bFactor: atom[ 4 ],
        element: atom[ 5 ],
        atomId: atom[ 6 ],
        hetFlag: atom[ 7 ],
        altLabel: atom[ 8 ],
        atomName: atom[ 9 ],
        insCode: atom[ 10 ],
        occupancy: atom[ 11 ],
        //
        groupNum: group[ 3 ],
        resName: group[ 4 ],
        secStruct: group[ 5 ],
        //
        model: chain[ 0 ],
        chainName: chain[ 3 ],
    };
}

function printObject( obj, id ){
    var elm = document.getElementById( id );
    var html = "";
    for( var name in obj ){
        html += name + ": " + obj[ name ] + "
";
    }
    elm.innerHTML = html;
}

function showRandomAtomInfo( sh, id ){
    var atomInfo = getAtomInfo( sh, Math.floor( Math.random() * sh.numAtoms ) );
    printObject( atomInfo, id );
}

function showStats( stats, id ){
    stats.fileSize = fileSizeSI( stats.msgpackByteLength ),
    stats.decodeTime = formatMilliseconds( stats.decodeTimeMs ),
    delete stats.msgpackByteLength;
    delete stats.decodeTimeMs;
    printObject( stats, id );
}

//

function StructureHelper( d ){

    function getBond( index ){
        return [
            d.bondStore.atomIndex1[ index ],
            d.bondStore.atomIndex2[ index ],
            d.bondStore.bondOrder[ index ]
        ];
    }

    function getAtom( index ){
        var groupIndex = d.atomStore.groupIndex[ index ];
        var group = d.groupMap[ d.groupStore.groupTypeId[ groupIndex ] ];
        var groupAtomOffset = d.groupStore.atomOffset[ groupIndex ];
        var groupAtomIndex = index - groupAtomOffset;
        return [
            groupIndex,
            d.atomStore.xCoord[ index ],
            d.atomStore.yCoord[ index ],
            d.atomStore.zCoord[ index ],
            d.atomStore.bFactor ? d.atomStore.bFactor[ index ] : null,
            group.atomInfo[ groupAtomIndex * 2 ],
            d.atomStore.atomId ? d.atomStore.atomId[ index ] : null,
            group.hetFlag,
            d.atomStore.altLabel ? String.fromCharCode( d.atomStore.altLabel[ index ] ) : null,
            group.atomInfo[ groupAtomIndex * 2 + 1 ],
            d.atomStore.insCode ? String.fromCharCode( d.atomStore.insCode[ index ] ) : null,
            d.atomStore.occupancy ? d.atomStore.occupancy[ index ] : null
        ];
    }

    function getGroup( index ){
        var group = d.groupMap[ d.groupStore.groupTypeId[ index ] ];
        return [
            d.groupStore.chainIndex[ index ],
            d.groupStore.atomOffset[ index ],
            d.groupStore.atomCount[ index ],
            d.groupStore.groupNum[ index ],
            group.resName,
            String.fromCharCode( d.groupStore.secStruct[ index ] ),
        ];
    }

    function getChain( index ){
        var chainName = "";
        for( var k = 0; k < 4; ++k ){
            var code = d.chainStore.chainName[ 4 * index + k ];
            if( code ){
                chainName += String.fromCharCode( code );
            }else{
                break;
            }
        }
        return [
            d.chainStore.modelIndex[ index ],
            d.chainStore.groupOffset[ index ],
            d.chainStore.groupCount[ index ],
            chainName,
        ];
    }

    function getModel( index ){
        return [
            d.modelStore.chainOffset[ index ],
            d.modelStore.chainCount[ index ]
        ];
    }

    function eachBond( callback ){
        for( var i = 0; i < d.numBonds; ++i ){
            callback.apply( null, getBond( i ) );
        }
    }

    function eachAtom( callback ){
        for( var i = 0; i < d.numAtoms; ++i ){
            callback.apply( null, getAtom( i ) );
        }
    }

    function eachGroup( callback ){
        for( var i = 0; i < d.numGroups; ++i ){
            callback.apply( null, getGroup( i ) );
        }
    }

    function eachChain( callback ){
        for( var i = 0; i < d.numChains; ++i ){
            callback.apply( null, getChain( i ) );
        }
    }

    function eachModel( callback ){
        for( var i = 0; i < d.numModels; ++i ){
            callback.apply( null, getModel( i ) );
        }
    }

    // API

    this.unitCell = d.unitCell;
    this.spaceGroup = d.spaceGroup;
    this.bioAssembly = d.bioAssembly;
    this.pdbCode = d.pdbCode;
    this.title = d.title;

    this.numBonds = d.numBonds;
    this.numAtoms = d.numAtoms;
    this.numGroups = d.numGroups;
    this.numChains = d.numChains;
    this.numModels = d.numModels;

    this.bondStore = d.bondStore;
    this.atomStore = d.atomStore;
    this.groupStore = d.groupStore;
    this.chainStore = d.chainStore;
    this.modelStore = d.modelStore;

    this.groupMap = d.groupMap;

    this.getBond = getBond;
    this.getAtom = getAtom;
    this.getGroup = getGroup;
    this.getChain = getChain;
    this.getModel = getModel;

    this.eachBond = eachBond;
    this.eachAtom = eachAtom;
    this.eachGroup = eachGroup;
    this.eachChain = eachChain;
    this.eachModel = eachModel;

}
<|endoftext|>


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

/**
 * @access public
 * @desc For use Chatwork Services
 */
export default class chatwork extends baseChatwork {

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分自身の情報を取得
   * @example
   * const cw = new Chatwork(apiKey);
   * cw.me()
   *   .then(res => {
   *     console.log(res.data);
   *     console.log(res.status);
   *     console.log(res.statusText);
   *     console.log(res.headers);
   *     console.log(res.config);
   *   })
   *   .catch(err => {
   *     if(err.response) {
   *       console.log(err.response.data);
   *       console.log(err.response.status);
   *       console.log(err.response.headers);
   *     } else if(err.request) {
   *       console.log(err.request);
   *     } else {
   *       console.log('Error', err.message);
   *     }
   *     console.log(err.config);
   *   });
   */
  me() {
    return this.instance.get('/me');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分の未読数、未読To数、未完了タスク数を返す
   */
  getMyStatus() {
    return this.instance.get('/my/status');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のタスク一覧を取得する。(100件まで取得可能)
   * @param {number} assignedByAccountId - タスクの依頼者のアカウントID
   * @param {string} status - タスクのステータス 'open' or 'done'
   */
  listMyTasks(assignedByAccountId, status) {
    return this.instance.get('/my/tasks', {
      params: {
        assigned_by_account_id: assignedByAccountId,
        status,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のコンタクト一覧を取得
   */
  listMyContacts() {
    return this.instance.get('/contacts');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分に対するコンタクト承認依頼一覧を取得する(100件まで取得可能)
   */
  incomingRequests() {
    return this.instance.get('/incoming_requests');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のチャット一覧の取得
   */
  listMyMessages() {
    return this.instance.get('/rooms');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットの名前、アイコン、種類(my/direct/group)を取得
   * @param {number} roomId - チャットルームのID
   */
  getRoomInfo(roomId) {
    return this.instance.get(`/rooms/${roomId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのメンバー一覧を取得
   * @param {number} roomId - チャットルームのID
   */
  listRoomMembers(roomId) {
    return this.instance.get(`/rooms/${roomId}/members`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのメッセージ一覧を取得。パラメータ未指定だと前回取得分からの差分のみを返します。(最大100件まで取得)
   * @param {number} roomId - チャットルームのID
   * @param {number} [isForce = 0] - 1を指定すると未取得にかかわらず最新の100件を取得します
   */
  listRoomMessages(roomId, isForce = 0) {
    return this.instance.get(`/rooms/${roomId}/messages`, {
      params: {
        force: isForce,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc メッセージ情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {string} messageId - 参照するメッセージのID
   */
  getMessageInfo(roomId, messageId) {
    return this.instance.get(`/rooms/${roomId}/messages/${messageId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのタスク一覧を取得 (100件まで取得可能)
   * @param {number} roomId - チャットルームのID
   * @param {number} accountId - タスクの担当者のアカウントID
   * @param {number} assignedByAccountId - タスクの依頼者のアカウントID
   * @param {string} [status = 'open'] - タスクのステータス 'open' or 'done'
   */
  listRoomTasks(roomId, accountId, assignedByAccountId, status = 'open') {
    return this.instance.get(`/rooms/${roomId}/tasks`, {
      params: {
        account_id: accountId,
        assigned_by_account_id: assignedByAccountId,
        status,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc タスク情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {number} taskId - 参照するタスクのID
   */
  getTaskInfo(roomId, taskId) {
    return this.instance.get(`/rooms/${roomId}/tasks/${taskId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのファイル一覧を取得 (100件まで取得可能)
   * @param {number} roomId - チャットルームのID
   * @param {number} accountId - アップロードしたユーザーのアカウントID
   */
  listRoomFiles(roomId, accountId) {
    return this.instance.get(`/rooms/${roomId}/files`, {
      params: {
        account_id: accountId,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc ファイル情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {number} fileId - 参照するファイルのID
   * @param {number} [isUrl = 0] - 1のときダウンロードする為のURLを生成する
   */
  getFileInfo(roomId, fileId, isUrl = 0) {
    return this.instance.get(`/rooms/${roomId}/files/${fileId}`, {
      params: {
        create_download_url: isUrl,
      },
    });
  }

}
<commit_msg>Append default value to listMyTasks(status)<commit_after>import baseChatwork from './baseChatwork';

/**
 * @access public
 * @desc For use Chatwork Services
 */
export default class chatwork extends baseChatwork {

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分自身の情報を取得
   * @example
   * const cw = new Chatwork(apiKey);
   * cw.me()
   *   .then(res => {
   *     console.log(res.data);
   *     console.log(res.status);
   *     console.log(res.statusText);
   *     console.log(res.headers);
   *     console.log(res.config);
   *   })
   *   .catch(err => {
   *     if(err.response) {
   *       console.log(err.response.data);
   *       console.log(err.response.status);
   *       console.log(err.response.headers);
   *     } else if(err.request) {
   *       console.log(err.request);
   *     } else {
   *       console.log('Error', err.message);
   *     }
   *     console.log(err.config);
   *   });
   */
  me() {
    return this.instance.get('/me');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分の未読数、未読To数、未完了タスク数を返す
   */
  getMyStatus() {
    return this.instance.get('/my/status');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のタスク一覧を取得する。(100件まで取得可能)
   * @param {number} assignedByAccountId - タスクの依頼者のアカウントID
   * @param {string} [status = 'open'] - タスクのステータス 'open' or 'done'
   */
  listMyTasks(assignedByAccountId, status = 'open') {
    return this.instance.get('/my/tasks', {
      params: {
        assigned_by_account_id: assignedByAccountId,
        status,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のコンタクト一覧を取得
   */
  listMyContacts() {
    return this.instance.get('/contacts');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分に対するコンタクト承認依頼一覧を取得する(100件まで取得可能)
   */
  incomingRequests() {
    return this.instance.get('/incoming_requests');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc 自分のチャット一覧の取得
   */
  listMyMessages() {
    return this.instance.get('/rooms');
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットの名前、アイコン、種類(my/direct/group)を取得
   * @param {number} roomId - チャットルームのID
   */
  getRoomInfo(roomId) {
    return this.instance.get(`/rooms/${roomId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのメンバー一覧を取得
   * @param {number} roomId - チャットルームのID
   */
  listRoomMembers(roomId) {
    return this.instance.get(`/rooms/${roomId}/members`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのメッセージ一覧を取得。パラメータ未指定だと前回取得分からの差分のみを返します。(最大100件まで取得)
   * @param {number} roomId - チャットルームのID
   * @param {number} [isForce = 0] - 1を指定すると未取得にかかわらず最新の100件を取得します
   */
  listRoomMessages(roomId, isForce = 0) {
    return this.instance.get(`/rooms/${roomId}/messages`, {
      params: {
        force: isForce,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc メッセージ情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {string} messageId - 参照するメッセージのID
   */
  getMessageInfo(roomId, messageId) {
    return this.instance.get(`/rooms/${roomId}/messages/${messageId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのタスク一覧を取得 (100件まで取得可能)
   * @param {number} roomId - チャットルームのID
   * @param {number} accountId - タスクの担当者のアカウントID
   * @param {number} assignedByAccountId - タスクの依頼者のアカウントID
   * @param {string} [status = 'open'] - タスクのステータス 'open' or 'done'
   */
  listRoomTasks(roomId, accountId, assignedByAccountId, status = 'open') {
    return this.instance.get(`/rooms/${roomId}/tasks`, {
      params: {
        account_id: accountId,
        assigned_by_account_id: assignedByAccountId,
        status,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc タスク情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {number} taskId - 参照するタスクのID
   */
  getTaskInfo(roomId, taskId) {
    return this.instance.get(`/rooms/${roomId}/tasks/${taskId}`);
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc チャットのファイル一覧を取得 (100件まで取得可能)
   * @param {number} roomId - チャットルームのID
   * @param {number} accountId - アップロードしたユーザーのアカウントID
   */
  listRoomFiles(roomId, accountId) {
    return this.instance.get(`/rooms/${roomId}/files`, {
      params: {
        account_id: accountId,
      },
    });
  }

  /**
   * @return {Promise} Return response or error message.
   * @desc ファイル情報を取得
   * @param {number} roomId - チャットルームのID
   * @param {number} fileId - 参照するファイルのID
   * @param {number} [isUrl = 0] - 1のときダウンロードする為のURLを生成する
   */
  getFileInfo(roomId, fileId, isUrl = 0) {
    return this.instance.get(`/rooms/${roomId}/files/${fileId}`, {
      params: {
        create_download_url: isUrl,
      },
    });
  }

}
<|endoftext|>


<commit_before>'use strict';

var express = require('express'),
    router = express.Router(),
    campaigns = require('../../app/controllers/campaign.server.controller'),
    users = require('../../app/controllers/users.server.controller');

module.exports = function(app) {
  app.route('/campaign/*').all(users.requiresLogin);
  app.route('/campaigns/*').all(users.requiresLogin);
  app.route('/campaign/add').post(campaigns.createCampaign);
  app.route('/campaign/:campaignId').get(campaigns.getCampaign);
  app.route('/campaign/:campaignId/edit').put(campaigns.updateCampaign);
  app.route('/campaign/:campaignId').delete(campaigns.deleteCampaign);
  app.route('/campaigns/:userId').get(campaigns.getUserCampaigns);
  app.route('/campaigns').get(campaigns.getCampaigns);
};
<commit_msg>refactored the route to allow unathenticated user to view campaigns only<commit_after>'use strict';

var express = require('express'),
    router = express.Router(),
    campaigns = require('../../app/controllers/campaign.server.controller'),
    users = require('../../app/controllers/users.server.controller');

module.exports = function(app) {
  app.route('/campaign/add').post( users.requiresLogin, campaigns.createCampaign);
  app.route('/campaign/:campaignId').get(campaigns.getCampaign);
  app.route('/campaign/:campaignId/edit').put(users.requiresLogin, campaigns.updateCampaign);
  app.route('/campaign/:campaignId').delete(users.requiresLogin, campaigns.deleteCampaign);
  app.route('/campaigns').get(campaigns.getCampaigns);
  app.route('/campaigns/:userId').get(users.requiresLogin, campaigns.getUserCampaigns);
};
<|endoftext|>