function Path.Destroy(R)for R,p in ipairs(R._events)do p:Destroy()end R._events=nil if rawget(R,"\095\118\105\115\117\097\108\087\097\121\112\111\105\110\116\115")then R._visualWaypoints=destroyVisualWaypoints(R._visualWaypoints)end R._path:Destroy()setmetatable(R,nil)for p,s in pairs(R)do R[p]=nil end end function Path.Stop(R)if not R._humanoid then output(error,"\065\116\116\101\109\112\116 \116\111 \099\097\108\108 \080\097\116\104\058\083\116\111\112\040\041 \111\110 \097 \110\111\110-\104\117\109\097\110\111\105\100\046")return end if R._status==Path.StatusType.Idle then output(function(R)warn(debug.traceback(R))end,"\065\116\116\101\109\112\116 \116\111 \114\117\110 \080\097\116\104\058\083\116\111\112\040\041 \105\110 \105\100\108\101 \115\116\097\116\101")return end disconnectMoveConnection(R)R._status=Path.StatusType.Idle R._visualWaypoints=destroyVisualWaypoints(R._visualWaypoints)R._events.Stopped:Fire(R._model)end function Path.Run(p,R)if not R and(not p._humanoid and p._target)then moveToFinished(p,true)return end if not(R and(typeof(R)=="\086\101\099\116\111\114\051"or R:IsA("\066\097\115\101\080\097\114\116")))then output(error,"\080\097\116\104\102\105\110\100\105\110\103 \116\097\114\103\101\116 \109\117\115\116 \098\101 \097 \118\097\108\105\100 \086\101\099\116\111\114\051 \111\114 \066\097\115\101\080\097\114\116\046")end if os.clock()-p._t<=p._settings.TIME_VARIANCE and p._humanoid then task.wait(os.clock()-p._t)declareError(p,p.ErrorType.LimitReached)return false elseif p._humanoid then p._t=os.clock()end local s,A=pcall(function()p._path:ComputeAsync(p._agent.PrimaryPart.Position,typeof(R)=="\086\101\099\116\111\114\051"and R or R.Position)end)if not s or p._path.Status==Enum.PathStatus.NoPath or#p._path:GetWaypoints()<2 or p._humanoid and p._humanoid:GetState()==Enum.HumanoidStateType.Freefall then p._visualWaypoints=destroyVisualWaypoints(p._visualWaypoints)task.wait()declareError(p,p.ErrorType.ComputationError)return false end p._status=p._humanoid and Path.StatusType.Active or Path.StatusType.Idle p._target=R pcall(function()p._agent.PrimaryPart:SetNetworkOwner(nil)end)p._waypoints=p._path:GetWaypoints()p._currentWaypoint=2 if p._humanoid then comparePosition(p)end destroyVisualWaypoints(p._visualWaypoints)p._visualWaypoints=p.Visualize and createVisualWaypoints(p._waypoints)p._moveConnection=p._humanoid and(p._moveConnection or p._humanoid.MoveToFinished:Connect(function(...)moveToFinished(p,...)end))if p._humanoid then p._humanoid:MoveTo(p._waypoints[p._currentWaypoint].Position)elseif#p._waypoints==2 then p._target=nil p._visualWaypoints=destroyVisualWaypoints(p._visualWaypoints)p._events.Reached:Fire(p._agent,p._waypoints[2])else p._currentWaypoint=getNonHumanoidWaypoint(p)moveToFinished(p,true)end return true end return Path
--[[ NON-STATIC METHODS ]]
--
function Path:Destroy()
	for _, event in ipairs(self._events) do
		event:Destroy()
	end
	self._events = nil
	if rawget(self, "_visualWaypoints") then
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	end
	self._path:Destroy()
	setmetatable(self, nil)
	for k, _ in pairs(self) do
		self[k] = nil
	end
end

function Path:Stop()
	if not self._humanoid then
		output(error, "Attempt to call Path:Stop() on a non-humanoid.")
		return
	end
	if self._status == Path.StatusType.Idle then
		output(function(m)
			warn(debug.traceback(m))
		end, "Attempt to run Path:Stop() in idle state")
		return
	end
	disconnectMoveConnection(self)
	self._status = Path.StatusType.Idle
	self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	self._events.Stopped:Fire(self._model)
end

function Path:Run(target)
	--Non-humanoid handle case
	if not target and not self._humanoid and self._target then
		moveToFinished(self, true)
		return
	end

	--Parameter check
	if not (target and (typeof(target) == "Vector3" or target:IsA("BasePart"))) then
		output(error, "Pathfinding target must be a valid Vector3 or BasePart.")
	end

	--Refer to Settings.TIME_VARIANCE
	if os.clock() - self._t <= self._settings.TIME_VARIANCE and self._humanoid then
		task.wait(os.clock() - self._t)
		declareError(self, self.ErrorType.LimitReached)
		return false
	elseif self._humanoid then
		self._t = os.clock()
	end

	--Compute path
	local pathComputed, _ = pcall(function()
		self._path:ComputeAsync(
			self._agent.PrimaryPart.Position,
			(typeof(target) == "Vector3" and target) or target.Position
		)
	end)

	--Make sure path computation is successful
	if
		not pathComputed
		or self._path.Status == Enum.PathStatus.NoPath
		or #self._path:GetWaypoints() < 2
		or (self._humanoid and self._humanoid:GetState() == Enum.HumanoidStateType.Freefall)
	then
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		task.wait()
		declareError(self, self.ErrorType.ComputationError)
		return false
	end

	--Set status to active; pathfinding starts
	self._status = (self._humanoid and Path.StatusType.Active) or Path.StatusType.Idle
	self._target = target

	--Set network owner to server to prevent "hops"
	pcall(function()
		self._agent.PrimaryPart:SetNetworkOwner(nil)
	end)

	--Initialize waypoints
	self._waypoints = self._path:GetWaypoints()
	self._currentWaypoint = 2

	--Refer to Settings.COMPARISON_CHECKS
	if self._humanoid then
		comparePosition(self)
	end

	--Visualize waypoints
	destroyVisualWaypoints(self._visualWaypoints)
	self._visualWaypoints = (self.Visualize and createVisualWaypoints(self._waypoints))

	--Create a new move connection if it doesn't exist already
	self._moveConnection = self._humanoid
		and (
			self._moveConnection
			or self._humanoid.MoveToFinished:Connect(function(...)
				moveToFinished(self, ...)
			end)
		)

	--Begin pathfinding
	if self._humanoid then
		self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position)
	elseif #self._waypoints == 2 then
		self._target = nil
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		self._events.Reached:Fire(self._agent, self._waypoints[2])
	else
		self._currentWaypoint = getNonHumanoidWaypoint(self)
		moveToFinished(self, true)
	end
	return true
end

return Path
