diff --git a/xtrn/SlyVote/SlyVote.js b/xtrn/SlyVote/SlyVote.js
index 31955699681ccab05639e04ea17fa6a2997fc2fc..87815420ec5e5197b39dd90c67a6babf13d7e5c7 100644
--- a/xtrn/SlyVote/SlyVote.js
+++ b/xtrn/SlyVote/SlyVote.js
@@ -55,6 +55,12 @@
  * 2017-08-19 Eric Oulashin     Version 0.27 Beta
  *                              Used the new Msgbase.close_poll() method in the August
  *                              19, 2017 build of Synchronet 3.17
+ * 2017-08-20 Eric Oulashin     Version 0.28 Beta
+ *                              Updated the vote option input for traditional mode
+ *                              (when voting from the 'view results' screen) so that
+ *                              it only accepts numbers and a comma for input.  Also,
+ *                              updated the close-poll behavior so that only the user
+ *                              who created the poll can close it (removed the sysop).
  */
 
 load("sbbsdefs.js");
@@ -99,8 +105,8 @@ load("scrollbar.js");
 load("DDLightbarMenu.js");
 
 // Version information
-var SLYVOTE_VERSION = "0.27 Beta";
-var SLYVOTE_DATE = "2017-08-19";
+var SLYVOTE_VERSION = "0.28 Beta";
+var SLYVOTE_DATE = "2017-08-20";
 
 // Determine the script's startup directory.
 // This code is a trick that was created by Deuce, suggested by Rob Swindell
@@ -141,14 +147,14 @@ var UPPER_RIGHT_VSINGLE_HDOUBLE = "\xB8";
 var LOWER_LEFT_VSINGLE_HDOUBLE = "\xD4";
 var LOWER_RIGHT_VSINGLE_HDOUBLE = "\xBE";
 // Other special characters
-var DOT_CHAR = "�";
+var DOT_CHAR = "\xF9";
 var CHECK_CHAR = "\xFB";
-var THIN_RECTANGLE_LEFT = "�";
-var THIN_RECTANGLE_RIGHT = "�";
-var BLOCK1 = "�"; // Dimmest block
-var BLOCK2 = "�";
-var BLOCK3 = "�";
-var BLOCK4 = "�"; // Brightest block
+var THIN_RECTANGLE_LEFT = "\xDD";
+var THIN_RECTANGLE_RIGHT = "\xDE";
+var BLOCK1 = "\xB0"; // Dimmest block
+var BLOCK2 = "\xB1";
+var BLOCK3 = "\xB2";
+var BLOCK4 = "\xDB"; // Brightest block
 
 // Strings for the various message attributes (used by makeAllAttrStr(),
 // makeMainMsgAttrStr(), makeAuxMsgAttrStr(), and makeNetMsgAttrStr())
@@ -1318,7 +1324,7 @@ function VoteOnPoll(pSubBoardCode, pMsgbase, pMsgHdr, pUser, pUserVoteNumber, pR
 					console.print("\1n\1gYour vote numbers, separated by commas, up to \1h" + pMsgHdr.votes + "\1n\1g (Q=quit):");
 					console.crlf();
 					console.print("\1c\1h");
-					var userInput = console.getstr();
+					var userInput = consoleGetStrWithValidKeys("0123456789,");
 					if ((userInput.length > 0) && (userInput.toUpperCase() != "Q"))
 					{
 						var userAnswers = userInput.split(",");
@@ -1786,13 +1792,13 @@ function ViewVoteResults(pSubBoardCode)
 			}
 			else if (scrollRetObj.lastKeypress == gReaderKeys.close)
 			{
-				// Only let the user close the poll if they created it or if they're a sysop.
+				// Only let the user close the poll if they created it
 				var pollCloseMsg = "";
 				if ((pollMsgHdrs[currentMsgIdx].type & MSG_TYPE_POLL) == MSG_TYPE_POLL)
 				{
 					if ((pollMsgHdrs[currentMsgIdx].auxattr & POLL_CLOSED) == 0)
 					{
-						if (gUserIsSysop || userHandleAliasNameMatch(pollMsgHdrs[currentMsgIdx].from))
+						if (userHandleAliasNameMatch(pollMsgHdrs[currentMsgIdx].from))
 						{
 							// Prompt to confirm whether the user wants to close the poll
 							console.gotoxy(1, console.screen_rows-1);
@@ -3426,4 +3432,89 @@ function closePoll(pSubBoardCode, pMsgNum)
 		msgbase.close();
 	}
 	return pollClosed;
+}
+
+// Inputs a string from the user, restricting their input to certain keys (optionally).
+//
+// Parameters:
+//  pKeys: A string containing valid characters for input.  Optional
+//  pMaxNumChars: The maximum number of characters to input.  Optional
+//  pCaseSensitive: Boolean - Whether or not the input should be case-sensitive.  Optional.
+//                  Defaults to true.  If false, then the user input will be uppercased.
+//
+// Return value: A string containing the user's input
+function consoleGetStrWithValidKeys(pKeys, pMaxNumChars, pCaseSensitive)
+{
+	var maxNumChars = 0;
+	if ((typeof(pMaxNumChars) == "number") && (pMaxNumChars > 0))
+		maxNumChars = pMaxNumChars;
+
+	var regexPattern = (typeof(pKeys) == "string" ? "[" + pKeys + "]" : ".");
+	var caseSensitive = (typeof(pCaseSensitive) == "boolean" ? pCaseSensitive : true);
+	var regex = new RegExp(regexPattern, (caseSensitive ? "" : "i"));
+
+	var CTRL_H = "\x08";
+	var BACKSPACE = CTRL_H;
+	var CTRL_M = "\x0d";
+	var KEY_ENTER = CTRL_M;
+
+	var modeBits = (caseSensitive ? K_NONE : K_UPPER);
+	var userInput = "";
+	var continueOn = true;
+	while (continueOn)
+	{
+		var userChar = console.getkey(K_NOECHO|modeBits);
+		if (regex.test(userChar) && isPrintableChar(userChar))
+		{
+			var appendChar = true;
+			if ((maxNumChars > 0) && (userInput.length >= maxNumChars))
+				appendChar = false;
+			if (appendChar)
+			{
+				userInput += userChar;
+				if ((modeBits & K_NOECHO) == 0)
+					console.print(userChar);
+			}
+		}
+		else if (userChar == BACKSPACE)
+		{
+			if (userInput.length > 0)
+			{
+				if ((modeBits & K_NOECHO) == 0)
+				{
+					console.print(BACKSPACE);
+					console.print(" ");
+					console.print(BACKSPACE);
+				}
+				userInput = userInput.substr(0, userInput.length-1);
+			}
+		}
+		else if (userChar == KEY_ENTER)
+		{
+			continueOn = false;
+			if ((modeBits & K_NOCRLF) == 0)
+				console.crlf();
+		}
+	}
+	return userInput;
+}
+
+// Returns whether or not a character is printable.
+//
+// Parameters:
+//  pChar: A character to test
+//
+// Return value: Boolean - Whether or not the character is printable
+function isPrintableChar(pChar)
+{
+	// Make sure pChar is valid and is a string.
+	if (typeof(pChar) != "string")
+		return false;
+	if (pChar.length == 0)
+		return false;
+
+	// Make sure the character is a printable ASCII character in the range of 32 to 254,
+	// except for 127 (delete).
+	var charCode = pChar.charCodeAt(0);
+	return ((charCode > 31) && (charCode < 255) && (charCode != 127));
 }
\ No newline at end of file
diff --git a/xtrn/SlyVote/readme.txt b/xtrn/SlyVote/readme.txt
index dba8af018caca04c2c53c5481000ea8b45765358..6f6eda0d5a91d278c93135ca433466636e83ba12 100644
--- a/xtrn/SlyVote/readme.txt
+++ b/xtrn/SlyVote/readme.txt
@@ -1,6 +1,6 @@
                                    SlyVote
-                                 Version 0.27 Beta
-                           Release date: 2017-08-19
+                                 Version 0.28 Beta
+                           Release date: 2017-08-20
 
                                      by