<commit_before>'use strict';

const fs = require('fs');
const path = require('path');

const requestsFile = path.resolve(__dirname, '../config/chat-plugins/genrequests.json');

//const permittedGenners = ['desokoro', 'lombres']
//const permittedGennersByNames = ['Desokoro', 'Lombres']

let genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};
try {
	genRequests = require(requestsFile);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND') throw e;
}

if (!(genRequests || typeof genRequests === 'object')) genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};

function writeGenRequests() {
	fs.writeFileSync(requestsFile, JSON.stringify(genRequests));
}

exports.commands = {
	genreq: function (target, room, user) {
		if (genRequests.blacklist.includes(user.userid)) return false;
		if (user.locked || !user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
		if (!target) return this.errorReply("Please specify something for the gen request.");
				if (target.includes("http://")) {
			target = '' + 'Gen Request' + '';
		}
		genRequests.requests.push({username: user.name, request: target, time: new Date().toUTCString()});
		writeGenRequests();
		this.sendReply("Your gen request was successfully added to the queue.");
	},

	reqview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.requests.length) return this.errorReply('There are no current genning requests.');
		let output = `There are <b>${genRequests.requests.length}</b> users who requested genning:<br />`;
		for (let i = 0; i < genRequests.requests.length; i++) {
			output += `<b>${genRequests.requests[i].username}</b>: ${genRequests.requests[i].request} (${genRequests.requests[i].time}).<br />`;
		}
		this.sendReplyBox(output);
	},

        gbl: 'genblacklist',
	genblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply('Please specify a target.');
		let blacklisted = toId(target);
		if (genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is already present on the genning blacklist.`);
		genRequests.blacklist.push(blacklisted);
		writeGenRequests();
		this.sendReply(`${target} was added to the genning blacklist.`);
		// Notify the user that they were blacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were added to the genning blacklist by ${user.name}. If you feel this is unfair, please PM an administrator (~) or the user who blacklisted you.`);
	},

        gwl: 'genunblacklist',
        genwhitelist: 'genunblacklist',
	genunblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply("Please specify a target.");
		let blacklisted = toId(target);
		if (!genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is currently not on the genning blacklist.`);
		genRequests.blacklist.splice(genRequests.blacklist.indexOf(blacklisted), 1);
		writeGenRequests();
		this.sendReply(`${target} was removed from the genning blacklist.`);
		// Notify the user that they were unblacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were removed from the genning blacklist by ${user.name}.`);
	},

        vbl: 'blacklistview',
        blv: 'blacklistview',
	blacklistview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.blacklist.length) return this.errorReply("There are currently no users on the genning blacklist.");
		let output = `There are <b>${genRequests.blacklist.length}</b> users on the genning blacklist:<br />`;
		for (let i = 0; i < genRequests.blacklist.length; i++) {
			output += `<i>${genRequests.blacklist[i]}</i><br />`;
		}
		this.sendReplyBox(output);
	},

        delreq: 'reqclear',
	reqclear: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!(target || target === 'force')) {
			this.errorReply("WARNING: This will reset all genning requests on the server.");
			this.errorReply("If you wish to continue, use /reqclear force.");
			return;
		}
		// Really lazy hack for doing this - just reset everything in genRequests.requests.
		genRequests.requests = [];
		writeGenRequests();
		this.sendReply("All genning requests were erased from the server.");
	},

	genguide: function (target, room, user) {
	this.sendReplyBox('
GENNING GUIDE

genreq (request): Requests a gen for those who can gen and are permitted by Tsunami to do so

viewgenners: View eligible genners

reportgenner: Reports a genner to Desokoro; use only if absolutely needed

More commands available to all users will be listed here in the future
');
	},

	staffgenguide: function (target, room, user) {
	if (!genRequests.permittedGenners.includes(user.userid) || !genRequests.permittedGennersByNames.includes(user.name)) return this.errorReply('You are not permitted to view this.');
	this.sendReplyBox('
GENNING RESPONSE GUIDE

reqclear: Clears all requests

vbl: Views all blacklisted users

gbl: Blacklists a user.

gwl: Un-blacklists a user
');
	},

	genneradd: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.')
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' could not be found. Please check your spelling!');
		if (genRequests.permittedGenners.includes(targetUser.userid) || genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply(`${target} is already present on the permitted genners list.`);
		genRequests.permittedGenners.push(targetUser.userid);
		genRequests.permittedGennersByNames.push(targetUser.name);
		writeGenRequests();
	this.sendReply('You have successfully added ' + targetUser.name + ' to the permitted genners list!');
	console.log(targetUser.name + ' was added to the permitted genners list by ' + user.name + '.');
	},

	removegenner: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.');
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' was not found. Check your spelling!');
	if (!genRequests.permittedGenners.includes(targetUser.userid) || !genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply('The target ' + target + ' is not on the permitted genners list.');
		genRequests.permittedGenners.splice(genRequests.permittedGenners.indexOf(targetUser.userid), 1);
		genRequests.permittedGennersByNames.splice(genRequests.permittedGennersByNames.indexOf(targetUser.name), 1);
		writeGenRequests();
	this.sendReply(target + ' was successfully removed from the permitted genners list.');
	console.log(target + ' was removed from the genners list by ' + user.name);
	},

	viewgenners: function (target, room, user) {
	for (let i = 0; i <  genRequests.permittedGennersByNames.length; i++) { this.sendReplyBox(genRequests.permittedGennersByNames[i]);   }
	},

	reportgenner: function (target, room, user) {
	//let CaseSensitiveArray = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
	if (genRequests.blacklist.includes(user.userid)) return this.errorReply('You are not allowed to partake in any genning services.');
	if (user.canTalk) return this.errorReply('You are currently unable to be trusted due to your disciplinary status; your report will not be accepted.');
	if (!user.autoconfirmed) return this.errorReply('You are not autoconfirmed and your report will not be accepted.');
	if (!target) return this.errorReply('Please specify a target.');
	if (!genRequests.permittedGenners.includes(target) && !genRequests.permittedGennersByNames.includes(target)) return this.errorReply('The user you have reported is not a valid genner.');
	if (target === 'desokoro' || target === 'Desokoro') return this.errorReply('Reporting the owner of the server to himself won\'t do you much good...');
	//if (CaseSensitiveArray.includes(target)) this.errorReply('Only lowercase letters and numbers can be used to report a genner.');
	this.parse('/tell Desokoro, TOKEN OF AUTHENTICITY: ' + user.name + '|' + Math.floor(Math.random() * 20) + '|' +  + Math.floor(Math.random() * 20) + '|' + Math.floor(Math.random() * 20) + '. Reporting genner ' + target + ' for misconduct.');
	},

	gensyscredits: function (target, room, user, connection) {
	this.sendReplyBox('Thank ' + '' + Chat.escapeHTML('Mystifi') + '' + ' for essentially building the framework for the genning request system!. The system is maintained by ' + '' + Chat.escapeHTML('Desokoro') + '' + '.');
	},
};

/*'use strict';

let GenReqArray = []

exports.commands = {
genreq: function (target, room, user) {
if (user.isBlacklisted === true) return this.errorReply('You are blacklisted.');
if (user.locked) return this.errorReply('You do not have adequate permissions to request a gen.');
if (!user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
//if (GenReqArray.length === 0) {
GenReqArray.push(user.userid);
//}
},

reqview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('Only Desokoro is permitted to use this.');
if (GenReqArray.length === 0) return this.errorReply('Nobody has requested a gen.');
for (let i = 0; i <  GenReqArray.length; i++) { this.sendReplyBox(GenReqArray[i]);   }
},

genblacklist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.errorReply(targetUser.username + ' is already blacklisted.');
targetUser.isBlacklisted = true;
this.sendReply(targetUser + ' is now blacklisted.');
},

genwhitelist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === false) return this.errorReply(targetUser.username + ' is not blacklisted.');
targetUser.isBlacklisted = false;
this.sendReply(targetUser + ' is no longer blacklisted.');
},

blacklistview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) this.errorReply (target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.sendReply('This user is blacklisted.');
else return this.sendReply('This user is not blacklisted.');
},

reqclear: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
GenReqArray = []
    this.sendReply('All requests have been cleared.');
console.log('Gen requests have been cleared by ' + user.name);
},
    };*/
<commit_msg>Add filters for inap links and add additional protocol for linking legitimate gen reqs<commit_after>'use strict';

const fs = require('fs');
const path = require('path');

const requestsFile = path.resolve(__dirname, '../config/chat-plugins/genrequests.json');

//const permittedGenners = ['desokoro', 'lombres']
//const permittedGennersByNames = ['Desokoro', 'Lombres']

let genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};
try {
	genRequests = require(requestsFile);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND') throw e;
}

if (!(genRequests || typeof genRequests === 'object')) genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};

function writeGenRequests() {
	fs.writeFileSync(requestsFile, JSON.stringify(genRequests));
}

exports.commands = {
	genreq: function (target, room, user) {
		if (genRequests.blacklist.includes(user.userid)) return false;
		if (user.locked || !user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
		if (!target) return this.errorReply("Please specify something for the gen request.");
		if (target.includes("pornhub" || "xvideos" || "xnxx") return this.errorReply('You are not permitted to link those things.');
				if (target.includes("http://" || ".com")) {
			target = '' + 'Gen Request' + '';
		}
		genRequests.requests.push({username: user.name, request: target, time: new Date().toUTCString()});
		writeGenRequests();
		this.sendReply("Your gen request was successfully added to the queue.");
	},

	reqview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.requests.length) return this.errorReply('There are no current genning requests.');
		let output = `There are <b>${genRequests.requests.length}</b> users who requested genning:<br />`;
		for (let i = 0; i < genRequests.requests.length; i++) {
			output += `<b>${genRequests.requests[i].username}</b>: ${genRequests.requests[i].request} (${genRequests.requests[i].time}).<br />`;
		}
		this.sendReplyBox(output);
	},

        gbl: 'genblacklist',
	genblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply('Please specify a target.');
		let blacklisted = toId(target);
		if (genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is already present on the genning blacklist.`);
		genRequests.blacklist.push(blacklisted);
		writeGenRequests();
		this.sendReply(`${target} was added to the genning blacklist.`);
		// Notify the user that they were blacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were added to the genning blacklist by ${user.name}. If you feel this is unfair, please PM an administrator (~) or the user who blacklisted you.`);
	},

        gwl: 'genunblacklist',
        genwhitelist: 'genunblacklist',
	genunblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply("Please specify a target.");
		let blacklisted = toId(target);
		if (!genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is currently not on the genning blacklist.`);
		genRequests.blacklist.splice(genRequests.blacklist.indexOf(blacklisted), 1);
		writeGenRequests();
		this.sendReply(`${target} was removed from the genning blacklist.`);
		// Notify the user that they were unblacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were removed from the genning blacklist by ${user.name}.`);
	},

        vbl: 'blacklistview',
        blv: 'blacklistview',
	blacklistview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.blacklist.length) return this.errorReply("There are currently no users on the genning blacklist.");
		let output = `There are <b>${genRequests.blacklist.length}</b> users on the genning blacklist:<br />`;
		for (let i = 0; i < genRequests.blacklist.length; i++) {
			output += `<i>${genRequests.blacklist[i]}</i><br />`;
		}
		this.sendReplyBox(output);
	},

        delreq: 'reqclear',
	reqclear: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!(target || target === 'force')) {
			this.errorReply("WARNING: This will reset all genning requests on the server.");
			this.errorReply("If you wish to continue, use /reqclear force.");
			return;
		}
		// Really lazy hack for doing this - just reset everything in genRequests.requests.
		genRequests.requests = [];
		writeGenRequests();
		this.sendReply("All genning requests were erased from the server.");
	},

	genguide: function (target, room, user) {
	this.sendReplyBox('
GENNING GUIDE

genreq (request): Requests a gen for those who can gen and are permitted by Tsunami to do so

viewgenners: View eligible genners

reportgenner: Reports a genner to Desokoro; use only if absolutely needed

More commands available to all users will be listed here in the future
');
	},

	staffgenguide: function (target, room, user) {
	if (!genRequests.permittedGenners.includes(user.userid) || !genRequests.permittedGennersByNames.includes(user.name)) return this.errorReply('You are not permitted to view this.');
	this.sendReplyBox('
GENNING RESPONSE GUIDE

reqclear: Clears all requests

vbl: Views all blacklisted users

gbl: Blacklists a user.

gwl: Un-blacklists a user
');
	},

	genneradd: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.')
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' could not be found. Please check your spelling!');
		if (genRequests.permittedGenners.includes(targetUser.userid) || genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply(`${target} is already present on the permitted genners list.`);
		genRequests.permittedGenners.push(targetUser.userid);
		genRequests.permittedGennersByNames.push(targetUser.name);
		writeGenRequests();
	this.sendReply('You have successfully added ' + targetUser.name + ' to the permitted genners list!');
	console.log(targetUser.name + ' was added to the permitted genners list by ' + user.name + '.');
	},

	removegenner: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.');
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' was not found. Check your spelling!');
	if (!genRequests.permittedGenners.includes(targetUser.userid) || !genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply('The target ' + target + ' is not on the permitted genners list.');
		genRequests.permittedGenners.splice(genRequests.permittedGenners.indexOf(targetUser.userid), 1);
		genRequests.permittedGennersByNames.splice(genRequests.permittedGennersByNames.indexOf(targetUser.name), 1);
		writeGenRequests();
	this.sendReply(target + ' was successfully removed from the permitted genners list.');
	console.log(target + ' was removed from the genners list by ' + user.name);
	},

	viewgenners: function (target, room, user) {
	for (let i = 0; i <  genRequests.permittedGennersByNames.length; i++) { this.sendReplyBox(genRequests.permittedGennersByNames[i]);   }
	},

	reportgenner: function (target, room, user) {
	//let CaseSensitiveArray = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
	if (genRequests.blacklist.includes(user.userid)) return this.errorReply('You are not allowed to partake in any genning services.');
	if (user.canTalk) return this.errorReply('You are currently unable to be trusted due to your disciplinary status; your report will not be accepted.');
	if (!user.autoconfirmed) return this.errorReply('You are not autoconfirmed and your report will not be accepted.');
	if (!target) return this.errorReply('Please specify a target.');
	if (!genRequests.permittedGenners.includes(target) && !genRequests.permittedGennersByNames.includes(target)) return this.errorReply('The user you have reported is not a valid genner.');
	if (target === 'desokoro' || target === 'Desokoro') return this.errorReply('Reporting the owner of the server to himself won\'t do you much good...');
	//if (CaseSensitiveArray.includes(target)) this.errorReply('Only lowercase letters and numbers can be used to report a genner.');
	this.parse('/tell Desokoro, TOKEN OF AUTHENTICITY: ' + user.name + '|' + Math.floor(Math.random() * 20) + '|' +  + Math.floor(Math.random() * 20) + '|' + Math.floor(Math.random() * 20) + '. Reporting genner ' + target + ' for misconduct.');
	},

	gensyscredits: function (target, room, user, connection) {
	this.sendReplyBox('Thank ' + '' + Chat.escapeHTML('Mystifi') + '' + ' for essentially building the framework for the genning request system!. The system is maintained by ' + '' + Chat.escapeHTML('Desokoro') + '' + '.');
	},
};

/*'use strict';

let GenReqArray = []

exports.commands = {
genreq: function (target, room, user) {
if (user.isBlacklisted === true) return this.errorReply('You are blacklisted.');
if (user.locked) return this.errorReply('You do not have adequate permissions to request a gen.');
if (!user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
//if (GenReqArray.length === 0) {
GenReqArray.push(user.userid);
//}
},

reqview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('Only Desokoro is permitted to use this.');
if (GenReqArray.length === 0) return this.errorReply('Nobody has requested a gen.');
for (let i = 0; i <  GenReqArray.length; i++) { this.sendReplyBox(GenReqArray[i]);   }
},

genblacklist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.errorReply(targetUser.username + ' is already blacklisted.');
targetUser.isBlacklisted = true;
this.sendReply(targetUser + ' is now blacklisted.');
},

genwhitelist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === false) return this.errorReply(targetUser.username + ' is not blacklisted.');
targetUser.isBlacklisted = false;
this.sendReply(targetUser + ' is no longer blacklisted.');
},

blacklistview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) this.errorReply (target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.sendReply('This user is blacklisted.');
else return this.sendReply('This user is not blacklisted.');
},

reqclear: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
GenReqArray = []
    this.sendReply('All requests have been cleared.');
console.log('Gen requests have been cleared by ' + user.name);
},
    };*/
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');

const requestsFile = path.resolve(__dirname, '../config/chat-plugins/genrequests.json');

//const permittedGenners = ['desokoro', 'lombres']
//const permittedGennersByNames = ['Desokoro', 'Lombres']

let genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};
try {
	genRequests = require(requestsFile);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND') throw e;
}

if (!(genRequests || typeof genRequests === 'object')) genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};

function writeGenRequests() {
	fs.writeFileSync(requestsFile, JSON.stringify(genRequests));
}

exports.commands = {
	genreq: function (target, room, user) {
		if (genRequests.blacklist.includes(user.userid)) return false;
		if (user.locked || !user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
		if (!target) return this.errorReply("Please specify something for the gen request.");
		genRequests.requests.push({username: user.name, request: target, time: new Date().toUTCString()});
		writeGenRequests();
		this.sendReply("Your gen request was successfully added to the queue.");
	},

	reqview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.requests.length) return this.errorReply('There are no current genning requests.');
		let output = `There are <b>${genRequests.requests.length}</b> users who requested genning:<br />`;
		for (let i = 0; i < genRequests.requests.length; i++) {
			output += `<b>${genRequests.requests[i].username}</b>: ${genRequests.requests[i].request} (${genRequests.requests[i].time}).</br>`;
		}
		this.sendReplyBox(output);
	},

        gbl: 'genblacklist',
	genblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply('Please specify a target.');
		let blacklisted = toId(target);
		if (genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is already present on the genning blacklist.`);
		genRequests.blacklist.push(blacklisted);
		writeGenRequests();
		this.sendReply(`${target} was added to the genning blacklist.`);
		// Notify the user that they were blacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were added to the genning blacklist by ${user.name}. If you feel this is unfair, please PM an administrator (~) or the user who blacklisted you.`);
	},

        gwl: 'genunblacklist',
        genwhitelist: 'genunblacklist',
	genunblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply("Please specify a target.");
		let blacklisted = toId(target);
		if (!genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is currently not on the genning blacklist.`);
		genRequests.blacklist.splice(genRequests.blacklist.indexOf(blacklisted), 1);
		writeGenRequests();
		this.sendReply(`${target} was removed from the genning blacklist.`);
		// Notify the user that they were unblacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were removed from the genning blacklist by ${user.name}.`);
	},

        vbl: 'blacklistview',
        blv: 'blacklistview',
	blacklistview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.blacklist.length) return this.errorReply("There are currently no users on the genning blacklist.");
		let output = `There are <b>${genRequests.blacklist.length}</b> users on the genning blacklist:<br />`;
		for (let i = 0; i < genRequests.blacklist.length; i++) {
			output += `<i>${genRequests.blacklist[i]}</i><br />`;
		}
		this.sendReplyBox(output);
	},

        delreq: 'reqclear',
	reqclear: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!(target || target === 'force')) {
			this.errorReply("WARNING: This will reset all genning requests on the server.");
			this.errorReply("If you wish to continue, use /reqclear force.");
			return;
		}
		// Really lazy hack for doing this - just reset everything in genRequests.requests.
		genRequests.requests = [];
		writeGenRequests();
		this.sendReply("All genning requests were erased from the server.");
	},

	genguide: function (target, room, user) {
	this.sendReplyBox('
GENNING GUIDE

genreq (request): Requests a gen for those who can gen and are permitted by Tsunami to do so

viewgenners: View eligible genners

reportgenner: Reports a genner to Desokoro; use only if absolutely needed

More commands available to all users will be listed here in the future
');
	},

	staffgenguide: function (target, room, user) {
	if (!permittedGenners.includes(user.userid)) return this.errorReply('You are not permitted to view this.');
	this.sendReplyBox('
GENNING RESPONSE GUIDE

reqclear: Clears all requests

vbl: Views all blacklisted users

gbl: Blacklists a user.

gwl: Un-blacklists a user
');
	},

	genneradd: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.')
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' could not be found. Please check your spelling!');
		if (genRequests.permittedGenners.includes(targetUser.userid) || genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply(`${target} is already present on the permitted genners list.`);
		genRequests.permittedGenners.push(targetUser.userid);
		genRequests.permittedGennersByNames.push(targetUser.name);
		writeGenRequests();
	this.sendReply('You have successfully added ' + targetUser.name + ' to the permitted genners list!');
	console.log(targetUser.name + ' was added to the permitted genners list by ' + user.name + '.');
	},

	removegenner: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.');
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' was not found. Check your spelling!');
	if (!genRequests.permittedGenners.includes(targetUser.userid) || !genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply('The target ' + target + ' is not on the permitted genners list.');
		genRequests.permittedGenners.splice(genRequests.permittedGenners.indexOf(targetUser.userid), 1);
		genRequests.permittedGennersByNames.splice(genRequests.permittedGennersByNames.indexOf(targetUser.name), 1);
		writeGenRequests();
	this.sendReply(target + ' was successfully removed from the permitted genners list.');
	console.log(target + ' was removed from the genners list by ' + user.name);
	},

	viewgenners: function (target, room, user) {
	for (let i = 0; i <  genRequests.permittedGennersByNames.length; i++) { this.sendReplyBox(genRequests.permittedGennersByNames[i]);   }
	},

	reportgenner: function (target, room, user) {
	//let CaseSensitiveArray = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
	if (genRequests.blacklist.includes(user.userid)) return this.errorReply('You are not allowed to partake in any genning services.');
	if (user.canTalk) return this.errorReply('You are currently unable to be trusted due to your disciplinary status; your report will not be accepted.');
	if (!user.autoconfirmed) return this.errorReply('You are not autoconfirmed and your report will not be accepted.');
	if (!target) return this.errorReply('Please specify a target.');
	if (!genRequests.permittedGenners.includes(target) && !genRequests.permittedGennersByNames.includes(target)) return this.errorReply('The user you have reported is not a valid genner.');
	if (target === 'desokoro') return this.errorReply('Reporting the owner of the server to himself won\'t do you much good...');
	//if (CaseSensitiveArray.includes(target)) this.errorReply('Only lowercase letters and numbers can be used to report a genner.');
	this.parse('/tell Desokoro, TOKEN OF AUTHENTICITY: ' + user.name + '|' + Math.floor(Math.random() * 20) + '|' +  + Math.floor(Math.random() * 20) + '|' + Math.floor(Math.random() * 20) + '. Reporting genner ' + target + ' for misconduct.');
	},

	gensyscredits: function (target, room, user, connection) {
	this.sendReplyBox('Thank ' + '' + Chat.escapeHTML('Mystifi') + '' + ' for essentially building the framework for the genning request system!. The system is maintained by ' + '' + Chat.escapeHTML('Desokoro') + '' + '.');
	},
};

/*'use strict';

let GenReqArray = []

exports.commands = {
genreq: function (target, room, user) {
if (user.isBlacklisted === true) return this.errorReply('You are blacklisted.');
if (user.locked) return this.errorReply('You do not have adequate permissions to request a gen.');
if (!user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
//if (GenReqArray.length === 0) {
GenReqArray.push(user.userid);
//}
},

reqview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('Only Desokoro is permitted to use this.');
if (GenReqArray.length === 0) return this.errorReply('Nobody has requested a gen.');
for (let i = 0; i <  GenReqArray.length; i++) { this.sendReplyBox(GenReqArray[i]);   }
},

genblacklist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.errorReply(targetUser.username + ' is already blacklisted.');
targetUser.isBlacklisted = true;
this.sendReply(targetUser + ' is now blacklisted.');
},

genwhitelist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === false) return this.errorReply(targetUser.username + ' is not blacklisted.');
targetUser.isBlacklisted = false;
this.sendReply(targetUser + ' is no longer blacklisted.');
},

blacklistview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) this.errorReply (target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.sendReply('This user is blacklisted.');
else return this.sendReply('This user is not blacklisted.');
},

reqclear: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
GenReqArray = []
    this.sendReply('All requests have been cleared.');
console.log('Gen requests have been cleared by ' + user.name);
},
    };*/
<commit_msg>Fix HTML syntax<commit_after>'use strict';

const fs = require('fs');
const path = require('path');

const requestsFile = path.resolve(__dirname, '../config/chat-plugins/genrequests.json');

//const permittedGenners = ['desokoro', 'lombres']
//const permittedGennersByNames = ['Desokoro', 'Lombres']

let genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};
try {
	genRequests = require(requestsFile);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND') throw e;
}

if (!(genRequests || typeof genRequests === 'object')) genRequests = {requests: [], blacklist: [], permittedGenners: [], permittedGennersByNames: []};

function writeGenRequests() {
	fs.writeFileSync(requestsFile, JSON.stringify(genRequests));
}

exports.commands = {
	genreq: function (target, room, user) {
		if (genRequests.blacklist.includes(user.userid)) return false;
		if (user.locked || !user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
		if (!target) return this.errorReply("Please specify something for the gen request.");
		genRequests.requests.push({username: user.name, request: target, time: new Date().toUTCString()});
		writeGenRequests();
		this.sendReply("Your gen request was successfully added to the queue.");
	},

	reqview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.requests.length) return this.errorReply('There are no current genning requests.');
		let output = `There are <b>${genRequests.requests.length}</b> users who requested genning:<br />`;
		for (let i = 0; i < genRequests.requests.length; i++) {
			output += `<b>${genRequests.requests[i].username}</b>: ${genRequests.requests[i].request} (${genRequests.requests[i].time}).<br />`;
		}
		this.sendReplyBox(output);
	},

        gbl: 'genblacklist',
	genblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply('Please specify a target.');
		let blacklisted = toId(target);
		if (genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is already present on the genning blacklist.`);
		genRequests.blacklist.push(blacklisted);
		writeGenRequests();
		this.sendReply(`${target} was added to the genning blacklist.`);
		// Notify the user that they were blacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were added to the genning blacklist by ${user.name}. If you feel this is unfair, please PM an administrator (~) or the user who blacklisted you.`);
	},

        gwl: 'genunblacklist',
        genwhitelist: 'genunblacklist',
	genunblacklist: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!target) return this.errorReply("Please specify a target.");
		let blacklisted = toId(target);
		if (!genRequests.blacklist.includes(blacklisted)) return this.errorReply(`${target} is currently not on the genning blacklist.`);
		genRequests.blacklist.splice(genRequests.blacklist.indexOf(blacklisted), 1);
		writeGenRequests();
		this.sendReply(`${target} was removed from the genning blacklist.`);
		// Notify the user that they were unblacklisted, if they are online.
		if (Users(blacklisted)) Users(blacklisted).popup(`You were removed from the genning blacklist by ${user.name}.`);
	},

        vbl: 'blacklistview',
        blv: 'blacklistview',
	blacklistview: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!genRequests.blacklist.length) return this.errorReply("There are currently no users on the genning blacklist.");
		let output = `There are <b>${genRequests.blacklist.length}</b> users on the genning blacklist:<br />`;
		for (let i = 0; i < genRequests.blacklist.length; i++) {
			output += `<i>${genRequests.blacklist[i]}</i><br />`;
		}
		this.sendReplyBox(output);
	},

        delreq: 'reqclear',
	reqclear: function (target, room, user) {
                if (user.userid !== 'desokoro') return this.errorReply('You aren\'t permitted to use this command.');
		//if (!this.can('hotpatch')) return false;
		if (!(target || target === 'force')) {
			this.errorReply("WARNING: This will reset all genning requests on the server.");
			this.errorReply("If you wish to continue, use /reqclear force.");
			return;
		}
		// Really lazy hack for doing this - just reset everything in genRequests.requests.
		genRequests.requests = [];
		writeGenRequests();
		this.sendReply("All genning requests were erased from the server.");
	},

	genguide: function (target, room, user) {
	this.sendReplyBox('
GENNING GUIDE

genreq (request): Requests a gen for those who can gen and are permitted by Tsunami to do so

viewgenners: View eligible genners

reportgenner: Reports a genner to Desokoro; use only if absolutely needed

More commands available to all users will be listed here in the future
');
	},

	staffgenguide: function (target, room, user) {
	if (!permittedGenners.includes(user.userid)) return this.errorReply('You are not permitted to view this.');
	this.sendReplyBox('
GENNING RESPONSE GUIDE

reqclear: Clears all requests

vbl: Views all blacklisted users

gbl: Blacklists a user.

gwl: Un-blacklists a user
');
	},

	genneradd: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.')
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' could not be found. Please check your spelling!');
		if (genRequests.permittedGenners.includes(targetUser.userid) || genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply(`${target} is already present on the permitted genners list.`);
		genRequests.permittedGenners.push(targetUser.userid);
		genRequests.permittedGennersByNames.push(targetUser.name);
		writeGenRequests();
	this.sendReply('You have successfully added ' + targetUser.name + ' to the permitted genners list!');
	console.log(targetUser.name + ' was added to the permitted genners list by ' + user.name + '.');
	},

	removegenner: function (target, room, user) {
	if (user.userid !== 'desokoro') return this.errorReply('You are not permitted to use this command.');
	if (!target) return this.errorReply('Please specify a target.');
	let targetUser = Users(toId(target));
	if (!targetUser) return this.errorReply('The target user ' + target + ' was not found. Check your spelling!');
	if (!genRequests.permittedGenners.includes(targetUser.userid) || !genRequests.permittedGennersByNames.includes(targetUser.name)) return this.errorReply('The target ' + target + ' is not on the permitted genners list.');
		genRequests.permittedGenners.splice(genRequests.permittedGenners.indexOf(targetUser.userid), 1);
		genRequests.permittedGennersByNames.splice(genRequests.permittedGennersByNames.indexOf(targetUser.name), 1);
		writeGenRequests();
	this.sendReply(target + ' was successfully removed from the permitted genners list.');
	console.log(target + ' was removed from the genners list by ' + user.name);
	},

	viewgenners: function (target, room, user) {
	for (let i = 0; i <  genRequests.permittedGennersByNames.length; i++) { this.sendReplyBox(genRequests.permittedGennersByNames[i]);   }
	},

	reportgenner: function (target, room, user) {
	//let CaseSensitiveArray = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
	if (genRequests.blacklist.includes(user.userid)) return this.errorReply('You are not allowed to partake in any genning services.');
	if (user.canTalk) return this.errorReply('You are currently unable to be trusted due to your disciplinary status; your report will not be accepted.');
	if (!user.autoconfirmed) return this.errorReply('You are not autoconfirmed and your report will not be accepted.');
	if (!target) return this.errorReply('Please specify a target.');
	if (!genRequests.permittedGenners.includes(target) && !genRequests.permittedGennersByNames.includes(target)) return this.errorReply('The user you have reported is not a valid genner.');
	if (target === 'desokoro') return this.errorReply('Reporting the owner of the server to himself won\'t do you much good...');
	//if (CaseSensitiveArray.includes(target)) this.errorReply('Only lowercase letters and numbers can be used to report a genner.');
	this.parse('/tell Desokoro, TOKEN OF AUTHENTICITY: ' + user.name + '|' + Math.floor(Math.random() * 20) + '|' +  + Math.floor(Math.random() * 20) + '|' + Math.floor(Math.random() * 20) + '. Reporting genner ' + target + ' for misconduct.');
	},

	gensyscredits: function (target, room, user, connection) {
	this.sendReplyBox('Thank ' + '' + Chat.escapeHTML('Mystifi') + '' + ' for essentially building the framework for the genning request system!. The system is maintained by ' + '' + Chat.escapeHTML('Desokoro') + '' + '.');
	},
};

/*'use strict';

let GenReqArray = []

exports.commands = {
genreq: function (target, room, user) {
if (user.isBlacklisted === true) return this.errorReply('You are blacklisted.');
if (user.locked) return this.errorReply('You do not have adequate permissions to request a gen.');
if (!user.autoconfirmed) return this.errorReply('You do not have adequate permissions to request a gen.');
//if (GenReqArray.length === 0) {
GenReqArray.push(user.userid);
//}
},

reqview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('Only Desokoro is permitted to use this.');
if (GenReqArray.length === 0) return this.errorReply('Nobody has requested a gen.');
for (let i = 0; i <  GenReqArray.length; i++) { this.sendReplyBox(GenReqArray[i]);   }
},

genblacklist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.errorReply(targetUser.username + ' is already blacklisted.');
targetUser.isBlacklisted = true;
this.sendReply(targetUser + ' is now blacklisted.');
},

genwhitelist: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) return this.errorReply(target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === false) return this.errorReply(targetUser.username + ' is not blacklisted.');
targetUser.isBlacklisted = false;
this.sendReply(targetUser + ' is no longer blacklisted.');
},

blacklistview: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
if (!target) return this.errorReply('Please specify a target.');
let targetUser = Users(toId(target));
if (!targetUser) this.errorReply (target + ' could not be found. Check your spelling.');
if (targetUser.isBlacklisted === true) return this.sendReply('This user is blacklisted.');
else return this.sendReply('This user is not blacklisted.');
},

reqclear: function (target, room, user) {
if (user.userid !== 'desokoro') return this.errorReply('You lack the permissions to use this.');
GenReqArray = []
    this.sendReply('All requests have been cleared.');
console.log('Gen requests have been cleared by ' + user.name);
},
    };*/
<|endoftext|>


<commit_before>/* eslint-disable import/prefer-default-export */
/* eslint-disable import/no-extraneous-dependencies */

import 'vtk.js/Sources/favicon';
import JSZip from 'jszip';

import macro from 'vtk.js/Sources/macro';

import HttpDataAccessHelper from 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper';
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkURLExtract from 'vtk.js/Sources/Common/Core/URLExtract';

import vtkOBJReader from 'vtk.js/Sources/IO/Misc/OBJReader';
import vtkMTLReader from 'vtk.js/Sources/IO/Misc/MTLReader';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';

import style from './OBJViewer.module.css';

const iOS = /iPad|iPhone|iPod/.test(window.navigator.platform);
let autoInit = true;

// Add class to body if iOS device --------------------------------------------

if (iOS) {
  document.querySelector('body').classList.add('is-ios-device');
}

function preventDefaults(e) {
  e.preventDefault();
  e.stopPropagation();
}

function emptyContainer(container) {
  while (container.firstChild) {
    container.removeChild(container.firstChild);
  }
}

function loadZipContent(zipContent, renderWindow, renderer) {
  const fileContents = { obj: {}, mtl: {}, img: {} };
  const zip = new JSZip();
  zip.loadAsync(zipContent).then(() => {
    let workLoad = 0;

    function done() {
      if (workLoad !== 0) {
        return;
      }
      // Attach images to MTLs
      Object.keys(fileContents.mtl).forEach((mtlFilePath) => {
        const mtlReader = fileContents.mtl[mtlFilePath];
        const basePath = mtlFilePath
          .split('/')
          .filter((v, i, a) => i  {
          const key = `${basePath}/${relPath}`;
          const imgSRC = fileContents.img[key];
          if (imgSRC) {
            mtlReader.setImageSrc(relPath, imgSRC);
          }
        });
      });

      // Create pipeline from obj
      Object.keys(fileContents.obj).forEach((objFilePath) => {
        const mtlFilePath = objFilePath.replace(/\.obj$/, '.mtl');
        const objReader = fileContents.obj[objFilePath];
        const mtlReader = fileContents.mtl[mtlFilePath];

        const size = objReader.getNumberOfOutputPorts();
        for (let i = 0; i < size; i++) {
          const source = objReader.getOutputData(i);
          const mapper = vtkMapper.newInstance();
          const actor = vtkActor.newInstance();
          const name = source.get('name').name;

          actor.setMapper(mapper);
          mapper.setInputData(source);
          renderer.addActor(actor);

          if (mtlReader && name) {
            mtlReader.applyMaterialToActor(name, actor);
          }
        }
      });
      renderer.resetCamera();
      renderWindow.render();

      // Rerender with hopefully all the textures loaded
      setTimeout(renderWindow.render, 500);
    }

    zip.forEach((relativePath, zipEntry) => {
      if (relativePath.match(/\.obj$/i)) {
        workLoad++;
        zipEntry.async('string').then((txt) => {
          const reader = vtkOBJReader.newInstance({ splitMode: 'usemtl' });
          reader.parseAsText(txt);
          fileContents.obj[relativePath] = reader;
          workLoad--;
          done();
        });
      }
      if (relativePath.match(/\.mtl$/i)) {
        workLoad++;
        zipEntry.async('string').then((txt) => {
          const reader = vtkMTLReader.newInstance();
          reader.parseAsText(txt);
          fileContents.mtl[relativePath] = reader;
          workLoad--;
          done();
        });
      }
      if (relativePath.match(/\.jpg$/i) || relativePath.match(/\.png$/i)) {
        workLoad++;
        zipEntry.async('base64').then((txt) => {
          const ext = relativePath.slice(-3).toLowerCase();
          fileContents.img[relativePath] = `data:image/${ext};base64,${txt}`;
          workLoad--;
          done();
        });
      }
    });
  });
}

export function load(container, options) {
  autoInit = false;
  emptyContainer(container);

  const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
    background: [0, 0, 0],
    rootContainer: container,
    containerStyle: { height: '100%', width: '100%', position: 'absolute' },
  });
  const renderer = fullScreenRenderer.getRenderer();
  const renderWindow = fullScreenRenderer.getRenderWindow();

  if (options.file) {
    if (options.ext === 'obj') {
      const reader = new FileReader();
      reader.onload = function onLoad(e) {
        const objReader = vtkOBJReader.newInstance();
        objReader.parseAsText(reader.result);
        const nbOutputs = objReader.getNumberOfOutputPorts();
        for (let idx = 0; idx < nbOutputs; idx++) {
          const source = objReader.getOutputData(idx);
          const mapper = vtkMapper.newInstance();
          const actor = vtkActor.newInstance();
          actor.setMapper(mapper);
          mapper.setInputData(source);
          renderer.addActor(actor);
        }
        renderer.resetCamera();
        renderWindow.render();
      };
      reader.readAsText(options.file);
    } else {
      loadZipContent(options.file, renderWindow, renderer);
    }
  } else if (options.fileURL) {
    const progressContainer = document.createElement('div');
    progressContainer.setAttribute('class', style.progress);
    container.appendChild(progressContainer);

    const progressCallback = (progressEvent) => {
      if (progressEvent.lengthComputable) {
        const percent = Math.floor(
          (100 * progressEvent.loaded) / progressEvent.total
        );
        progressContainer.innerHTML = `Loading ${percent}%`;
      } else {
        progressContainer.innerHTML = macro.formatBytesToProperUnit(
          progressEvent.loaded
        );
      }
    };

    HttpDataAccessHelper.fetchBinary(options.fileURL, {
      progressCallback,
    }).then((content) => {
      container.removeChild(progressContainer);
      loadZipContent(content, renderWindow, renderer);
    });
  }
}

export function initLocalFileLoader(container) {
  const exampleContainer = document.querySelector('.content');
  const rootBody = document.querySelector('body');
  const myContainer = container || exampleContainer || rootBody;

  if (myContainer !== container) {
    myContainer.classList.add(style.fullScreen);
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  } else {
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  }

  const fileContainer = document.createElement('div');
  fileContainer.innerHTML = `
<input type="file" accept=".zip,.obj" style="display: none;"/>`;
  myContainer.appendChild(fileContainer);

  const fileInput = fileContainer.querySelector('input');

  function handleFile(e) {
    preventDefaults(e);
    const dataTransfer = e.dataTransfer;
    const files = e.target.files || dataTransfer.files;
    if (files.length === 1) {
      myContainer.removeChild(fileContainer);
      const ext = files[0].name.split('.').slice(-1)[0];
      load(myContainer, { file: files[0], ext });
    }
  }

  fileInput.addEventListener('change', handleFile);
  fileContainer.addEventListener('drop', handleFile);
  fileContainer.addEventListener('click', (e) => fileInput.click());
  fileContainer.addEventListener('dragover', preventDefaults);
}

// Look at URL an see if we should load a file
// ?fileURL=https://data.kitware.com/api/v1/item/59cdbb588d777f31ac63de08/download
const userParams = vtkURLExtract.extractURLParameters();

if (userParams.url || userParams.fileURL) {
  const exampleContainer = document.querySelector('.content');
  const rootBody = document.querySelector('body');
  const myContainer = exampleContainer || rootBody;
  if (myContainer) {
    myContainer.classList.add(style.fullScreen);
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  }
  load(myContainer, userParams);
}

// Auto setup if no method get called within 100ms
setTimeout(() => {
  if (autoInit) {
    initLocalFileLoader();
  }
}, 100);
<commit_msg>fix(OBJViewer): Add noInterpolation url argument<commit_after>/* eslint-disable import/prefer-default-export */
/* eslint-disable import/no-extraneous-dependencies */

import 'vtk.js/Sources/favicon';
import JSZip from 'jszip';

import macro from 'vtk.js/Sources/macro';

import HttpDataAccessHelper from 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper';
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkURLExtract from 'vtk.js/Sources/Common/Core/URLExtract';

import vtkOBJReader from 'vtk.js/Sources/IO/Misc/OBJReader';
import vtkMTLReader from 'vtk.js/Sources/IO/Misc/MTLReader';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';

import style from './OBJViewer.module.css';

const iOS = /iPad|iPhone|iPod/.test(window.navigator.platform);
let autoInit = true;

// Look at URL an see if we should load a file
// ?fileURL=https://data.kitware.com/api/v1/item/59cdbb588d777f31ac63de08/download
// &noInterpolation

const userParams = vtkURLExtract.extractURLParameters();

// Add class to body if iOS device --------------------------------------------

if (iOS) {
  document.querySelector('body').classList.add('is-ios-device');
}

function preventDefaults(e) {
  e.preventDefault();
  e.stopPropagation();
}

function emptyContainer(container) {
  while (container.firstChild) {
    container.removeChild(container.firstChild);
  }
}

function loadZipContent(zipContent, renderWindow, renderer) {
  const fileContents = { obj: {}, mtl: {}, img: {} };
  const zip = new JSZip();
  zip.loadAsync(zipContent).then(() => {
    let workLoad = 0;

    function done() {
      if (workLoad !== 0) {
        return;
      }

      // Attach images to MTLs
      const promises = [];
      Object.keys(fileContents.mtl).forEach((mtlFilePath) => {
        const mtlReader = fileContents.mtl[mtlFilePath];
        const basePath = mtlFilePath
          .split('/')
          .filter((v, i, a) => i  {
          const key = basePath.length ? `${basePath}/${relPath}` : relPath;
          const imgSRC = fileContents.img[key];
          if (imgSRC) {
            promises.push(mtlReader.setImageSrc(relPath, imgSRC));
            console.log('register promise');
          }
        });
      });

      Promise.all(promises).then(() => {
        console.log('load obj...');
        // Create pipeline from obj
        Object.keys(fileContents.obj).forEach((objFilePath) => {
          const mtlFilePath = objFilePath.replace(/\.obj$/, '.mtl');
          const objReader = fileContents.obj[objFilePath];
          const mtlReader = fileContents.mtl[mtlFilePath];

          const size = objReader.getNumberOfOutputPorts();
          for (let i = 0; i < size; i++) {
            const source = objReader.getOutputData(i);
            const mapper = vtkMapper.newInstance();
            const actor = vtkActor.newInstance();
            const name = source.get('name').name;

            actor.setMapper(mapper);
            mapper.setInputData(source);
            renderer.addActor(actor);

            if (mtlReader && name) {
              mtlReader.applyMaterialToActor(name, actor);
            }
          }
        });
        renderer.resetCamera();
        renderWindow.render();
      });
    }

    zip.forEach((relativePath, zipEntry) => {
      if (relativePath.match(/\.obj$/i)) {
        workLoad++;
        zipEntry.async('string').then((txt) => {
          const reader = vtkOBJReader.newInstance({ splitMode: 'usemtl' });
          reader.parseAsText(txt);
          fileContents.obj[relativePath] = reader;
          workLoad--;
          done();
        });
      }
      if (relativePath.match(/\.mtl$/i)) {
        workLoad++;
        zipEntry.async('string').then((txt) => {
          const reader = vtkMTLReader.newInstance({
            interpolateTextures: !userParams.noInterpolation,
          });
          reader.parseAsText(txt);
          fileContents.mtl[relativePath] = reader;
          workLoad--;
          done();
        });
      }
      if (relativePath.match(/\.jpg$/i) || relativePath.match(/\.png$/i)) {
        workLoad++;
        zipEntry.async('base64').then((txt) => {
          const ext = relativePath.slice(-3).toLowerCase();
          fileContents.img[relativePath] = `data:image/${ext};base64,${txt}`;
          workLoad--;
          done();
        });
      }
    });
  });
}

export function load(container, options) {
  autoInit = false;
  emptyContainer(container);

  const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
    background: [0, 0, 0],
    rootContainer: container,
    containerStyle: { height: '100%', width: '100%', position: 'absolute' },
  });
  const renderer = fullScreenRenderer.getRenderer();
  const renderWindow = fullScreenRenderer.getRenderWindow();

  if (options.file) {
    if (options.ext === 'obj') {
      const reader = new FileReader();
      reader.onload = function onLoad(e) {
        const objReader = vtkOBJReader.newInstance();
        objReader.parseAsText(reader.result);
        const nbOutputs = objReader.getNumberOfOutputPorts();
        for (let idx = 0; idx < nbOutputs; idx++) {
          const source = objReader.getOutputData(idx);
          const mapper = vtkMapper.newInstance();
          const actor = vtkActor.newInstance();
          actor.setMapper(mapper);
          mapper.setInputData(source);
          renderer.addActor(actor);
        }
        renderer.resetCamera();
        renderWindow.render();
      };
      reader.readAsText(options.file);
    } else {
      loadZipContent(options.file, renderWindow, renderer);
    }
  } else if (options.fileURL) {
    const progressContainer = document.createElement('div');
    progressContainer.setAttribute('class', style.progress);
    container.appendChild(progressContainer);

    const progressCallback = (progressEvent) => {
      if (progressEvent.lengthComputable) {
        const percent = Math.floor(
          (100 * progressEvent.loaded) / progressEvent.total
        );
        progressContainer.innerHTML = `Loading ${percent}%`;
      } else {
        progressContainer.innerHTML = macro.formatBytesToProperUnit(
          progressEvent.loaded
        );
      }
    };

    HttpDataAccessHelper.fetchBinary(options.fileURL, {
      progressCallback,
    }).then((content) => {
      container.removeChild(progressContainer);
      loadZipContent(content, renderWindow, renderer);
    });
  }
}

export function initLocalFileLoader(container) {
  const exampleContainer = document.querySelector('.content');
  const rootBody = document.querySelector('body');
  const myContainer = container || exampleContainer || rootBody;

  if (myContainer !== container) {
    myContainer.classList.add(style.fullScreen);
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  } else {
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  }

  const fileContainer = document.createElement('div');
  fileContainer.innerHTML = `
<input type="file" accept=".zip,.obj" style="display: none;"/>`;
  myContainer.appendChild(fileContainer);

  const fileInput = fileContainer.querySelector('input');

  function handleFile(e) {
    preventDefaults(e);
    const dataTransfer = e.dataTransfer;
    const files = e.target.files || dataTransfer.files;
    if (files.length === 1) {
      myContainer.removeChild(fileContainer);
      const ext = files[0].name.split('.').slice(-1)[0];
      load(myContainer, { file: files[0], ext });
    }
  }

  fileInput.addEventListener('change', handleFile);
  fileContainer.addEventListener('drop', handleFile);
  fileContainer.addEventListener('click', (e) => fileInput.click());
  fileContainer.addEventListener('dragover', preventDefaults);
}

if (userParams.url || userParams.fileURL) {
  const exampleContainer = document.querySelector('.content');
  const rootBody = document.querySelector('body');
  const myContainer = exampleContainer || rootBody;
  if (myContainer) {
    myContainer.classList.add(style.fullScreen);
    rootBody.style.margin = '0';
    rootBody.style.padding = '0';
  }
  load(myContainer, userParams);
}

// Auto setup if no method get called within 100ms
setTimeout(() => {
  if (autoInit) {
    initLocalFileLoader();
  }
}, 100);
<|endoftext|>


<commit_before>var FaviconBar = {};

FaviconBar.renderLinks = function(links){
	var row = document.getElementById("linksTableRow");
	row.innerHTML = "";
	links.map(function(l){
		if(l && l.length > 0){
			row.innerHTML += FaviconBar.renderLinkHtml(l.trim());
		}
	});
}

FaviconBar.applyCentering = function(centerBar){
	var row = document.getElementById("linksTable");
	if(centerBar){
		row.classList.add("centerBar");
	}
	else{
		row.classList.remove("centerBar");
	}
}

FaviconBar.renderLinkHtml = function(link){
	return "" +
		"" +
			"" +
		"" +
	"	";
}

FaviconBar.onLoad = function(){
	// alert("onLoad fired");
	var links = safari.extension.settings.links.split(";");
	var centerBar = safari.extension.settings.centerBar;
	FaviconBar.applyCentering(centerBar);
	FaviconBar.renderLinks(links);
}

FaviconBar.settingsChanged = function(event){
	console.log("Settings changed. Details: " + JSON.stringify(event));
	if(event.key == "links") {
		FaviconBar.onLoad();
	}
	else if(event.key == "centerBar") {
		FaviconBar.applyCentering(event.newValue);
	}
	else if(event.key == "settingsCheckbox") {
		// safari.extension.settings.settingsCheckbox = false;
		console.log("Go to settings page");
		safari.application.activeBrowserWindow.openTab().url = safari.extension.baseURI + "settings.html";
	}
}

FaviconBar.swapElems = function(){
	childNode[4].parentNode.insertBefore(childNode[4], childNode[3]);
}

FaviconBar.linkIsNotDupe = function(link){
	// check for duplicates here
	return safari.extension.settings.links.indexOf(link) === -1;
}

FaviconBar.addNewLink = function(link){
	if(link && FaviconBar.linkIsNotDupe(link)){
		safari.extension.settings.links += ";" + link;
	}
}

FaviconBar.onLinkMouseover = function(elem, event){
	console.log("In");
}

FaviconBar.onLinkMouseleave = function(elem, event){
	console.log("Out");
}

FaviconBar.onBarDragenter = function(elem, event) {
	event.preventDefault();
	return true;
}

FaviconBar.onBarDragover = function(elem, event) {
	if (!event.dataTransfer) {
		return false;
	}
	event.dataTransfer.dropEffect = "copy";
	event.preventDefault();
	return true;
}

FaviconBar.onBarDrop = function(elem, event) {
	if(!event.dataTransfer){
		return false;
	}
	var link = event.dataTransfer.getData("Text");
	FaviconBar.addNewLink(link);
	return true;
}

safari.extension.settings.addEventListener("change", FaviconBar.settingsChanged, false);<commit_msg>Removed unused functions<commit_after>var FaviconBar = {};

FaviconBar.renderLinks = function(links){
	var row = document.getElementById("linksTableRow");
	row.innerHTML = "";
	links.map(function(l){
		if(l && l.length > 0){
			row.innerHTML += FaviconBar.renderLinkHtml(l.trim());
		}
	});
}

FaviconBar.applyCentering = function(centerBar){
	var row = document.getElementById("linksTable");
	if(centerBar){
		row.classList.add("centerBar");
	}
	else{
		row.classList.remove("centerBar");
	}
}

FaviconBar.renderLinkHtml = function(link){
	return "" +
		"" +
			"" +
		"" +
	"	";
}

FaviconBar.onLoad = function(){
	// alert("onLoad fired");
	var links = safari.extension.settings.links.split(";");
	var centerBar = safari.extension.settings.centerBar;
	FaviconBar.applyCentering(centerBar);
	FaviconBar.renderLinks(links);
}

FaviconBar.settingsChanged = function(event){
	console.log("Settings changed. Details: " + JSON.stringify(event));
	if(event.key == "links") {
		FaviconBar.onLoad();
	}
	else if(event.key == "centerBar") {
		FaviconBar.applyCentering(event.newValue);
	}
	else if(event.key == "settingsCheckbox") {
		// safari.extension.settings.settingsCheckbox = false;
		console.log("Go to settings page");
		safari.application.activeBrowserWindow.openTab().url = safari.extension.baseURI + "settings.html";
	}
}

FaviconBar.linkIsNotDupe = function(link){
	// check for duplicates here
	return safari.extension.settings.links.indexOf(link) === -1;
}

FaviconBar.addNewLink = function(link){
	if(link && FaviconBar.linkIsNotDupe(link)){
		safari.extension.settings.links += ";" + link;
	}
}

FaviconBar.onBarDragenter = function(elem, event) {
	event.preventDefault();
	return true;
}

FaviconBar.onBarDragover = function(elem, event) {
	if (!event.dataTransfer) {
		return false;
	}
	event.dataTransfer.dropEffect = "copy";
	event.preventDefault();
	return true;
}

FaviconBar.onBarDrop = function(elem, event) {
	if(!event.dataTransfer){
		return false;
	}
	var link = event.dataTransfer.getData("Text");
	FaviconBar.addNewLink(link);
	return true;
}

safari.extension.settings.addEventListener("change", FaviconBar.settingsChanged, false);<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {Link} from 'react-router';
import DeleteRecipe from './DeleteRecipe'

export default class ShowRecipes extends Component {

  constructor(props) {
    super(props);
    this.state = {recipes: []};
  }

  componentDidMount() {
    var componentPointer =  this;
    axios.get("http://localhost:8080/Pluto/meta/recipes").
    then(function (response) {
      componentPointer.setState({recipes: response.data});
    }).catch(function (error) {
      console.log(error);
    })
  }

  render() {
    return (

Hauptmenü

<Link to="/">Startseite</Link>

<Link to="/laundry/alert" >Wäschealarm erstellen</Link>

<Link to="/laundry/icons" >Wäscheinfo anzeigen</Link>

<Link to="/recipes">Rezepte anzeigen</Link>

<Link to="/recipes/create">Rezept erstellen</Link>

<Link to="/recipes/create">Rezept suchen</Link>

Rezepte

              {this.state.recipes.map(function(recipe) {
                return (

{recipe.title} ({recipe.id})

Von {recipe.eMail}

Zutaten:

                    {recipe.ingredients.map(function(ingredient) {
                      return (

{ingredient.name}: {ingredient.amount}

                      )
                    })}

Zubereitung:

{recipe.text}

                    <button onClick={() => {DeleteRecipe.deleteRecipe(recipe.id)}} className="negative ui button">
                      Löschen
                    </button>

                );
              })}

    )
  }
}
<commit_msg>Change path from create to search<commit_after>import React, {Component} from 'react';
import {Link} from 'react-router';
import DeleteRecipe from './DeleteRecipe'

export default class ShowRecipes extends Component {

  constructor(props) {
    super(props);
    this.state = {recipes: []};
  }

  componentDidMount() {
    var componentPointer =  this;
    axios.get("http://localhost:8080/Pluto/meta/recipes").
    then(function (response) {
      componentPointer.setState({recipes: response.data});
    }).catch(function (error) {
      console.log(error);
    })
  }

  render() {
    return (

Hauptmenü

<Link to="/">Startseite</Link>

<Link to="/laundry/alert" >Wäschealarm erstellen</Link>

<Link to="/laundry/icons" >Wäscheinfo anzeigen</Link>

<Link to="/recipes">Rezepte anzeigen</Link>

<Link to="/recipes/create">Rezept erstellen</Link>

<Link to="/recipes/show">Rezept suchen</Link>

Rezepte

              {this.state.recipes.map(function(recipe) {
                return (

{recipe.title} ({recipe.id})

Von {recipe.eMail}

Zutaten:

                    {recipe.ingredients.map(function(ingredient) {
                      return (

{ingredient.name}: {ingredient.amount}

                      )
                    })}

Zubereitung:

{recipe.text}

                    <button onClick={() => {DeleteRecipe.deleteRecipe(recipe.id)}} className="negative ui button">
                      Löschen
                    </button>

                );
              })}

    )
  }
}
<|endoftext|>


<commit_before>'use strict';

/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

goog.provide('tachyfont.SparseBitArray');

goog.require('goog.asserts');

goog.scope(function() {

/**
 * This class provides a sparse bit array.
 *
 * The bit array is made up of 'pages'. The bit array is sparse because only
 * pages with set bits are allocated. Each page uses an array of bytes to cover
 * a continous range of bits.
 * @constructor @struct @final
 */
tachyfont.SparseBitArray = function() {
  /** @private {!Object<number, !Uint8Array>} */
  this.pages_ = {};

  /**
   * TODO(bstell): if no errors reporting then delete this after 2016-10-01.
   *
   * For testing make an alternate recording of the bits.
   * This is used to verify the correct operation of the sparse bit array.
   * Note: Storing info this way uses a large amount of memory; eg,20K entries
   * can take 1.5MB.
   * @private {!Object<number, boolean>}
   */
  this.alternateBitInfo_ = {};

  /**
   * For testing record the number of page allocations.
   * @private {number}
   */
  this.numberOfPageAllocations_ = 0;
};
var SparseBitArray = tachyfont.SparseBitArray;

/**
 * The amount to shift to get the page index.
 */
SparseBitArray.PAGE_SHIFT = 8;

/**
 * The amount to shift to get the page index.
 */
SparseBitArray.PAGE_MASK = 0xFF;

/**
 * The number of bytes in a page.
 */
SparseBitArray.BYTES_PER_PAGE = 32;

/**
 * The number of bytes in a page.
 */
SparseBitArray.BITS_PER_BYTE = 8;

/**
 * The amount to shift to get the byte index.
 */
SparseBitArray.BYTE_SHIFT = 3;

/**
 * The amount to shift to get the byte index.
 */
SparseBitArray.BYTE_MASK = 0x7;

/**
 * Sets the bit at index.
 * @param {number} index The bit's index.
 */
SparseBitArray.prototype.setBit = function(index) {
  var pageIndex = index >> SparseBitArray.PAGE_SHIFT;
  var pageBitArray = this.pages_[pageIndex];
  if (!pageBitArray) {
    pageBitArray = this.pages_[pageIndex] =
        new Uint8Array(SparseBitArray.BYTES_PER_PAGE);
    this.numberOfPageAllocations_++;
  }
  var pageBitIndex = index & SparseBitArray.PAGE_MASK;
  var pageByteIndex = pageBitIndex >> SparseBitArray.BYTE_SHIFT;
  var byteBitIndex = pageBitIndex & SparseBitArray.BYTE_MASK;
  var theBit = 1 << byteBitIndex;
  pageBitArray[pageByteIndex] |= theBit;
  goog.asserts.assert(this.alternateBitInfo_[index] = true);
};

/**
 * Gets whether the bit at index is set.
 * Returns false if the bit is missing; ie: is in a sparse area.
 * @param {number} index The bit's index.
 * @return {boolean}
 */
SparseBitArray.prototype.isSet = function(index) {
  var pageIndex = index >> SparseBitArray.PAGE_SHIFT;
  var pageBitArray = this.pages_[pageIndex];
  if (!pageBitArray) {
    goog.asserts.assert(
        !this.alternateBitInfo_[index], 'bit %s should not be set', index);
    return false;
  }
  var pageBitIndex = index & SparseBitArray.PAGE_MASK;
  var pageByteIndex = pageBitIndex >> SparseBitArray.BYTE_SHIFT;
  var theByte = pageBitArray[pageByteIndex];
  var byteBitIndex = pageBitIndex & SparseBitArray.BYTE_MASK;
  var theBit = 1 << byteBitIndex;
  var bitIsSet = !!(theByte & theBit);
  goog.asserts.assert(
      bitIsSet == !!this.alternateBitInfo_[index], 'bit %s should be %s', index,
      !!this.alternateBitInfo_[index]);
  return bitIsSet;
};

/**
 * Gets the number of page allocations.
 * This is useful for testing.
 * @return {number}
 */
SparseBitArray.prototype.getNumberOfPageAllocations = function() {
  return this.numberOfPageAllocations_;
};

/**
 * Compares the sparse bit array against the alternate bit info.
 * This is useful for testing.
 * @return {boolean}
 */
SparseBitArray.prototype.compareAlternateBitInfo = function() {
  var pageKeys = Object.keys(this.pages_);
  for (var i = 0; i < pageKeys.length; i++) {
    // Need parseInt because Object.keys() always returns strings.
    var pageKey = parseInt(pageKeys[i], 10);
    var page = this.pages_[pageKey];
    for (var j = 0; j < SparseBitArray.BYTES_PER_PAGE; j++) {
      var theByte = page[j];
      for (var k = 0; k < SparseBitArray.BITS_PER_BYTE; k++) {
        var theBit = 1 << k;
        var bitIsSet = !!(theByte & theBit);
        var index =  //
            (pageKey * SparseBitArray.BYTES_PER_PAGE *
             SparseBitArray.BITS_PER_BYTE) +
            (j * SparseBitArray.BITS_PER_BYTE) + k;
        goog.asserts.assert(
            bitIsSet == !!this.alternateBitInfo_[index], 'bit %s should be %s',
            index, !!this.alternateBitInfo_[index]);
        goog.asserts.assert(
            (!!this.alternateBitInfo_[index] ?
                 delete (this.alternateBitInfo_[index]) :
                 0) ||
            true);
      }
    }
  }
  goog.asserts.assert(
      Object.keys(this.alternateBitInfo_).length == 0,
      'number of alternateBitInfo bits set differs from the sparse array by ' +
          '%s bits',
      Object.keys(this.alternateBitInfo_).length);
  return true;
};

});  // goog.scope
<commit_msg>Slowly re-removing the code for the alternateBitInfo. It was removed but then rolled back due to a 4% increase in CALC_NEEDED_CHARS.<commit_after>'use strict';

/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

goog.provide('tachyfont.SparseBitArray');

goog.require('goog.asserts');

goog.scope(function() {

/**
 * This class provides a sparse bit array.
 *
 * The bit array is made up of 'pages'. The bit array is sparse because only
 * pages with set bits are allocated. Each page uses an array of bytes to cover
 * a continous range of bits.
 * @constructor @struct @final
 */
tachyfont.SparseBitArray = function() {
  /** @private {!Object<number, !Uint8Array>} */
  this.pages_ = {};

  /**
   * TODO(bstell): if no errors reporting then delete this after 2016-10-01.
   *
   * For testing make an alternate recording of the bits.
   * This is used to verify the correct operation of the sparse bit array.
   * Note: Storing info this way uses a large amount of memory; eg,20K entries
   * can take 1.5MB.
   * @private {!Object<number, boolean>}
   */
  this.alternateBitInfo_ = {};

  /**
   * For testing record the number of page allocations.
   * @private {number}
   */
  this.numberOfPageAllocations_ = 0;
};
var SparseBitArray = tachyfont.SparseBitArray;

/**
 * The amount to shift to get the page index.
 */
SparseBitArray.PAGE_SHIFT = 8;

/**
 * The amount to shift to get the page index.
 */
SparseBitArray.PAGE_MASK = 0xFF;

/**
 * The number of bytes in a page.
 */
SparseBitArray.BYTES_PER_PAGE = 32;

/**
 * The number of bytes in a page.
 */
SparseBitArray.BITS_PER_BYTE = 8;

/**
 * The amount to shift to get the byte index.
 */
SparseBitArray.BYTE_SHIFT = 3;

/**
 * The amount to shift to get the byte index.
 */
SparseBitArray.BYTE_MASK = 0x7;

/**
 * Sets the bit at index.
 * @param {number} index The bit's index.
 */
SparseBitArray.prototype.setBit = function(index) {
  var pageIndex = index >> SparseBitArray.PAGE_SHIFT;
  var pageBitArray = this.pages_[pageIndex];
  if (!pageBitArray) {
    pageBitArray = this.pages_[pageIndex] =
        new Uint8Array(SparseBitArray.BYTES_PER_PAGE);
    this.numberOfPageAllocations_++;
  }
  var pageBitIndex = index & SparseBitArray.PAGE_MASK;
  var pageByteIndex = pageBitIndex >> SparseBitArray.BYTE_SHIFT;
  var byteBitIndex = pageBitIndex & SparseBitArray.BYTE_MASK;
  var theBit = 1 << byteBitIndex;
  pageBitArray[pageByteIndex] |= theBit;
  goog.asserts.assert(this.alternateBitInfo_[index] = true);
};

/**
 * Gets whether the bit at index is set.
 * Returns false if the bit is missing; ie: is in a sparse area.
 * @param {number} index The bit's index.
 * @return {boolean}
 */
SparseBitArray.prototype.isSet = function(index) {
  var pageIndex = index >> SparseBitArray.PAGE_SHIFT;
  var pageBitArray = this.pages_[pageIndex];
  if (!pageBitArray) {
    return false;
  }
  var pageBitIndex = index & SparseBitArray.PAGE_MASK;
  var pageByteIndex = pageBitIndex >> SparseBitArray.BYTE_SHIFT;
  var theByte = pageBitArray[pageByteIndex];
  var byteBitIndex = pageBitIndex & SparseBitArray.BYTE_MASK;
  var theBit = 1 << byteBitIndex;
  var bitIsSet = !!(theByte & theBit);
  goog.asserts.assert(
      bitIsSet == !!this.alternateBitInfo_[index], 'bit %s should be %s', index,
      !!this.alternateBitInfo_[index]);
  return bitIsSet;
};

/**
 * Gets the number of page allocations.
 * This is useful for testing.
 * @return {number}
 */
SparseBitArray.prototype.getNumberOfPageAllocations = function() {
  return this.numberOfPageAllocations_;
};

/**
 * Compares the sparse bit array against the alternate bit info.
 * This is useful for testing.
 * @return {boolean}
 */
SparseBitArray.prototype.compareAlternateBitInfo = function() {
  var pageKeys = Object.keys(this.pages_);
  for (var i = 0; i < pageKeys.length; i++) {
    // Need parseInt because Object.keys() always returns strings.
    var pageKey = parseInt(pageKeys[i], 10);
    var page = this.pages_[pageKey];
    for (var j = 0; j < SparseBitArray.BYTES_PER_PAGE; j++) {
      var theByte = page[j];
      for (var k = 0; k < SparseBitArray.BITS_PER_BYTE; k++) {
        var theBit = 1 << k;
        var bitIsSet = !!(theByte & theBit);
        var index =  //
            (pageKey * SparseBitArray.BYTES_PER_PAGE *
             SparseBitArray.BITS_PER_BYTE) +
            (j * SparseBitArray.BITS_PER_BYTE) + k;
        goog.asserts.assert(
            bitIsSet == !!this.alternateBitInfo_[index], 'bit %s should be %s',
            index, !!this.alternateBitInfo_[index]);
        goog.asserts.assert(
            (!!this.alternateBitInfo_[index] ?
                 delete (this.alternateBitInfo_[index]) :
                 0) ||
            true);
      }
    }
  }
  goog.asserts.assert(
      Object.keys(this.alternateBitInfo_).length == 0,
      'number of alternateBitInfo bits set differs from the sparse array by ' +
          '%s bits',
      Object.keys(this.alternateBitInfo_).length);
  return true;
};

});  // goog.scope
<|endoftext|>


<commit_before>test( "Popcorn 1.0 WebSRT/VTT Parser Plugin", function () {

  var count = 0,
      numSubs = 0,
      sub,
      poppercorn = Popcorn( "#video" ),
      expectedSubs = [
        {
          id: "00:00:02.400 --> 00:00:07.200",
          text: "A typical multiline
subtitle.",
          start: 2.4,
          end: 7.2
        },
        {
          id: "00:09.712-->00:13.399",
          text: "No whitespace between time tokens",
          start: 9.712,
          end: 13.399
        },
        {
          id: "00:00:15.042 --> 00:00:18.042 A:start D:vertical L:98%",
          text: "It's a trap! Ignore the timeline styling for now!",
          start: 15.042,
          end: 18.042
        },
        {
          id: "00:00:20.000--> 00:00:21.670",
          text: "This text is boldy italicized",
          start: 20.000,
          end: 21.670
        }
      ],
      expects = expectedSubs.length  *4 + 1;

  function plus() {
    if ( ++count === expects ) {
      start();
    }
  }

  poppercorn.parseVTT( "data/unit.vtt" );
  expect( expects );
  stop( 5000 );

  // Allow load time
  setTimeout(function () {
    Popcorn.forEach( poppercorn.getTrackEvents(), function( evt ) {
      if( evt._natives.type === "subtitle" ) {
        sub = expectedSubs[ numSubs++ ];

        strictEqual( evt.id, sub.id, "Correctly parsed id" );
        plus();
        strictEqual( evt.text, sub.text, "Correctly parsed text of '" + evt.id + "'" );
        plus();
        strictEqual( evt.start, sub.start, "Correctly parsed start at '" + evt.id + "'" );
        plus();
        strictEqual( evt.end, sub.end, "Correctly parsed end at '" + evt.id + "'" );
        plus();
      }
    });

    equals( expectedSubs.length, numSubs, "Parsed all subtitles" );
    plus();

  }, 500);
});
<commit_msg>[#750] Fix dumb spacing mistake<commit_after>test( "Popcorn 1.0 WebSRT/VTT Parser Plugin", function () {

  var count = 0,
      numSubs = 0,
      sub,
      poppercorn = Popcorn( "#video" ),
      expectedSubs = [
        {
          id: "00:00:02.400 --> 00:00:07.200",
          text: "A typical multiline
subtitle.",
          start: 2.4,
          end: 7.2
        },
        {
          id: "00:09.712-->00:13.399",
          text: "No whitespace between time tokens",
          start: 9.712,
          end: 13.399
        },
        {
          id: "00:00:15.042 --> 00:00:18.042 A:start D:vertical L:98%",
          text: "It's a trap! Ignore the timeline styling for now!",
          start: 15.042,
          end: 18.042
        },
        {
          id: "00:00:20.000--> 00:00:21.670",
          text: "This text is boldy italicized",
          start: 20.000,
          end: 21.670
        }
      ],
      expects = expectedSubs.length * 4 + 1;

  function plus() {
    if ( ++count === expects ) {
      start();
    }
  }

  poppercorn.parseVTT( "data/unit.vtt" );
  expect( expects );
  stop( 5000 );

  // Allow load time
  setTimeout(function () {
    Popcorn.forEach( poppercorn.getTrackEvents(), function( evt ) {
      if( evt._natives.type === "subtitle" ) {
        sub = expectedSubs[ numSubs++ ];

        strictEqual( evt.id, sub.id, "Correctly parsed id" );
        plus();
        strictEqual( evt.text, sub.text, "Correctly parsed text of '" + evt.id + "'" );
        plus();
        strictEqual( evt.start, sub.start, "Correctly parsed start at '" + evt.id + "'" );
        plus();
        strictEqual( evt.end, sub.end, "Correctly parsed end at '" + evt.id + "'" );
        plus();
      }
    });

    equals( expectedSubs.length, numSubs, "Parsed all subtitles" );
    plus();

  }, 500);
});
<|endoftext|>


<commit_before>// Cookies
//
// Get or set cookie values
//
// Usage:
//
//    GOVUK.cookie('myCookie');
//
//      returns the value of 'myCookie';
//
//    GOVUK.cookie('myCookie', 'hobnob', 30);
//
//      sets the cookie 'myCookie' to 'hobnob' for 30 days.
//

(function () {
  "use strict"
  var root = this,
      $ = root.jQuery;
  if(typeof root.GOVUK === 'undefined') { root.GOVUK = {}; }

  root.GOVUK.cookie = function(name, value, days){
    if(typeof value !== 'undefined'){
      return root.GOVUK.setCookie(name, value, days);
    } else {
      return root.GOVUK.getCookie(name);
    }
  };

  root.GOVUK.setCookie = function(name, value, days){
    var cookieString = name + "=" + value + "; path=/";
    if (days) {
      var date = new Date();
      date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
      cookieString = cookieString + "; expires=" + date.toGMTString();
    }
    if (document.location.protocol == 'https:'){
      cookieString = cookieString + "; Secure";
    }
    root.document.cookie = cookieString;
  };

  root.GOVUK.getCookie = function(name){
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i = 0, len = ca.length; i < len; i++) {
      var c = ca[i];
      while (c.charAt(0) == ' ') {
        c = c.substring(1, c.length);
      }
      if (c.indexOf(nameEQ) === 0) {
        return c.substring(nameEQ.length, c.length);
      }
    }
    return null;
  };
}).call(this);
<commit_msg>removed cookies.js (is duplicate of functionality in govuk-template)<commit_after><|endoftext|>