Why yes, as a matter of fact it does ;)   //
on('ready',function(){
    var getCleanImgsrc = function (imgsrc) {
	   "use strict";
	   var parts = imgsrc.match(/(.*\/images\/.*)(thumb|med|original|max)(.*)$/);
	   if(parts) {
		  return parts[1]+'thumb'+parts[3];
	   }
	   return;
	},
	summonToken = function(character,pageid,baseX,baseY,baseW,baseH){
		"use strict";
		var page=getObj('page',pageid);
		baseW=baseW||70;
		baseH=baseH||70;
		character.get('defaulttoken',function(defaulttoken){
		  var dt = JSON.parse(defaulttoken);
		  if(dt && getCleanImgsrc(dt.imgsrc)){
			dt.imgsrc=getCleanImgsrc(dt.imgsrc);
			dt.left=((baseX+baseW+dt.width)>page.get('width') ? baseX-dt.width : baseX+baseW);
			dt.top=((baseY+baseH+dt.width)>page.get('height') ? baseY-dt.width : baseY+baseH);
			dt.pageid = pageid;
			createObj('graphic',dt);
		  } else {
			sendChat('','/w gm Cannot create token for <b>'+character.get('name')+'</b>');
		  }
		});
	};
	on("chat:message", function(msg)
	{
		if (msg.type == "api" && msg.content.indexOf("!summon ") === 0) 
		{
			var GM = "";
			var size1 = 0;
			var size2 = size1;
			var s = 0;
			var inputName = "";
			var howMuch = 0;
			var amount = 0;			// Amount of summoned monsters.
			var mod = 0;			// Modifier to amount.
			var skip = false;
			var action = "Summons ";
			var section = msg.content.split(" ");		// Breaks API call into sections.
			if (section.length > 1)
			{
				for (var j=1;j<section.length;j++)
				{
					if (typeof parseInt(section[j]) === 'number' && Math.round(parseInt(section[j])) % 1 == 0 || section[j].length <= 4 && section[j].toLowerCase().search("d") != -1 && /\dd/.test(section[j]) || section[j].toLowerCase() == 'cust')
					{
						if (section[j].toLowerCase() == 'cust')
						{
							var howMuch = j;
							break;
						}
						else
						{
							if (j != section.length-1)
							{
								for (var m = j+1; m < section.length; m++)
								{
									
									if (typeof parseInt(section[m]) === 'number' && Math.round(parseInt(section[m])) % 1 == 0 || section[m].length <= 4 && section[m].toLowerCase().search("d") != -1 && /\dd/.test(section[m]))
									{
										skip = true;
									}
									else
									{
										skip = false;
									}
								}
							}
							else
							{
								skip = false;
							}
							if (skip == false)
							{
								var howMuch = j;
								break;
							}
						}
					}
				}
				if (howMuch > 0)
				{
					for (var k=1;k<howMuch;k++)
					{
						if (k == howMuch-1)
						{
							inputName = inputName + section[k];
						}
						else
						{
							inputName = inputName + section[k] + " ";
						}
					}
					if (section[howMuch].toLowerCase().search("d") != -1)		// If user chose to roll.
					{
						if (section[howMuch].indexOf("+") != -1)
						{
							mod = section[howMuch].split("+");				// If user specified a modfier.
							section[howMuch] = mod[0];
							mod = parseInt(mod[1],10);
						}
						var count = 0;
						var diceRoll = section[howMuch].split("d");
						diceRoll[0] = diceRoll[0].replace(/\D/g,'');
						diceRoll[1] = diceRoll[1].replace(/\D/g,'');
						var lowEnd = parseInt(diceRoll[0]);
						var highEnd = parseInt(diceRoll[1]);
						while (count < lowEnd) 
						{
							amount = amount + randomInteger(highEnd);		// Rolls dice.
							count++;
							log("Summoner: rolls a " + amount)
						}
					}
					else if (section[howMuch].toLowerCase() != 'cust')
					{
						var amount = parseInt(section[howMuch],10);						// Creates variable for number of summoned monsters.
					}
					else
					{
						amount == 1;
					}
					amount = amount + mod;
				}
				else if (howMuch == 0)
				{
					if (section[section.length-1].length == 1)
					{
						s = 1;
						howMuch = section.length - 2;
					}
					amount = 1;
					
					for (var k=1;k<section.length-s;k++)
					{
						if (k == section.length-1-s)
						{
							inputName = inputName + section[k];
						}
						else
						{
							inputName = inputName + section[k] + " ";
						}
					}
				}
				if (section.length > (howMuch+1) && section[howMuch].toLowerCase() != "cust")
				{
					if (section[howMuch+1].toLowerCase() == "f")
					{
						size1 = -63;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "d")
					{
						size1 = -56;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "t")
					{
						size1 = -35;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "l")
					{
						size1 = 70;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "h")
					{
						size1 = 140;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "g")
					{
						size1 = 210;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "c")
					{
						size1 = 280;
						size2 = size1;
					}
					else if (section[howMuch+1].toLowerCase() == "cust")
					{
						if (typeof section[howMuch+2] != 'undefined')
						{
							size1 = parseInt(section[howMuch+2]);
						}
						else
						{
							sendChat(msg.who, "/w gm Please ensure the \"cust\" tag is followed by two values (every 70 = 1 square).");			// If monster is not in character list.
						}
						if (typeof section[howMuch+3] != 'undefined')
						{
							size2 = parseInt(section[howMuch+3]);
						}
						else
						{
							sendChat(msg.who, "/w gm Please ensure the \"cust\" tag is followed by two values (every 70 = 1 square).");			// If monster is not in character list.
						}
					}
				}
				else if (section[howMuch].toLowerCase() == "cust")
				{
					if (typeof section[howMuch+1] != 'undefined')
					{
						size1 = parseInt(section[howMuch+1]);
					}
					else
					{
						sendChat(msg.who, "/w gm Please ensure the \"cust\" tag is followed by two values (every 70 = 1 square).");			// If monster is not in character list.
					}
					if (typeof section[howMuch+2] != 'undefined')
					{
						size2 = parseInt(section[howMuch+2]);
					}
					else
					{
						sendChat(msg.who, "/w gm Please ensure the \"cust\" tag is followed by two values (every 70 = 1 square).");			// If monster is not in character list.
					}
				}
			}
			else
			{
				sendChat(msg.who, "/w gm No monsters specified to summon");	// If user writes too many things.
			}
			var check = findObjs({ _type: "character", name: inputName },{caseInsensitive: true})[0];
			if (typeof check == 'undefined')
			{
				sendChat(msg.who, "/w gm Monster of name \""  + inputName + "\" does not exist.");			// If monster is not in character list.
			}
			else
			{
				var list = findObjs({ _type: "character", name: inputName},{caseInsensitive: true});
				var characterId = list[0].id;								// Extract character ID from character sheet
				var characterName = list[0].get('name');					// Extract character name from character sheet
				var characterImage = list[0].get('avatar');					// Extract character image URL from character sheet
				var character;
				if (characterImage.indexOf("marketplace") != -1)
				{
					sendChat(msg.who, "/w gm Monster of name \""  + inputName + "\" has a marketplace image.");    		// Error message
				}
				else
				{
					characterImage = characterImage.replace("med","thumb");		// Change character image to thumb if med
					characterImage = characterImage.replace("max","thumb");		// Change character image to thumb if max
					var selected = msg.selected;								
					_.each(selected, function(obj)
					{
						var tok = getObj("graphic", obj._id);					// Create variable for selected token (for summoned monster positioning)
						var HP = findObjs({ _type: "attribute", name: "hitpoints", _characterid: characterId },{caseInsensitive: true})[0];            //finds the health from charactersheet
						if (typeof HP == 'undefined')
						{
							HP = "-1";
						}
						else
						{
							HP = (HP) ? HP.get("current") : 0;                                          // Changes HP to useable string
						}
						var SP = findObjs({ _type: "attribute", name: "speed", _characterid: characterId },{caseInsensitive: true})[0];            //finds the speed from charactersheet
						if (typeof SP == 'undefined')
						{
							SP = "-1";
						}
						else
						{
							SP = (SP) ? SP.get("current") : 0;                                          // Changes SP to useable string
						}
						var AC = findObjs({ _type: "attribute", name: "armorclass", _characterid: characterId },{caseInsensitive: true})[0];            // finds the ac from charactersheet
						if (typeof AC == 'undefined')
						{
							AC = "-1";
						}
						else
						{
							AC = (AC) ? AC.get("current") : 0;                                          // Changes AC to useable string
						}
						if (amount == 0)
						{
							amount = 1;
						}
						else if (amount > 20)
						{
							var tooMany = amount;
							amount = 20;
							log("Summoner: User specified " + tooMany + " monsters. Scaling to 20.")		// If user spams the field.
						}
						for (var i=0;i<amount;i++)
						{
							if (HP == "-1" && AC == "-1" && msg.content.toLowerCase().search("torch") != -1)
							{
								action = "Lights"
								createObj("graphic", 
								{
									represents: characterId,  							// Links new token to charactersheet
									left: tok.get("left")+70,
									top: tok.get("top"),
									width: 70+size1,
									height: 70+size2,
									name: characterName,
									pageid: tok.get("pageid"),
									imgsrc: characterImage,
									layer: "objects",
									light_radius: 40,
									light_dimradius: 20,
									light_otherplayers: true
								});
							}
							else if (HP == "-1" && AC == "-1")
							{
								character = getObj('character',characterId);
								if(character){
									summonToken(
										character,
										tok.get('pageid'),
										tok.get('left'),
										tok.get('top'),
										tok.get('width'),
										tok.get('height')
									);
								} else {
									sendChat('','/w gm No character for id: <b>'+characterId+'</b>');
								}
							}
							else
							{
								character = getObj('character',characterId);
								if(character){
									summonToken(
										character,
										tok.get('pageid'),
										tok.get('left'),
										tok.get('top'),
										tok.get('width'),
										tok.get('height')
									);
								} else {
									sendChat('','/w gm No character for id: <b>'+characterId+'</b>');
								}
							}
						}
					});
					if (amount > 1)
					{
						inputName = inputName + "s";						// If more than 1 summon, adds plural.
					}
					else if (amount == 1 && action == "Lights")
					{
						amount = " a";
						inputName = "torch";
					}
					if (typeof amount === 'number')
					{
						amount = amount.toString();
					}
					sendChat(msg.who, GM + action + amount + " " + inputName + "!");		// Announces how many and what Summoner has summoned.
				}
			}
		}
	});
});