Pinkstack/roblox-luau-corpus-text huggingface dataset:
--End of example plugin
----------------------------------------------------------------------------
--[[
--Below are some real plugins that are functional.

--As another example I have included a plugin that will change the permissions of specific commands. You can see it below.

return function(set)
--make the table that holds our new perms and what command they are for
local coms={
	{cmd='insert',perms=5};
	{cmd='m',perms=5};
	{cmd='gear',perms=5};
} --Changes insert, m, and gear to place owners only.

--These are the commandss and the new permission level, refer to the top of Example Plugin for perm levels.
-- Do note the cmd HAS to be the command thats shown in :cmds command, so if you want tornado to
-- be usable by the game owner only you would put {cmd='tornado',perms=5}; but you CAN NOT user twister instead of tornado.
 
for i=1,#set.Commands do --grab commands, for i,v in pairs for some reason does not like to work for this
	coroutine.wrap(function() --wrap it to make the process go a little faster overall
	for k,v in pairs(coms) do --grab our table with the new command perms
		if v.cmd==set.Commands[i].Cmds[1] then -- if the cmd is the same as the first cmd of the target command then...
			set.Commands[i].AdminLevel=v.perms --set its admin level to our intended one.
		end
	end
	end)()
end
end

------------------------------------------------------------------------
below is a plugin I made for an automated barista bot that allows it to get chats from
the admin script and send them to the barista bot for processing, for server to server
communication like this its recommended to use bindable events, for more information here 
is the bindable event roblox wiki link: http://wiki.roblox.com/index.php?title=Bindableevent

return function(set)
local barista
for i,v in pairs(workspace:children()) do
	if v.Name=='Jessica' and v:IsA('Model') and v:FindFirstChild('BaristaStuff') then barista=v end
end --find the barista
local backup=barista:Clone() --make a backup of the barista
	set.MakePluginEvent('Chat',function(msg,plr) --Add a new function to run on chat for the plugin
		local sendchat=barista.BaristaStuff.Event --Declare the event
		sendchat:Fire(msg,plr) --send the chat to the barista
	end)
	--lets make the reset and on/off commands
	set.MakeCommand('Reset Barista',2,set.Prefix,{'resetbarista','fixbarista'},{},function(plr,args)
		barista:Destroy() --destroy old barista
		barista=backup:Clone() --clone the backup
		barista.Parent=workspace --put it in workspace
		barista:MakeJoints() --make some joints
	end)
	set.MakeCommand('Turn Barista On/Off',3,set.Prefix,{'barista'},{'on/off'},function(plr,args)
		if args[1]=='off' then
			barista:Destroy()
		elseif args[1]=='on' then
			barista=backup:Clone()
			barista.Parent=workspace
			barista:MakeJoints()
		end
	end)--does basically the same stuff as reset.
end
--]]
--		print("Keyframe : ".. frameName)


		local repeatAnim = stopToolAnimations()
		playToolAnimation(repeatAnim, 0.0, Humanoid)
	end
end


function playToolAnimation(animName, transitionTime, Zombie)
	if (animName ~= toolAnimName) then		 
		
		if (toolAnimTrack ~= nil) then
			toolAnimTrack:Stop()
			toolAnimTrack:Destroy()
			transitionTime = 0
		end

		local roll = math.random(1, animTable[animName].totalWeight) 
		local origRoll = roll
		local idx = 1
		while (roll > animTable[animName][idx].weight) do
			roll = roll - animTable[animName][idx].weight
			idx = idx + 1
		end
-- Anytime a weapon is eqipped the weapons spread is displayed


local function DisplaySpreadForWeapon(tool)
	
	if steppedHandle then
		steppedHandle:Disconnect()
	end
	
	-- Get the weapons definition by the tool
	local weaponDefinition = APIEquipment.GetWeaponDefinitionFromTool(tool)
	
	-- Get the runtime of the weapon by the definition
	local weaponRuntime = APIEquipment.WaitForLocalCurrentWeaponRuntimeData(weaponDefinition)
	
	-- Get the spread simulator
	local spreadSimulator = weaponRuntime:GetSpreadSimulator()
	
	local characterState = APICharacterState.GetCharacterState()
	
	-- Interpolate crosshair based on spread
	steppedHandle = RunService.Stepped:Connect(function(currentTime,dt)
		
		-- Hide the crosshair when the player aims their weapon
		if characterState:GetAttribute("IsAiming") then
			Crosshair_Image.ImageTransparency = math.clamp(Crosshair_Image.ImageTransparency + dt * 10,0,1)
		else
			Crosshair_Image.ImageTransparency = math.clamp(Crosshair_Image.ImageTransparency - dt * 10,0,1)
		end
		
		-- Display the spread visuallly based on the weapons spread runtime data
		if spreadSimulator then
			local currentSpread = spreadSimulator:GetSpreadScreenMagnitude(workspace.CurrentCamera)
			Crosshair_Frame.Size = UDim2.new(0,currentSpread,0,currentSpread)
		else
			Crosshair_Frame.Size = UDim2.new(0,10,0,10)
		end
		
	end)
	
end

local character = Local_Player.Character

if character then
	character.ChildAdded:Connect(function(child)
		if not child:IsA("Tool") then return end
		DisplaySpreadForWeapon(child)
	end)
end

Local_Player.CharacterAdded:Connect(function(character)
	character.ChildAdded:Connect(function(child)
		if not child:IsA("Tool") then return end
		DisplaySpreadForWeapon(child)
	end)
end)
-- Roblox User Input Control Modules - each returns a new() constructor function used to create controllers as needed


local Keyboard = require(script:WaitForChild("Keyboard"))
local Gamepad = require(script:WaitForChild("Gamepad"))
local DynamicThumbstick = require(script:WaitForChild("DynamicThumbstick"))

local FFlagUserFlagEnableNewVRSystem do
	local success, result = pcall(function()
		return UserSettings():IsUserFeatureEnabled("UserFlagEnableNewVRSystem")
	end)
	FFlagUserFlagEnableNewVRSystem = success and result
end

local FFlagUserHideControlsWhenMenuOpen do
	local success, result = pcall(function()
		return UserSettings():IsUserFeatureEnabled("UserHideControlsWhenMenuOpen")
	end)
	FFlagUserHideControlsWhenMenuOpen = success and result
end

local TouchThumbstick = require(script:WaitForChild("TouchThumbstick"))
-- Create sound instance


local currentSound = Instance.new("Sound", character.HumanoidRootPart)
	  currentSound.Name = "CurrentSound"
	  currentSound.RollOffMode = Enum.RollOffMode.Linear -- you can experiment with this value
	  currentSound.RollOffMinDistance = 10 -- When should the sound start fading out? (in studs)
	  currentSound.RollOffMaxDistance = 75 -- When should the sound stop being heard? (in studs)
-- To change the sound ID of a material, change the 'id' variable.
-- To change the volume, change the volume variable.
-- To change the playback speed of a sound, change the speed variable.



local IDList = {
	Air = {id = "rbxassetid://329997777", volume = 0, speed = 1.00},
	Asphalt = {id = "rbxassetid://277067660", volume = 0.60, speed = 1.00},
	Basalt = {id = "rbxassetid://3190903775", volume = 0.60, speed = 1.00},
	Brick = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Cobblestone = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Concrete = {id = "rbxassetid://277067660", volume = 0.60, speed = 1.00},
	CorrodedMetal = {id = "rbxassetid://177940974", volume = 0.60, speed = 1.00},
	CrackedLava = {id = "rbxassetid://3190903775", volume = 0.60, speed = 1.00},
	DiamondPlate = {id = "rbxassetid://177940974", volume = 0.60, speed = 1.00},
	Fabric = {id = "rbxassetid://9083849830", volume = 0.40, speed = 1.00},
	Foil = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Forcefield = {id = "rbxassetid://329997777", volume = 0.60, speed = 1.00},
	Glass = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Granite = {id = "rbxassetid://178054124", volume = 0.60, speed = 1.00},
	Grass = {id = "rbxassetid://9064714296", volume = 0.60, speed = 1.00},
	Glacier = {id = "rbxassetid://7047108275", volume = 0.40, speed = 1.00},
	Ground = {id = "rbxassetid://9064714296", volume = 0.60, speed = 1.00},
	Ice = {id = "rbxassetid://7047108275", volume = 0.40, speed = 1.00},
	Limestone = {id = "rbxassetid://9083846829", volume = 0.60, speed = 1.00},
	LeafyGrass = {id = "rbxassetid://3098847639", volume = 0.60, speed = 1.00},
	Marble = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Metal = {id = "rbxassetid://177940974", volume = 0.60, speed = 1.00},
	Mud = {id = "rbxassetid://6441160246", volume = 0.60, speed = 1.00},
	Neon = {id = "rbxassetid://177940974", volume = 0.60, speed = 1.00},
	Pebble = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Plastic = {id = "rbxassetid://4416041299", volume = 0.60, speed = 1.40},
	Pavement = {id = "rbxassetid://277067660", volume = 0.60, speed = 1.00},
	Rock = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Sand = {id = "rbxassetid://9083846829", volume = 0.40, speed = 1.00},
	Slate = {id = "rbxassetid://178054124", volume = 0.60, speed = 1.00},
	Snow = {id = "rbxassetid://8453425942", volume = 0.60, speed = 1.00},
	Salt = {id = "rbxassetid://9083846829", volume = 0.40, speed = 1.00},
	Sandstone = {id = "rbxassetid://3190903775", volume = 0.60, speed = 0.75},
	SmoothPlastic = {id = "rbxassetid://178190837", volume = 0.60, speed = 1.00},
	Wood = {id = "rbxassetid://3199270096", volume = 0.60, speed = 1.00},
	WoodPlanks = {id = "rbxassetid://211987063", volume = 0.60, speed = 1.00}
}

return IDList
--[[
	
	
	flashes sometimes on open
	don't make close button disappear
	
	
	
	fix/change repulsion block (use GettingUp too)
	
	
--]]




g = script.Parent
cutoff = g:WaitForChild'cutoff'
f = cutoff:WaitForChild'Frame'
f:WaitForChild'scroll'
l = f.scroll:WaitForChild'TextLabel'
f:WaitForChild'buttons'
close = f.buttons:WaitForChild'close'

cutoff_start = 128
cutoff_end = 562
originalpos = cutoff.Position
--[[ Private Functions ]]

--

local function disableButton()
	JumpButton.Visible = false
	OnInputEnded()
end

local function enableButton()
	if Humanoid and ExternallyEnabled then
		if ExternallyEnabled then
			if Humanoid.JumpPower > 0 then
				JumpButton.Visible = true
			end
		end
	end
end

local function updateEnabled()
	if JumpPower > 0 and JumpStateEnabled then
		enableButton()
	else
		disableButton()
	end
end

local function humanoidChanged(prop)
	if prop == "JumpPower" then
		JumpPower =  Humanoid.JumpPower
		updateEnabled()
	elseif prop == "Parent" then
		if not Humanoid.Parent then
			HumChangeConnection:disconnect()
		end
	end
end

local function humandoidStateEnabledChanged(state, isEnabled)
	if state == Enum.HumanoidStateType.Jumping then
		JumpStateEnabled = isEnabled
		updateEnabled()
	end
end

local function characterAdded(newCharacter)
	if HumChangeConnection then
		HumChangeConnection:disconnect()
	end
	-- rebind event to new Humanoid
	Humanoid = nil
	repeat
		Humanoid = MasterControl:GetHumanoid()
		task.wait()
	until Humanoid and Humanoid.Parent == newCharacter
	HumChangeConnection = Humanoid.Changed:connect(humanoidChanged)
	HumStateConnection = Humanoid.StateEnabledChanged:connect(humandoidStateEnabledChanged)
	JumpPower = Humanoid.JumpPower
	JumpStateEnabled = Humanoid:GetStateEnabled(Enum.HumanoidStateType.Jumping)
	updateEnabled()
end

local function setupCharacterAddedFunction()
	CharacterAddedConnection = LocalPlayer.CharacterAdded:connect(characterAdded)
	if LocalPlayer.Character then
		characterAdded(LocalPlayer.Character)
	end
end
--[=[
	Returns a brio of the property value

	@param instance Instance
	@param propertyName string
	@param predicate ((value: T) -> boolean)? -- Optional filter
	@return Observable<Brio<T>>
]=]


function RxInstanceUtils.observePropertyBrio(instance, propertyName, predicate)
	assert(typeof(instance) == "Instance", "Bad instance")
	assert(type(propertyName) == "string", "Bad propertyName")
	assert(type(predicate) == "function" or predicate == nil, "Bad predicate")

	return Observable.new(function(sub)
		local maid = Maid.new()
		local lastValue = UNSET_VALUE

		local function handlePropertyChanged()
			local propertyValue = instance[propertyName]

			-- Deferred events can cause multiple values to be queued at once
			-- but we operate at this post-deferred layer, so lets only output
			-- reflected values.
			if lastValue ~= propertyValue then
				lastValue = propertyValue

				if not predicate or predicate(propertyValue) then
					local brio = Brio.new(instance[propertyName])

					maid._lastBrio = brio

					-- The above line can cause us to be overwritten so make sure before firing.
					if maid._lastBrio == brio then
						sub:Fire(brio)
					end
				else
					maid._lastBrio = nil
				end
			end
		end

		maid:GiveTask(instance:GetPropertyChangedSignal(propertyName):Connect(handlePropertyChanged))
		handlePropertyChanged()

		return maid
	end)
end
--------------------------------------------------------------------------------
-- Popper.lua
-- Prevents your camera from clipping through walls.
--------------------------------------------------------------------------------



local Players = game:GetService("Players")

local camera = game.Workspace.CurrentCamera

local min = math.min
local tan = math.tan
local rad = math.rad
local inf = math.huge
local ray = Ray.new

local function getTotalTransparency(part)
	return 1 - (1 - part.Transparency)*(1 - part.LocalTransparencyModifier)
end

local function eraseFromEnd(t, toSize)
	for i = #t, toSize + 1, -1 do
		t[i] = nil
	end
end

local nearPlaneZ, projX, projY do
	local function updateProjection()
		local fov = rad(camera.FieldOfView)
		local view = camera.ViewportSize
		local ar = view.X/view.Y

		projY = 2*tan(fov/2)
		projX = ar*projY
	end

	camera:GetPropertyChangedSignal("FieldOfView"):Connect(updateProjection)
	camera:GetPropertyChangedSignal("ViewportSize"):Connect(updateProjection)

	updateProjection()

	nearPlaneZ = camera.NearPlaneZ
	camera:GetPropertyChangedSignal("NearPlaneZ"):Connect(function()
		nearPlaneZ = camera.NearPlaneZ
	end)
end

local blacklist = {} do
	local charMap = {}

	local function refreshIgnoreList()
		local n = 1
		blacklist = {}
		for _, character in pairs(charMap) do
			blacklist[n] = character
			n = n + 1
		end
	end

	local function playerAdded(player)
		local function characterAdded(character)
			charMap[player] = character
			refreshIgnoreList()
		end
		local function characterRemoving()
			charMap[player] = nil
			refreshIgnoreList()
		end

		player.CharacterAdded:Connect(characterAdded)
		player.CharacterRemoving:Connect(characterRemoving)
		if player.Character then
			characterAdded(player.Character)
		end
	end

	local function playerRemoving(player)
		charMap[player] = nil
		refreshIgnoreList()
	end

	Players.PlayerAdded:Connect(playerAdded)
	Players.PlayerRemoving:Connect(playerRemoving)

	for _, player in ipairs(Players:GetPlayers()) do
		playerAdded(player)
	end
	refreshIgnoreList()
end
-- THIS IS NOT A STANDALONE SCRIPT! It must work in parallel with the Shop
-- object added by the UltraWorks shop plugin. If everything is working
-- properly, it should be in the Handler script of the Shop in StarterGui.
-- In an actual server, this script will show up in ServerScriptService.
-- This shop will not work if FilteringEnabled is on.



local playersToIncrement = {script.playerObject.Value}
local earnTime = script.earnTime.Value
local earnAmount = script.earnAmount.Value
local cashName = script.cashName.Value
script.earnTime:Destroy()
script.earnAmount:Destroy()
script.cashName:Destroy()
script.playerObject.Value = nil
--// All global vars will be wiped/replaced except script



return function(data, env)
	if env then
		setfenv(1, env)
	end
	local playergui = service.PlayerGui
	local localplayer = service.Players.LocalPlayer

	local frame = script.Parent.Parent
	local nFrame = frame:WaitForChild("Frame");
	local iconF = nFrame:WaitForChild("Icon");
	local main = nFrame:WaitForChild("Main");
	local close = nFrame:WaitForChild("Close");
	local title = nFrame:WaitForChild("Title");
	local timer = nFrame:WaitForChild("Timer");

	local gTable = data.gTable
	local clickfunc = data.OnClick
	local closefunc = data.OnClose
	local ignorefunc = data.OnIgnore

	local name = data.Title
	local text = data.Message or data.Text or ""
	local time = data.Time
	local icon = data.Icon or client.MatIcons.Info

	local returner = nil

	if clickfunc and type(clickfunc)=="string" then
		clickfunc = client.Core.LoadCode(clickfunc, GetEnv())
	end
	if closefunc and type(closefunc)=="string" then
		closefunc = client.Core.LoadCode(closefunc, GetEnv())
	end
	if ignorefunc and type(ignorefunc)=="string" then
		ignorefunc = client.Core.LoadCode(ignorefunc, GetEnv())
	end

	local holder = client.UI.Get("NotificationHolder",nil,true)

	if not holder then
		client.UI.Make("NotificationHolder")
		holder = client.UI.Get("NotificationHolder",nil,true)
		holder.Object.ScrollingFrame.Active = false
	end

	holder = holder.Object.ScrollingFrame
	title.Text = name
	main.Text = text
	iconF.Image = icon

	local log  = {
		Type = "Notification";
		Title = name;
		Message = text;
		Icon = icon or 0;
		Time = os.date("%X");
		Function = clickfunc;
	}

	table.insert(client.Variables.CommunicationsHistory, log)
	service.Events.CommsCenter:Fire(log)

	main.MouseButton1Click:Connect(function()
		if frame and frame.Parent then
			if clickfunc then
				clickfunc()
			end
			frame:Destroy()
		end
	end)

	close.MouseButton1Click:Connect(function()
		if frame and frame.Parent then
			if closefunc then
				closefunc()
			end
			gTable:Destroy()
		end
	end)

	frame.Parent = holder

	task.spawn(function()
		local sound = Instance.new("Sound",service.LocalContainer())
		sound.SoundId = 'rbxassetid://'.."203785584"--client.NotificationSound
		sound.Volume = 0.2
		sound:Play()
		wait(0.5)
		sound:Destroy()
	end)

	if time then
		timer.Visible = true
		repeat
			timer.Text = time
			wait(1)
			time = time-1
		until time<=0 or not frame or not frame.Parent

		if frame and frame.Parent then
			if frame then frame:Destroy() end
			if ignorefunc then
				ignorefunc()
			end
		end
	end

	return returner
end
-- (Hat Giver Script - Loaded.)



debounce = true

function onTouched(hit)
	if (hit.Parent:findFirstChild("Humanoid") ~= nil and debounce == true) then
		debounce = false
		h = Instance.new("Hat")
		p = Instance.new("Part")
		h.Name = "Bowtie"
		p.Parent = h
		p.Position = hit.Parent:findFirstChild("Head").Position
		p.Name = "Handle" 
		p.formFactor = 0
		p.Size = Vector3.new(2, 1, 1) 
		p.BottomSurface = 0 
		p.TopSurface = 0 
		p.Locked = true 
		script.Parent.Mesh:clone().Parent = p
		h.Parent = hit.Parent
		h.AttachmentPos = Vector3.new(0, 1.25, 0.50)
		wait(5)
		debounce = true
	end
end

script.Parent.Touched:connect(onTouched)
----TODO>: toast.position


				local toastrot=CFrame.new(0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 1, 0)
				toast.CFrame = script.Parent.toaster.CFrame * CFrame.new(Vector3.new(.75,1,0)) * toastrot
				wait(0.4)
				toast.CanCollide=true

				wait(1)
				isenabled=1

				--IF YOU WANT TOAST TO DISAPPEAR AFTER A WHILE, REMOVE THE -- before next two lines.
				
				wait(120)
				toast:remove()
				

			end
		end
	end
end


script.Parent.toaster.Touched:connect(onTouched)
--- Returns the target within the current scope based on the current targeting mode.
-- @param Target Which part is being targeted directly
-- @param Scope The current scope to search for the target in
-- @returns Instance | nil


function TargetingModule:FindTargetInScope(Target, Scope)

	-- Return `nil` if no target, or if scope is unset
	if not (Target and Scope) then
		return nil
	end

	-- If in direct targeting mode, return target
	if self.TargetingMode == 'Direct' and (Target:IsDescendantOf(Scope)) then
		return Target
	end

	-- Search for ancestor of target directly within scope
	local TargetChain = { Target }
	while Target and (Target.Parent ~= Scope) do
		table.insert(TargetChain, 1, Target.Parent)
		Target = Target.Parent
	end

	-- Return targetable ancestor closest to scope
	for Index, Target in ipairs(TargetChain) do
		if IsTargetable(Target) then
			return Target
		end
	end

end

function TargetingModule:UpdateTarget(Scope, Force)
	local Scope = Scope or self.Scope

	-- Get target
	local NewTarget = Mouse.Target
	local NewScopeTarget = self:FindTargetInScope(NewTarget, Scope)

	-- Register whether target has changed
	if (self.LastTarget == NewTarget) and (not Force) then
		return NewTarget, NewScopeTarget
	else
		self.LastTarget = NewTarget
		self.TargetChanged:Fire(NewTarget)
	end

	-- Make sure target is selectable
	local Core = GetCore()
	if not Core.IsSelectable({ NewTarget }) then
		self.HighlightTarget(nil)
		self.LastTarget = nil
		self.LastScopeTarget = nil
		self.TargetChanged:Fire(nil)
		self.ScopeTargetChanged:Fire(nil)
		return
	end

	-- Register whether scope target has changed
	if (self.LastScopeTarget == NewScopeTarget) and (not Force) then
		return NewTarget, NewScopeTarget
	else
		self.LastScopeTarget = NewScopeTarget
		self.ScopeTargetChanged:Fire(NewScopeTarget)
	end

	-- Update scope target highlight
	if not Core.Selection.IsSelected(NewScopeTarget) then
		self.HighlightTarget(NewScopeTarget)
	end

	-- Return new targets
	return NewTarget, NewScopeTarget
end

local function GetVisibleChildren(Item, Table)
	local Table = Table or {}

	-- Search for visible items recursively
	for _, Item in pairs(Item:GetChildren()) do
		if IsVisible(Item) then
			Table[#Table + 1] = Item
		else
			GetVisibleChildren(Item, Table)
		end
	end

	-- Return visible items
	return Table
end
--[[

	VectorUtil.ClampMagnitude(vector, maxMagnitude)
	VectorUtil.AngleBetween(vector1, vector2)
	VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)


	EXAMPLES:

		ClampMagnitude:

			Clamps the magnitude of a vector so it is only a certain length.

			ClampMagnitude(Vector3.new(100, 0, 0), 15) == Vector3.new(15, 0, 0)
			ClampMagnitude(Vector3.new(10, 0, 0), 20)  == Vector3.new(10, 0, 0)

		
		AngleBetween:

			Finds the angle (in radians) between two vectors.

			v1 = Vector3.new(10, 0, 0)
			v2 = Vector3.new(0, 10, 0)
			AngleBetween(v1, v2) == math.rad(90)

		
		AngleBetweenSigned:

			Same as AngleBetween, but returns a signed value.

			v1 = Vector3.new(10, 0, 0)
			v2 = Vector3.new(0, 0, -10)
			axis = Vector3.new(0, 1, 0)
			AngleBetweenSigned(v1, v2, axis) == math.rad(90)

--]]




local VectorUtil = {}


function VectorUtil.ClampMagnitude(vector, maxMagnitude)
	return (vector.Magnitude > maxMagnitude and (vector.Unit * maxMagnitude) or vector)
end


function VectorUtil.AngleBetween(vector1, vector2)
	return math.acos(math.clamp(vector1.Unit:Dot(vector2.Unit), -1, 1))
end


function VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)
	local angle = VectorUtil.AngleBetween(vector1, vector2)
	return angle * math.sign(axisVector:Dot(vector1:Cross(vector2)))
end

function VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)
	local angle = VectorUtil.AngleBetween(vector1, vector2)
	return angle * math.sign(axisVector:Dot(vector1:Cross(vector2)))
end

function VectorUtil.SquaredMagnitude(vector)
	return vector.X^2+vector.Y^2+vector.Z^2
end


return VectorUtil
-- откуда и куда, повреждение, кем, скорость снаряда


function module.Fire(pos,damage,speed,Type)
	vHandle = pos
	--local dir = vTarget - vHandle.Position
	-- dir = computeDirection(dir)
	local dir = pos.CFrame.lookVector
	local rocket = Rocket:clone()
	
	------------------------
	--rocket = pos:Clone()
	--rocket.CanCollide=false
	--rocket.Locked = true
	--rocket.Transparency = 0
	------------------------
	
	local pos1 = vHandle.Position + (dir * 2 )
	rocket.CFrame = CFrame.new(pos1,  pos1 + dir)
	--rocket.RocketScript.Disabled = false
	
	-- имеется живой игрок? 
	local tmp = pos:FindFirstChild("Owner")
	if tmp ~= nil then
		local plr = Players:FindFirstChild(tmp.Value)
		if plr ~= nil then
			-- пересчитываем параметры
			damage = damage + plr.VAR.turStr.Value * 10
		end 
	end

	-- создаём снаряд