<commit_before>/**
* Wi-Fi chat-plugin. Only works in a room with id 'wifi'
* Handles giveaways in the formats: question, lottery
* Credits: Codelegend, SilverTactic, DanielCranham
**/

// checks whether any alt of the user is present in list.
function checkAllAlts(user, list) {
	for (var prevName in user.prevNames) {
		if (prevName in list) return 'previous name ' + prevName;
	}
	var alts = user.getAlts().map(toId);
	for (var i = 0; i < alts.length; i++) {
		if (alts[i] in list) return 'alt ' + alts[i];
	}
	return false;
}

var giveaway = null;
var wifiRoom = Rooms.get('wifi');

// import giveaway, if exists:
if (wifiRoom && wifiRoom.plugin) {
	giveaway = wifiRoom.plugin;
}

function clearGiveaway() {
	giveaway = null;
	if (wifiRoom) delete wifiRoom.plugin;
}

var QuestionGiveAway = (function () {
	function QuestionGiveAway(host, giver, room, options) {
		this.host = host;
		this.giver = giver;
		this.room = room;
		this.phase = 'pending';

		this.prize = options.prize;
		this.question = options.question;
		this.answers = options.answers;
		this.answered = {}; // userid: number of guesses

		this.room.addRaw('<center><div class = "broadcast-blue"><font size = 3><b>It\'s giveaway time!</b></font><br/>' +
			'<font size = 1>Question Giveaway started by ' + Tools.escapeHTML(host.name) + '</font><br/><br/>' +
			'<b>' + Tools.escapeHTML(giver.name) + '</b> will be giving away a <b>' + Tools.escapeHTML(this.prize) + '!</b><br/>' +
			'The question will be displayed in a minute!');
		this.room.update();
		this.startTimer = setTimeout(this.start.bind(this), 1000 * 60);

		this.excluded = {};
		this.excluded[host.userid] = 1;
		this.excluded[giver.userid] = 1;
	}
	QuestionGiveAway.prototype.type = 'question';

	QuestionGiveAway.prototype.guessAnswer = function (user, guess, output) {
		if (this.phase !== 'started') return output.sendReply("The giveaway has not started yet.");

		var joinError = checkAllAlts(user, this.answered);
		if (joinError) return output.sendReply("You have already joined the giveaway under the " + joinError + ". Use that alt/account to continue.");
		joinError = checkAllAlts(user, this.excluded) || (user.userid in this.excluded);
		if (joinError) return output.sendReply("You are the host/giver of the giveaway, and cannot guess.");

		var userid = user.userid;
		if (!this.answered[userid]) this.answered[userid] = 0;
		if (this.answered[userid] >= 3) {
			return output.sendReply("You have already guessed three times. You cannot guess anymore in this giveaway.");
		}

		if (toId(guess) in this.answers) {
			this.winner = user;
			return this.onEnd();
		}

		this.answered[userid]++;
		if (this.answered[userid] >= 3) {
			output.sendReply("Your guess " + guess + " is wrong. You have used up all your guesses. Better luck next time!");
		} else {
			output.sendReply("Your guess " + guess + " is wrong. Try again!");
		}
		return;
	};

	QuestionGiveAway.prototype.change = function (key, value, user, output) {
		if (user.userid !== this.host.userid) return this.sendReply("You cannot edit this giveaway. Only the host/starter can edit.");
		if (this.phase !== 'pending') return output.sendReply("The giveaway has started, and the question/answer cannot be changed.");

		switch (key) {
		case 'question':
			this.question = value;
			output.sendReply("The question has been changed to " + value + ".");
			break;
		case 'answer':
			var ans = this.sanitizeAnswers(value);
			if (Object.keys(ans).length <= 0) return output.sendReply("You must specify at least one answer and must not contain any special characters.");

			this.answers = ans;
			output.sendReply("The answers have been changed to " + value + ".");
			break;
		}
		return;
	};
	QuestionGiveAway.prototype.start = function () {
		this.phase = 'started';
		clearTimeout(this.startTimer); // just in case it was a force start.
		this.room.addRaw('<div class = "broadcast-blue">Giveaway Question: <b>' + this.question + '</b><br/>' +
			'use /ga to guess.');
		this.room.update();
		this.endTimer = setTimeout(this.onEnd.bind(this), 1000 * 60 * 10);
	};
	QuestionGiveAway.prototype.onEnd = function (force) {
		if (force) {
			if (this.phase === 'ended') return;
			clearTimeout(this.startTimer);
			clearTimeout(this.endTimer);
			this.room.addRaw('<b>The giveaway was forcibly ended.</b>');
			this.room.update();
			clearGiveaway();
			return;
		}
		this.phase = 'ended';
		clearTimeout(this.endTimer);
		if (!this.winner) {
			this.room.addRaw('<b>The giveaway has been forcibly ended, as no one has answered the question.	</b>');
		} else {
			var ans = [];
			for (var i in this.answers) {
				ans.push(this.answers[i]);
			}
			this.room.addRaw('<div class = "broadcast-blue"><b>' + Tools.escapeHTML(this.winner.name) + '</b> guessed the correct answer.</b> Congratulations!<br/>' +
				"Correct answer(s) : " + ans.join(','));
			if (this.winner.connected) this.winner.popup('You have won the giveaway. PM **' + Tools.escapeHTML(this.giver.name) + '** to claim your reward!');
		}
		this.room.update();
		clearGiveaway();
		return;
	};

	QuestionGiveAway.sanitizeAnswers = function (target) {
		var ret = {};
		target.split("/").forEach(function (ans) {
			ans = ans.replace(/[^a-z0-9 ]+/ig, "").trim();
			if (!toId(ans)) return;
			ret[toId(ans)] = ans.toLowerCase();
		});
		return ret;
	};

	return QuestionGiveAway;
})();

var LotteryGiveAway = (function () {
	function LotteryGiveAway(host, giver, room, options) {
		this.host = host;
		this.giver = giver;
		this.room = room;
		this.phase = 'joining';

		this.prize = options.prize;
		this.maxwinners = options.maxwinners;
		this.joined = {}; // userid: 0

		this.reminder = '<center><div class = "broadcast-blue"><font size = 3><b>It\'s giveaway time!</b></font><br/>' +
			'<font size = 1>Giveaway started by ' + Tools.escapeHTML(host.name) + '</font><br/><br/>' +
			'<b>' + Tools.escapeHTML(giver.name) + '</b> will be giving away: <b>' + Tools.escapeHTML(this.prize) + '</b>!<br/>' +
			'The lottery drawing will occur in 2 minutes, with ' + this.maxwinners + ' winners!<br/>' +
			'<button name = "send" value = "/giveaway joinlottery"><font size = 1><b>Join</b></font></button> <button name = "send" value = "/giveaway leavelottery"><font size = 1><b>Leave</b></font></button><br/>' +
			'<font size = 1><b><u>Note:</u> Please do not join if you don\'t have a 3DS and a copy of Pokémon XY or ORAS';
		this.room.addRaw(this.reminder);
		this.room.update();

		this.drawTimer = setTimeout(this.drawLottery.bind(this), 1000 * 60 * 2);

		this.excluded = {};
		this.excluded[host.userid] = 1;
		this.excluded[giver.userid] = 1;
	}
	LotteryGiveAway.prototype.type = 'lottery';

	LotteryGiveAway.prototype.addUser = function (user, output) {
		if (this.phase !== 'joining') return output.sendReply("The join phase of the lottery giveaway has not started yet.");

		var joinError = checkAllAlts(user, this.joined);
		if (joinError) return output.sendReply("You have already joined the giveaway under the " + joinError + ". Use that alt/account to continue.");
		joinError = checkAllAlts(user, this.excluded) || (user.userid in this.excluded);
		if (joinError) return output.sendReply("You are the host/giver of the giveaway, and cannot join.");

		this.joined[user.userid] = 0;<commit_msg>Prevent guests from joining lotteries.<commit_after>/**
* Wi-Fi chat-plugin. Only works in a room with id 'wifi'
* Handles giveaways in the formats: question, lottery
* Credits: Codelegend, SilverTactic, DanielCranham
**/

// checks whether any alt of the user is present in list.
function checkAllAlts(user, list) {
	for (var prevName in user.prevNames) {
		if (prevName in list) return 'previous name ' + prevName;
	}
	var alts = user.getAlts().map(toId);
	for (var i = 0; i < alts.length; i++) {
		if (alts[i] in list) return 'alt ' + alts[i];
	}
	return false;
}

var giveaway = null;
var wifiRoom = Rooms.get('wifi');

// import giveaway, if exists:
if (wifiRoom && wifiRoom.plugin) {
	giveaway = wifiRoom.plugin;
}

function clearGiveaway() {
	giveaway = null;
	if (wifiRoom) delete wifiRoom.plugin;
}

var QuestionGiveAway = (function () {
	function QuestionGiveAway(host, giver, room, options) {
		this.host = host;
		this.giver = giver;
		this.room = room;
		this.phase = 'pending';

		this.prize = options.prize;
		this.question = options.question;
		this.answers = options.answers;
		this.answered = {}; // userid: number of guesses

		this.room.addRaw('<center><div class = "broadcast-blue"><font size = 3><b>It\'s giveaway time!</b></font><br/>' +
			'<font size = 1>Question Giveaway started by ' + Tools.escapeHTML(host.name) + '</font><br/><br/>' +
			'<b>' + Tools.escapeHTML(giver.name) + '</b> will be giving away a <b>' + Tools.escapeHTML(this.prize) + '!</b><br/>' +
			'The question will be displayed in a minute!');
		this.room.update();
		this.startTimer = setTimeout(this.start.bind(this), 1000 * 60);

		this.excluded = {};
		this.excluded[host.userid] = 1;
		this.excluded[giver.userid] = 1;
	}
	QuestionGiveAway.prototype.type = 'question';

	QuestionGiveAway.prototype.guessAnswer = function (user, guess, output) {
		if (this.phase !== 'started') return output.sendReply("The giveaway has not started yet.");

		var joinError = checkAllAlts(user, this.answered);
		if (joinError) return output.sendReply("You have already joined the giveaway under the " + joinError + ". Use that alt/account to continue.");
		joinError = checkAllAlts(user, this.excluded) || (user.userid in this.excluded);
		if (joinError) return output.sendReply("You are the host/giver of the giveaway, and cannot guess.");

		var userid = user.userid;
		if (!this.answered[userid]) this.answered[userid] = 0;
		if (this.answered[userid] >= 3) {
			return output.sendReply("You have already guessed three times. You cannot guess anymore in this giveaway.");
		}

		if (toId(guess) in this.answers) {
			this.winner = user;
			return this.onEnd();
		}

		this.answered[userid]++;
		if (this.answered[userid] >= 3) {
			output.sendReply("Your guess " + guess + " is wrong. You have used up all your guesses. Better luck next time!");
		} else {
			output.sendReply("Your guess " + guess + " is wrong. Try again!");
		}
		return;
	};

	QuestionGiveAway.prototype.change = function (key, value, user, output) {
		if (user.userid !== this.host.userid) return this.sendReply("You cannot edit this giveaway. Only the host/starter can edit.");
		if (this.phase !== 'pending') return output.sendReply("The giveaway has started, and the question/answer cannot be changed.");

		switch (key) {
		case 'question':
			this.question = value;
			output.sendReply("The question has been changed to " + value + ".");
			break;
		case 'answer':
			var ans = this.sanitizeAnswers(value);
			if (Object.keys(ans).length <= 0) return output.sendReply("You must specify at least one answer and must not contain any special characters.");

			this.answers = ans;
			output.sendReply("The answers have been changed to " + value + ".");
			break;
		}
		return;
	};
	QuestionGiveAway.prototype.start = function () {
		this.phase = 'started';
		clearTimeout(this.startTimer); // just in case it was a force start.
		this.room.addRaw('<div class = "broadcast-blue">Giveaway Question: <b>' + this.question + '</b><br/>' +
			'use /ga to guess.');
		this.room.update();
		this.endTimer = setTimeout(this.onEnd.bind(this), 1000 * 60 * 10);
	};
	QuestionGiveAway.prototype.onEnd = function (force) {
		if (force) {
			if (this.phase === 'ended') return;
			clearTimeout(this.startTimer);
			clearTimeout(this.endTimer);
			this.room.addRaw('<b>The giveaway was forcibly ended.</b>');
			this.room.update();
			clearGiveaway();
			return;
		}
		this.phase = 'ended';
		clearTimeout(this.endTimer);
		if (!this.winner) {
			this.room.addRaw('<b>The giveaway has been forcibly ended, as no one has answered the question.	</b>');
		} else {
			var ans = [];
			for (var i in this.answers) {
				ans.push(this.answers[i]);
			}
			this.room.addRaw('<div class = "broadcast-blue"><b>' + Tools.escapeHTML(this.winner.name) + '</b> guessed the correct answer.</b> Congratulations!<br/>' +
				"Correct answer(s) : " + ans.join(','));
			if (this.winner.connected) this.winner.popup('You have won the giveaway. PM **' + Tools.escapeHTML(this.giver.name) + '** to claim your reward!');
		}
		this.room.update();
		clearGiveaway();
		return;
	};

	QuestionGiveAway.sanitizeAnswers = function (target) {
		var ret = {};
		target.split("/").forEach(function (ans) {
			ans = ans.replace(/[^a-z0-9 ]+/ig, "").trim();
			if (!toId(ans)) return;
			ret[toId(ans)] = ans.toLowerCase();
		});
		return ret;
	};

	return QuestionGiveAway;
})();

var LotteryGiveAway = (function () {
	function LotteryGiveAway(host, giver, room, options) {
		this.host = host;
		this.giver = giver;
		this.room = room;
		this.phase = 'joining';

		this.prize = options.prize;
		this.maxwinners = options.maxwinners;
		this.joined = {}; // userid: 0

		this.reminder = '<center><div class = "broadcast-blue"><font size = 3><b>It\'s giveaway time!</b></font><br/>' +
			'<font size = 1>Giveaway started by ' + Tools.escapeHTML(host.name) + '</font><br/><br/>' +
			'<b>' + Tools.escapeHTML(giver.name) + '</b> will be giving away: <b>' + Tools.escapeHTML(this.prize) + '</b>!<br/>' +
			'The lottery drawing will occur in 2 minutes, with ' + this.maxwinners + ' winners!<br/>' +
			'<button name = "send" value = "/giveaway joinlottery"><font size = 1><b>Join</b></font></button> <button name = "send" value = "/giveaway leavelottery"><font size = 1><b>Leave</b></font></button><br/>' +
			'<font size = 1><b><u>Note:</u> Please do not join if you don\'t have a 3DS and a copy of Pokémon XY or ORAS';
		this.room.addRaw(this.reminder);
		this.room.update();

		this.drawTimer = setTimeout(this.drawLottery.bind(this), 1000 * 60 * 2);

		this.excluded = {};
		this.excluded[host.userid] = 1;
		this.excluded[giver.userid] = 1;
	}
	LotteryGiveAway.prototype.type = 'lottery';

	LotteryGiveAway.prototype.addUser = function (user, output) {
		if (this.phase !== 'joining') return output.sendReply("The join phase of the lottery giveaway has not started yet.");

		if (!user.authenticated) return output.sendReply("You need to choose a name before joining a lottery giveaway.");
		var joinError = checkAllAlts(user, this.joined);
		if (joinError) return output.sendReply("You have already joined the giveaway under the " + joinError + ". Use that alt/account to continue.");
		joinError = checkAllAlts(user, this.excluded) || (user.userid in this.excluded);
		if (joinError) return output.sendReply("You are the host/giver of the giveaway, and cannot join.");

		this.joined[user.userid] = 0;
{'fraction_non_alphanumeric': 0.16252637310283807, 'fraction_numerical': 0.0058531273395494455, 'mean_word_length': 3.925913509889373, 'pattern_counts': {'":': 0, '<': 133, '<?xml version=': 0, '>': 133, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6232781', 'n_tokens_mistral': 5517, 'n_tokens_neox': 4942, 'n_words': 1345}