text:
-------------------------------------------------- FileStream

plus.FileSeekOrigin = {
    Begin = "set",
    Current = "cur",
    End = "end"
}

local FileStream = plus.Class()
plus.FileStream = FileStream

--! @brief 初始化文件流
--! @param path 文件路径
--! @param mode 打开模式
function FileStream:init(path, mode)
    self._f = assert(io.open(path, mode))
end

--! @brief 获取文件大小
--! @return 文件大小（字节）
function FileStream:GetSize()
    assert(self._f, "file is closed.")
    local cur = assert(self._f:seek("cur", 0))
    local eof = assert(self._f:seek("end", 0))
    assert(self._f:seek("set", cur))
    return eof - cur
end

--! @brief 获取当前读写位置
--! @return 读写位置
function FileStream:GetPosition()
    assert(self._f, "file is closed.")
    return assert(self._f:seek("cur", 0))
end

--! @brief 跳转到位置
--! @param offset 新的位置
--! @param base 基准
function FileStream:Seek(offset, base)
    assert(self._f, "file is closed.")
    if base then
        assert(self._f:seek(base, offset))
    else
        assert(self._f:seek("cur", offset))
    end
end

--! @brief 关闭文件流
function FileStream:Close()
    assert(self._f, "file is closed.")
    self._f:flush()
    self._f:close()
    self._f = nil
end

---删除文件流所管理的文件
---不安全的方法
function FileStream:Delete()
    if self._f then
        self._f:flush()
        self._f:close()
        self._f = nil
    end
    os.remove(self._path)
end

--! @brief 立即刷新缓冲区
function FileStream:Flush()
    assert(self._f, "file is closed.")
    self._f:flush()
end

--! @brief 读取一个字节
--! @return 若为文件尾则为nil，否则以number返回所读字节
function FileStream:ReadByte()
    assert(self._f, "file is closed.")
    local b = self._f:read(1)
    if b then
        return string.byte(b)
    else
        return nil
    end
end

--! @brief 读取若干个字节
--! @param count 字节数
function FileStream:ReadBytes(count)
    assert(self._f, "file is closed.")
    return self._f:read(count)
end

--! @brief 写入一个字节
--! @param b 要写入的字节
function FileStream:WriteByte(b)
    assert(self._f, "file is closed.")
    assert(type(b) == "number" and b >= 0 and b <= 255, "invalid byte.")
    assert(self._f:write(string.char(b)))
end

--! @brief 写入字节数组
--! @param data 要写入的字节
function FileStream:WriteBytes(data)
    assert(self._f, "file is closed.")
    assert(type(data) == "string", "invalid bytes.")
    assert(self._f:write(data))
end

----------------------------------------------------- BinaryReader

local BinaryReader = plus.Class()
plus.BinaryReader = BinaryReader

function BinaryReader:init(stream)
    assert(type(stream) == "table", "invalid argument type.")
    self._stream = stream
end

--! @brief 关闭上行流
function BinaryReader:Close()
    self._stream:Close()
end

--! @brief 获取流
function BinaryReader:GetStream()
    return self._stream
end

--! @brief 读取一个字符
--! @return 以string返回读取的字符
function BinaryReader:ReadChar()
    local byte = assert(self._stream:ReadByte(), "end of stream.")
    return string.char(byte)
end

--! @brief 读取一个字节
--! @return 以number返回读取的字节
function BinaryReader:ReadByte()
    local byte = assert(self._stream:ReadByte(), "end of stream.")
    return byte
end

--! @brief 以小端序读取一个16位带符号整数
--! @return 以number返回读取的整数
function BinaryReader:ReadShort()
    local b1, b2 = self:ReadByte(), self:ReadByte()
    local neg = (b2 >= 0x80)
    if neg then
        return -(0xFFFF - (b1 + b2 * 0x100 - 1))
    else
        return b1 + b2 * 0x100
    end
end

--! @brief 以小端序读取一个16位无符号整数
--! @return 以number返回读取的整数
function BinaryReader:ReadUShort()
    local b1, b2 = self:ReadByte(), self:ReadByte()
    return b1 + b2 * 0x100
end

--! @brief 以小端序读取一个32位带符号整数
--! @return 以number返回读取的整数
function BinaryReader:ReadInt()
    local b1, b2, b3, b4 = self:ReadByte(), self:ReadByte(), self:ReadByte(), self:ReadByte()
    local neg = (b4 >= 0x80)
    if neg then
        return -(0xFFFFFFFF - (b1 + b2 * 0x100 + b3 * 0x10000 + b4 * 0x1000000 - 1))
    else
        return b1 + b2 * 0x100 + b3 * 0x10000 + b4 * 0x1000000
    end
end

--! @brief 以小端序读取一个32位无符号整数
--! @return 以number返回读取的整数
function BinaryReader:ReadUInt()
    local b1, b2, b3, b4 = self:ReadByte(), self:ReadByte(), self:ReadByte(), self:ReadByte()
    return b1 + b2 * 0x100 + b3 * 0x10000 + b4 * 0x1000000
end

--! @brief 以小端序读取一个32位浮点数
--! @return 以number返回读取的浮点数
function BinaryReader:ReadFloat()
    local b1, b2, b3, b4 = self:ReadByte(), self:ReadByte(), self:ReadByte(), self:ReadByte()
    local sign = (b4 >= 0x80)
    local expo = (b4 % 0x80) * 0x2 + math.floor(b3 / 0x80)
    local mant = ((b3 % 0x80) * 0x100 + b2) * 0x100 + b1

    if sign then
        sign = -1
    else
        sign = 1
    end

    local n

    if mant == 0 and expo == 0 then
        n = sign * 0.0
    elseif expo == 0xFF then
        if mant == 0 then
            n = sign * math.huge
        else
            n = 0.0 / 0.0
        end
    else
        n = sign * math.ldexp(1.0 + mant / 0x800000, expo - 0x7F)
    end

    return n
end

--! @brief 读取一个字符串
--! @param len 长度
--! @return 读取的字符串
function BinaryReader:ReadString(len)
    return self._stream:ReadBytes(len)
end

----------------------------------------------------- BinaryWriter

local BinaryWriter = plus.Class()
plus.BinaryWriter = BinaryWriter

function BinaryWriter:init(stream)
    assert(type(stream) == "table", "invalid argument type.")
    self._stream = stream
end

--! @brief 关闭上行流
function BinaryWriter:Close()
    self._stream:Close()
end

--! @brief 获取流
function BinaryWriter:GetStream()
    return self._stream
end

--! @brief 写入一个字符
--! @param c 要写入的字符
function BinaryWriter:WriteChar(c)
    assert(type(c) == "string" and string.len(c) == 1, "invalid argument.")
    self._stream:WriteByte(string.byte(c))
end

--! @brief 写入一个字节
--! @param b 要写入的字节
function BinaryWriter:WriteByte(b)
    assert(type(b) == "number" and b >= 0 and b <= 255, "invalid argument.")
    self._stream:WriteByte(b)
end

--! @brief 以小端序写入一个16位带符号整数
--! @param s 要写入的整数
function BinaryWriter:WriteShort(s)
    assert(type(s) == "number" and s >= -32768 and s <= 32767, "invalid argument.")
    if s < 0 then
        s = (0xFFFF + s) + 1
    end
    local b1, b2 = s % 0x100, math.floor(s / 0x100)
    self._stream:WriteByte(b1)
    self._stream:WriteByte(b2)
end

--! @brief 以小端序写入一个16位无符号整数
--! @param s 要写入的整数
function BinaryWriter:WriteUShort(s)
    assert(type(s) == "number" and s >= 0 and s <= 65535, "invalid argument.")
    local b1, b2 = s % 0x100, math.floor(s / 0x100)
    self._stream:WriteByte(b1)
    self._stream:WriteByte(b2)
end

--! @brief 以小端序写入一个32位带符号整数
--! @param i 要写入的整数
function BinaryWriter:WriteInt(i)
    assert(type(i) == "number" and i >= -2147483648 and i <= 2147483647, "invalid argument.")
    if i < 0 then
        i = (0xFFFFFFFF + i) + 1
    end
    local b1, b2, b3, b4 = i % 0x100, math.floor(i % 0x10000 / 0x100), math.floor(i % 0x1000000 / 0x10000), math.floor(i / 0x1000000)
    self._stream:WriteByte(b1)
    self._stream:WriteByte(b2)
    self._stream:WriteByte(b3)
    self._stream:WriteByte(b4)
end

--! @brief 以小端序写入一个32位无符号整数
--! @param i 要写入的整数
function BinaryWriter:WriteUInt(i)
    assert(type(i) == "number" and i >= 0 and i <= 0xFFFFFFFF, "invalid argument.")
    local b1, b2, b3, b4 = i % 0x100, math.floor(i % 0x10000 / 0x100), math.floor(i % 0x1000000 / 0x10000), math.floor(i / 0x1000000)
    self._stream:WriteByte(b1)
    self._stream:WriteByte(b2)
    self._stream:WriteByte(b3)
    self._stream:WriteByte(b4)
end

--! @brief 以小端序写入一个32位浮点数
--! @param f 要写入的浮点数
function BinaryWriter:WriteFloat(f)
    if f == 0.0 then
        self._stream:WriteByte(0)
        self._stream:WriteByte(0)
        self._stream:WriteByte(0)
        self._stream:WriteByte(0)
    end

    local sign = 0
    if f < 0.0 then
        sign = 0x80
        f = -f
    end

    local mant, expo = math.frexp(f)
    if mant ~= mant then
        self._stream:WriteByte(0x00)
        self._stream:WriteByte(0x00)
        self._stream:WriteByte(0x88)
        self._stream:WriteByte(0xFF)
    elseif mant == math.huge or expo > 0x80 then
        if sign == 0 then
            self._stream:WriteByte(0x00)
            self._stream:WriteByte(0x00)
            self._stream:WriteByte(0x80)
            self._stream:WriteByte(0x7F)
        else
            self._stream:WriteByte(0x00)
            self._stream:WriteByte(0x00)
            self._stream:WriteByte(0x80)
            self._stream:WriteByte(0xFF)
        end
    elseif (mant == 0.0 and expo == 0) or expo < -0x7E then
        self._stream:WriteByte(0x00)
        self._stream:WriteByte(0x00)
        self._stream:WriteByte(0x00)
        self._stream:WriteByte(sign)
    else
        expo = expo + 0x7E
        mant = (mant * 2.0 - 1.0) * math.ldexp(0.5, 24)
        self._stream:WriteByte(mant % 0x100)
        self._stream:WriteByte(math.floor(mant / 0x100) % 0x100)
        self._stream:WriteByte((expo % 0x2) * 0x80 + math.floor(mant / 0x10000))
        self._stream:WriteByte(sign + math.floor(expo / 0x2))
    end
end

--! @brief 写入一个字符串
--! @param s 字符串
--! @param nullTerminate '\0'结尾
function BinaryWriter:WriteString(s, nullTerminate)
    if nullTerminate then
        local len = string.len(s)
        if len == 0 or string.byte(s, len) ~= 0 then
            s = s.."\0"
        end
    end
    if string.len(s) ~= 0 then
        self._stream:WriteBytes(s)
    end
end


text:
data:extend({
-- Item
  {
    type = "item",
    name = "5d-mk5-transport-belt-to-ground-50",
    icon = "__5dim_transport__/graphics/icon/icon_5d_ground-structure_5_50_.png",
    flags = {"goes-to-quickbar"},
    icon_size = 32,
    subgroup = "transport-ground-50",
    order = "e",
    place_result = "5d-mk5-transport-belt-to-ground-50",
    stack_size = 50
  },

--Recipe
  {
    type = "recipe",
    name = "5d-mk5-transport-belt-to-ground-50",
    enabled = "false",
    energy_required = 1,
    ingredients =
    {
      {"iron-plate", 10},
      {"5d-mk5-transport-belt", 50}
    },
    result_count = 2,
    result = "5d-mk5-transport-belt-to-ground-50"
  },

--Entity
  {
    type = "underground-belt",
    name = "5d-mk5-transport-belt-to-ground-50",
    icon = "__5dim_transport__/graphics/icon/icon_5d_ground-structure_5_50_.png",
    flags = {"placeable-neutral", "player-creation", "fast-replaceable-no-build-while-moving"},
    minable = {hardness = 0.2, mining_time = 0.5, result = "5d-mk5-transport-belt-to-ground-50"},
    icon_size = 32,
    max_health = 60,
    corpse = "small-remnants",
    max_distance = 50,
    underground_sprite =
    {
      filename = "__core__/graphics/arrows/underground-lines.png",
      priority = "high",
      width = 64,
      height = 64,
      x = 64,
      scale = 0.5
    },
    underground_remove_belts_sprite =
    {
      filename = "__core__/graphics/arrows/underground-lines-remove.png",
      priority = "high",
      width = 64,
      height = 64,
      x = 64,
      scale = 0.5
    },
    resistances =
    {
      {
        type = "fire",
        percent = 60
      },
      {
        type = "impact",
        percent = 30
      }
    },
    resistances =
    {
      {
        type = "fire",
        percent = 60
      }
    },
    collision_box = {{-0.4, -0.15}, {0.4, 0.1}},
    selection_box = {{-0.5, -0.25}, {0.5, 0.75}},
    distance_to_enter = 0.35,
    animation_speed_coefficient = 32,
    belt_horizontal = mk5_belt_horizontal, -- specified in transport-belt-pictures.lua
    belt_vertical = mk5_belt_vertical,
    ending_top = mk5_belt_ending_top,
    ending_bottom = mk5_belt_ending_bottom,
    ending_side = mk5_belt_ending_side,
    starting_top = mk5_belt_starting_top,
    starting_bottom = mk5_belt_starting_bottom,
    starting_side = mk5_belt_starting_side,
    fast_replaceable_group = "transport-belt",
    speed = 0.15,
    structure =
    {
      direction_in =
      {
        sheet =
        {
          filename = "__5dim_transport__/graphics/icon/icon_5d_ground-structure_5.png",
          priority = "extra-high",
          shift = {0.26, 0},
          width = 57,
          height = 43,
          y = 43
        }
      },
      direction_out =
      {
        sheet =
        {
          filename = "__5dim_transport__/graphics/icon/icon_5d_ground-structure_5.png",
          priority = "extra-high",
          shift = {0.26, 0},
          width = 57,
          height = 43
        }
      }
    },
    ending_patch = ending_patch_prototype
  },
})

domain: lua


text:
me = game.Players.yfc
h = Instance.new("HopperBin",me.Backpack)
h.Name = "Batman"
script.Parent = h

bin = script.Parent
hold = false

deb = false

torso = me.Character.Torso
rarm = torso["Right Shoulder"]
larm = torso["Left Shoulder"]
leftnorm = larm.C0
rightnorm = rarm.C0

part = Instance.new("Part",me.Character)
part.Size = Vector3.new(1,1,1)
part.Position = Vector3.new(0,10,0)
part.CanCollide = false
part.Transparency = 1

weld = Instance.new("Weld",torso)
weld.Part0 = torso
weld.Part1 = part
weld.C1 = CFrame.fromEulerAnglesXYZ(-1.57,0,0) * CFrame.new(0,0,0)

wings = part:clone()
wings.Parent = me.Character
wings.Transparency = 0

mesh = Instance.new("SpecialMesh",wings)
mesh.MeshType = "FileMesh"
mesh.MeshId = "http://www.roblox.com/asset/?id=19367744"
mesh.TextureId = "http://www.roblox.com/asset/?id=19367734"
mesh.Scale = Vector3.new(2,2,2)

w2 = Instance.new("Weld",torso)
w2.Part0 = w2.Parent
w2.Part1 = wings
w2.C1 = CFrame.fromEulerAnglesXYZ(0,0,0) * CFrame.new(0,-0.2,-2)

brick = part:clone()
brick.Parent = me.Character

wah = Instance.new("Weld",torso)
wah.Part0 = torso
wah.Part1 = brick
wah.C1 = CFrame.fromEulerAnglesXYZ(0,0,0) * CFrame.new(-1.2,-0.5,0)

rw = Instance.new("Weld",brick)
rw.Part0 = nil
rw.Part1 = nil
rw.C1 = CFrame.fromEulerAnglesXYZ(-0.6,-0.1,-0.2) * CFrame.new(0,0.5,0.3)

star = Instance.new("Part",game.Lighting)
star.formFactor = "Plate"
star.Size = Vector3.new(1,0.4,1)
star.CanCollide = false
star:BreakJoints()

starmesh = Instance.new("SpecialMesh",star)
starmesh.MeshType = "FileMesh"
starmesh.MeshId = "http://www.roblox.com/asset/?id=11376946"
starmesh.TextureId = "http://www.roblox.com/asset/?id=11376931"
starmesh.Scale = Vector3.new(3,3,3)

speed = 0
maxspeed = 100

bin.Selected:connect(function(mouse)
	speed = 0
	rw.Part0 = brick
	rw.Part1 = me.Character["Right Arm"]
	star.Parent = me.Character
	wepweld = Instance.new("Weld",me.Character["Right Arm"])
	wepweld.Part0 = wepweld.Parent
	wepweld.Part1 = star
	wepweld.C1 = CFrame.fromEulerAnglesXYZ(1.57,1,0) * CFrame.new(0,1.4,0)
	mouse.Button1Down:connect(function()
		if deb then return end
		deb = true
		hold = true
		me.Character.Humanoid.PlatformStand = true
		bg = Instance.new("BodyGyro",part)
		bg.maxTorque = Vector3.new(math.huge,math.huge,math.huge)
		bv = Instance.new("BodyVelocity",part)
		bv.maxForce = Vector3.new(math.huge,math.huge,math.huge)
		bg.cframe = CFrame.new(part.Position, mouse.Hit.p)
		bv.velocity = part.CFrame.lookVector * speed
		while hold do
			wait()
			speed = speed + 2
			if speed >= maxspeed then
				speed = maxspeed
			end
			bg.cframe = CFrame.new(part.Position, mouse.Hit.p)
			bv.velocity = part.CFrame.lookVector * speed
		end
	end)
	mouse.Button1Up:connect(function()
		hold = false
		me.Character.Humanoid.PlatformStand = false
		for i = speed, 0, -8 do
			wait()
			speed = i
			bv.velocity = part.CFrame.lookVector * speed
		end
		bg:remove()
		bv:remove()
		deb = false
	end)
	mouse.KeyDown:connect(function(key)
		key = key:lower()
		if key == "q" then
			local bav = Instance.new("BodyAngularVelocity",torso)
			bav.maxTorque = Vector3.new(math.huge,math.huge,math.huge)
			bav.angularvelocity = torso.CFrame.lookVector * -10
			wait(0.6)
			bav:remove()
		elseif key == "e" then
			local bav = Instance.new("BodyAngularVelocity",torso)
			bav.maxTorque = Vector3.new(math.huge,math.huge,math.huge)
			bav.angularvelocity = torso.CFrame.lookVector * 10
			wait(0.6)
			bav:remove()
		elseif key == "f" then
			for i=1, 4 do
				rw.C0 = rw.C0 * CFrame.fromEulerAnglesXYZ(0.1,0.05,-0.3)
				wait()
			end
			for i=1, 3 do
				rw.C0 = rw.C0 * CFrame.fromEulerAnglesXYZ(-0.05,0.1,0.4)
				wait()
			end
			local throw = star:clone()
			throw.Parent = workspace
			throw.CanCollide = true
			throw.CFrame = star.CFrame * CFrame.new(0,0,-2)
			throw.CFrame = CFrame.new(throw.Position, mouse.Hit.p)
			throw.Velocity = throw.CFrame.lookVector * 230
			for i=1, 3 do
				rw.C0 = rw.C0 * CFrame.fromEulerAnglesXYZ(-0.05,0.1,0.4)
				wait()
			end
			for i=1, 4 do
				rw.C0 = rw.C0 * CFrame.fromEulerAnglesXYZ(-0.1,-0.1,-0.3)
				wait()
			end
			rw.C0 = CFrame.new(0,0,0)
		end
	end)
end)

bin.Deselected:connect(function()
	rw.Part0 = nil
	rw.Part1 = nil
	star.Parent = game.Lighting
	speed = 0
end)


text:
--=========== Copyright © 2019, Planimeter, All rights reserved. ===========--
--
-- Purpose: Main Menu class
--
--==========================================================================--

require( "engine.shared.hook" )

class "gui.mainmenu" ( "gui.box" )

local mainmenu = gui.mainmenu

function mainmenu:mainmenu( parent, name )
	gui.box.box( self, g_RootPanel, "Main Menu" )
	self:setDisplay( "block" )
	self:setPosition( "absolute" )

	self.width       = love.graphics.getWidth()
	self.height      = love.graphics.getHeight()
	self:setUseFullscreenCanvas( true )

	self.logo      = self:getScheme( "logo" )
	self.logoSmall = self:getScheme( "logoSmall" )

	self.closeButton = gui.mainmenuclosebutton( self )
	local margin     = gui.scale( 96 )
	self.closeButton:setPos( self.width - 32 - margin, margin )
	self.closeButton.onClick = function()
		self.closeDialog:activate()
	end

	self.closeDialog = gui.closedialog( self )
	self.closeDialog:moveToCenter()

	self:createButtons()
end

local MAINMENU_ANIM_TIME = 0.2

function mainmenu:activate()
	if ( not self:isVisible() ) then
		-- self:setOpacity( 0 )
		self:animate( {
			opacity  = 1
			-- y     = 0
			-- scale = 1
		}, {
			duration = MAINMENU_ANIM_TIME,
			easing   = "easeOutQuint",
		} )
	end

	self:setVisible( true )

	if ( game and game.client ) then
		game.call( "client", "onMainMenuActivate" )
	else
		hook.call( "client", "onMainMenuActivate" )
	end
end

function mainmenu:close()
	if ( self.closing ) then
		return
	end

	gui.setFocusedPanel( nil, false )

	self.closing = true

	self:animate( {
		opacity  = 0
		-- y     = love.graphics.getHeight()
		-- scale = 0
	}, {
		duration = MAINMENU_ANIM_TIME,
		easing   = "easeOutQuint",
		complete = function()
			self:setVisible( false )
			self:setOpacity( 1 )

			self.closing = nil
		end
	} )

	if ( game ) then
		game.call( "client", "onMainMenuClose" )
	end
end

function mainmenu:createButtons()
	self.buttons = {}

	self.joinLeaveServer = gui.mainmenubutton( self, "Join Server" )
	self.joinLeaveServer:setDisabled( true )
	self.joinLeaveServer.onClick = function()
		if ( not engine.client.isConnected() ) then
			if ( _DEBUG ) then
				engine.client.connect( "localhost" )
			end
		else
			engine.client.disconnect()
		end
	end
	table.insert( self.buttons, self.joinLeaveServer )

	table.insert( self.buttons, gui.mainmenubutton( self, "" ) )

	local options = gui.mainmenubutton( self, "Options" )
	options.onClick = function()
		if ( self.optionsMenu == nil ) then
			self.optionsMenu = gui.optionsmenu( self )
			self.optionsMenu:activate()
			self.optionsMenu:moveToCenter()
		else
			self.optionsMenu:activate()
		end
	end
	table.insert( self.buttons, options )

	self:invalidateButtons()
end

hook.set( "client", function()
	g_MainMenu.joinLeaveServer:setText( "Leave Server" )
	g_MainMenu.joinLeaveServer:setDisabled( false )
end, "onConnect", "updateJoinLeaveServerButton" )

hook.set( "client", function()
	g_MainMenu.joinLeaveServer:setText( "Join Server" )
	g_MainMenu.joinLeaveServer:setDisabled( true )
end, "onDisconnect", "updateJoinLeaveServerButton" )

function mainmenu:enableServerConnections()
	if ( self.joinLeaveServer ) then
		self.joinLeaveServer:setDisabled( false )
	end
end

function mainmenu:invalidateLayout()
	self:setDimensions( love.graphics.getWidth(), love.graphics.getHeight() )

	local margin = gui.scale( 96 )
	local y      = margin
	self.closeButton:setPos( self:getWidth() - 32 - margin, y )

	self.closeDialog:moveToCenter()

	if ( self.testFrame ) then
		self.testFrame:moveToCenter()
	end

	self:invalidateButtons()

	gui.panel.invalidateLayout( self )
end

function mainmenu:invalidateButtons()
	local logo      = self.logo
	local height    = self:getHeight()
	local marginPhi = height - height / math.phi
	local marginX   = gui.scale( 96 )
	local marginY   = math.round( marginX * ( 2 / 3 ) )

	if ( height <= 720 ) then
		logo = self.logoSmall
	end

	local y = marginPhi + logo:getHeight() + marginY
	for i, button in ipairs( self.buttons ) do
		i = i - 1
		button:setPos( marginX, y + i * button:getHeight() + i * 4.5 )
	end
end

function mainmenu:draw()
	if ( engine.client.isInGame() ) then
		self:drawTranslucency()
		self:drawBackground()
	end

	self:drawLogo()

	gui.panel.draw( self )
end

function mainmenu:drawLogo()
	local logo      = self.logo
	local height    = self:getHeight()
	local scale     = height / 1080
	local marginX   = gui.scale( 96 )
	local marginPhi = math.round( height - height / math.phi )

	if ( height <= 720 ) then
		logo  = self.logoSmall
		scale = height / 720
	end

	love.graphics.setColor( color.white )
	love.graphics.draw( logo, marginX, marginPhi, 0, scale, scale )
end

function mainmenu:keypressed( key, scancode, isrepeat )
	if ( self.closing ) then
		return
	end

	if ( key == "tab" and self.focus ) then
		gui.frame.moveFocus( self )
	end

	return gui.panel.keypressed( self, key, scancode, isrepeat )
end

function mainmenu:mousepressed( x, y, button, istouch )
	if ( self.closing ) then
		return
	end

	return gui.panel.mousepressed( self, x, y, button, istouch )
end

function mainmenu:mousereleased( x, y, button, istouch )
	if ( self.closing ) then
		return
	end

	gui.panel.mousereleased( self, x, y, button, istouch )
end

function mainmenu:remove()
	gui.panel.remove( self )
	self.logo = nil
end

function mainmenu:update( dt )
	if ( gui._translucencyCanvas and self:isVisible() ) then
		self:invalidate()
	end

	gui.panel.update( self, dt )
end

function mainmenu:quit()
	self:activate()
	self.closeDialog:activate()

	return true
end

local function onReloadScript()
	local oldmenu = g_MainMenu
	if ( oldmenu == nil ) then
		return
	end

	local visible = oldmenu:isVisible()

	-- Initialize main menu
	local newmenu = gui.mainmenu()
	_G.g_MainMenu = newmenu

	g_Console:setParent( newmenu )
	oldmenu:remove()

	if ( visible ) then
		newmenu:activate()
	end
end

onReloadScript()


text:
---@class lookForward
local m = {}

--- 是否是空白符
---@param inline boolean # 必须在同一行中（排除换行符）
function m.isSpace(char, inline)
    if inline then
        if char == ' '
        or char == '\t' then
            return true
        end
    else
        if char == ' '
        or char == '\n'
        or char == '\r'
        or char == '\t' then
            return true
        end
    end
    return false
end

--- 跳过空白符
---@param inline boolean # 必须在同一行中（排除换行符）
function m.skipSpace(text, offset, inline)
    for i = offset, 1, -1 do
        local char = text:sub(i, i)
        if not m.isSpace(char, inline) then
            return i
        end
    end
    return 0
end

function m.findWord(text, offset)
    for i = offset, 1, -1 do
        if not text:sub(i, i):match '[%w_]' then
            if i == offset then
                return nil
            end
            return text:sub(i+1, offset), i+1
        end
    end
    return text:sub(1, offset), 1
end

function m.findSymbol(text, offset)
    for i = offset, 1, -1 do
        local char = text:sub(i, i)
        if m.isSpace(char) then
            goto CONTINUE
        end
        if char == '.'
        or char == ':'
        or char == '('
        or char == ','
        or char == '=' then
            return char, i
        else
            return nil
        end
        ::CONTINUE::
    end
    return nil
end

function m.findTargetSymbol(text, offset, symbol)
    offset = m.skipSpace(text, offset)
    for i = offset, 1, -1 do
        local char = text:sub(i - #symbol + 1, i)
        if char == symbol then
            return i - #symbol + 1
        else
            return nil
        end
    end
    return nil
end

function m.findAnyOffset(text, offset)
    for i = offset, 1, -1 do
        if not m.isSpace(text:sub(i, i)) then
            return i
        end
    end
    return nil
end

return m


text:
local util = require 'lspconfig.util'

local bin_name = 'vscode-html-language-server'
local cmd = { bin_name, '--stdio' }

if vim.fn.has 'win32' == 1 then
  cmd = { 'cmd.exe', '/C', bin_name, '--stdio' }
end

return {
  default_config = {
    cmd = cmd,
    filetypes = { 'html' },
    root_dir = util.root_pattern('package.json', '.git'),
    single_file_support = true,
    settings = {},
    init_options = {
      provideFormatter = true,
      embeddedLanguages = { css = true, javascript = true },
      configurationSection = { 'html', 'css', 'javascript' },
    },
  },
  docs = {
    description = [[
https://github.com/hrsh7th/vscode-langservers-extracted

`vscode-html-language-server` can be installed via `npm`:
```sh
npm i -g vscode-langservers-extracted
```

Neovim does not currently include built-in snippets. `vscode-html-language-server` only provides completions when snippet support is enabled.
To enable completion, install a snippet plugin and add the following override to your language client capabilities during setup.

The code-formatting feature of the lsp can be controlled with the `provideFormatter` option.

```lua
--Enable (broadcasting) snippet capability for completion
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true

require'lspconfig'.html.setup {
  capabilities = capabilities,
}
```
]],
  },
}


text:
ITEM.Name = 'Butterfly Knife | Blue Steel'
ITEM.Price = 20000
ITEM.Model = 'models/weapons/w_csgo_butterfly.mdl'
ITEM.Skin = 11
ITEM.WeaponClass = 'csgo_butterfly_bluesteel'

function ITEM:OnEquip(ply)
	if not ply:Alive() then return end
	ply:StripWeapon('weapon_zm_improvised')
		ply:Give(self.WeaponClass)
		ply:SelectWeapon(self.WeaponClass)

	end

	function ITEM:OnHolster(ply)
	if not ply:Alive() then return end
		ply:StripWeapon(self.WeaponClass)
		ply:Give('weapon_zm_improvised')  -- Also don't know why you're giving the player a weapon for holstering it..
		ply:SelectWeapon('weapon_zm_improvised')
	end

	function ITEM:PlayerSpawn(ply)
			ply:StripWeapon('weapon_zm_improvised')
			ply:Give(self.WeaponClass)
			ply:SelectWeapon(self.WeaponClass)
	end


text:
local Signal = require(script.Utilities.Signal)
local Janitor = require(script.Utilities.Janitor)
local GetChecks = require(script.GetChecks)
local WrappedInstance = require(script.WrappedInstance)

export type Signal = WrappedInstance.Signal
export type WrappedInstance<I> = WrappedInstance.WrappedInstance<I>

--[=[
    @class WrapperService

    A service that allows you to create custom properties for roblox instances
    Github: [https://github.com/zxibs/WrapperService](https://github.com/zxibs/WrapperService)
]=]
local WrapperService = {}

--[=[
    @prop Instances { WrappedInstance<Instance> }
    @within WrapperService

    A table containing all of the wrapped instances
    that have been created and not cleaned.
]=]
WrapperService.Instances = {} :: { WrappedInstance<Instance> }

local Checks = GetChecks(WrapperService, true)

--[=[
    @since v1.0.0
    @param Instance I
    @return WrappedInstance<I>

    Creates and returns a new WrappedInstance from the Instance
]=]
function WrapperService:Create<I>(Instance: I): WrappedInstance<I>
	assert(Checks.Create(self, Instance))

	local Wrapped = { _Public = {} }

	Wrapped._Janitor = Janitor.new()
	Wrapped._Instance = Instance
	Wrapped._Index = #self.Instances + 1

	Wrapped._Public.Changed = Signal.new(Wrapped._Janitor)
	Wrapped._Public.Called = Signal.new(Wrapped._Janitor)

	Wrapped._Public.Called:Connect(function(methodKey)
		if tostring(methodKey) == "Clean" then
			for InstanceIndex = (Wrapped._Index + 1), #self.Instances do
				self.Instances[InstanceIndex]._Index -= 1
			end

			table.remove(self.Instances, Wrapped._Index)
		end
	end)

	setmetatable(Wrapped, WrappedInstance)
	table.insert(self.Instances, Wrapped)

	return Wrapped :: any
end

--[=[
    @since v1.0.0
    @param object any
    @return ( boolean, string? )

    A method for checking if an object is a WrappedInstance,
    if it is not it will return false and an error message
]=]
function WrapperService:Is(object: any): (boolean, string?)
	assert(Checks.Is(self, object))

	return (type(object) == "table" and getmetatable(object) == WrappedInstance) or false,
		("expected WrappedInstance got %s"):format(typeof(object))
end

--[=[
    @since v1.0.0
    @param Index number
    @return WrappedInstance<Instance>

    Gets a wrapped instance in ```WrapperService.Instances``` from an index
]=]
function WrapperService:GetByIndex(Index: number): WrappedInstance<Instance>?
	assert(Checks.GetByIndex(self, Index))

	return self.Instances[Index] :: any
end

--[=[
    @since v1.0.0
    @param Instance I
    @return WrappedInstance<I>

    Gets a wrapped instance in ```WrapperService.Instances``` from an instance
]=]
function WrapperService:GetByInstance<I>(Instance: I): WrappedInstance<I>?
	assert(Checks.GetByInstance(self, Instance))

	for _index, wrappedInstance in ipairs(self.Instances) do
		if wrappedInstance._Instance == Instance then
			return wrappedInstance :: any
		end
	end
end

return WrapperService


text:
---@diagnostic disable: undefined-global, lowercase-global

-- basic
arg                 = 'Argumentos de inicialização para a versão standalone da linguagem Lua.'
assert              = 'Emite um erro se o valor de seu argumento v for falso (i.e., `nil` ou `false`); caso contrário, devolve todos os seus argumentos. Em caso de erro, `message` é o objeto de erro que, quando ausente, por padrão é `"assertion failed!"`'
cgopt.collect       = 'Realiza um ciclo completo de coleta de lixo (i.e., garbage-collection cycle).'
cgopt.stop          = 'Interrompe a execução automática.'
cgopt.restart       = 'Reinicia a execução automática.'
cgopt.count         = 'Retorna, em Kbytes, a quantidade total de memória utilizada pela linguagem Lua.'
cgopt.step          = 'Executa a coleta de lixo (i.e., garbage-collection) em uma única etapa. A quantidade de execuções por etapa é controlada via `arg`.'
cgopt.setpause      = 'Estabelece pausa. Defina via `arg` o intervalo de pausa do coletor de lixo (i.e., garbage-collection).'
cgopt.setstepmul    = 'Estabelece um multiplicador para etapa de coleta de lixo (i.e., garbage-collection). Defina via `arg` o valor multiplicador.'
cgopt.incremental   = 'Altera o modo do coletor para incremental.'
cgopt.generational  = 'Altera o modo do coletor para geracional.'
cgopt.isrunning     = 'Retorna um valor booleano indicando se o coletor de lixo (i.e., garbage-collection) está em execução.'
collectgarbage      = 'Esta função é uma interface genérica para o coletor de lixo (i.e., garbage-collection). Ela executa diferentes funções de acordo com seu primeiro argumento, `opt`.'
dofile              = 'Abre o arquivo fornecido por argumento e executa seu conteúdo como código Lua. Quando chamado sem argumentos, `dofile` executa o conteúdo da entrada padrão (`stdin`). Retorna todos os valores retornados pelo trecho de código contido no arquivo. Em caso de erros, o `dofile` propaga o erro para seu chamador. Ou seja, o `dofile` não funciona em modo protegido.'
error               = [[
Termina a última chamada de função protegida e retorna `message` como objeto de `erro`.

Normalmente, o 'erro' adiciona algumas informações sobre a localização do erro no início da mensagem, quando a mensagem for uma string.
]]
_G                  = 'Uma variável global (não uma função) que detém o ambiente global (ver §2.2). Lua em si não usa esta variável; mudar seu valor não afeta nenhum ambiente e vice-versa.'
getfenv             = 'Retorna o ambiente atual em uso pela função. O `f` pode ser uma função Lua ou um número que especifica a função naquele nível de pilha.'
getmetatable        = 'Se o objeto não tiver uma metatable, o retorno é `nil`. Mas caso a metatable do objeto tenha um campo `__metatable`, é retornado o valor associado. Caso contrário, retorna a metatable do objeto dado.'
ipairs              = [[
Retorna três valores (uma função iteradora, a tabela `t`, e `0`) para que a seguinte construção
```lua
    for i,v in ipairs(t) do body end
```
possa iterar sobre os pares de valor-chave `(1,t[1]), (2,t[2]), ...`, até o primeiro índice ausente.
]]
loadmode.b          = 'Somente blocos binários.'
loadmode.t          = 'Somente blocos de texto.'
loadmode.bt         = 'Tanto binário quanto texto.'
load['<5.1']        = 'Carrega um bloco utilizando a função `func` para obter suas partes. Cada chamada para o `func` deve retornar uma string que é concatenada com os resultados anteriores.'
load['>5.2']        = [[
Carrega um bloco.

Se o bloco (i.e., `chunk`) é uma string, o bloco é essa string. Se o bloco é uma função, a função "load" é chamada repetidamente para obter suas partes. Cada chamada para o bloco deve retornar uma string que é concatenada com os resultados anteriores. O fim do bloco é sinalizado com o retorno de uma string vazia ou `nil`.
]]
loadfile            = 'Carrega um bloco de arquivo `filename` ou da entrada padrão, se nenhum nome de arquivo for dado.'
loadstring          = 'Carrega um bloco a partir de uma string dada.'
module              = 'Cria um módulo.'
next                = [[
Permite que um programa percorra todos os campos de uma tabela. Seu primeiro argumento é uma tabela e seu segundo argumento é um índice nesta tabela. Uma chamada `next` retorna o próximo índice da tabela e seu valor associado. Quando chamado usando `nil` como segundo argumento, `next` retorna um índice inicial e seu valor associado. Quando chamado com o último índice, ou com `nil` em uma tabela vazia, o `next` retorna o `nil`. Se o segundo argumento estiver ausente, então é interpretado como `nil`. Portanto, pode-se utilizar o `next(t)` para verificar se uma tabela está vazia.

A ordem na qual os índices são enumerados não é especificada, *mesmo para índices numéricos*. (Para percorrer uma tabela em ordem numérica, utilize um `for`).

O comportamento do `next` é indefinido se, durante a iteração/travessia, você atribuir qualquer valor a um campo inexistente na tabela. Você pode, entretanto, modificar os campos existentes e pode, inclusive, os definir como nulos.
]]
pairs               = [[
Se `t` tem um "meta" método (i.e., metamethod) `__pairs`, a chamada é feita usando t como argumento e retorna os três primeiros resultados.

Caso contrário, retorna três valores: a função $next, a tabela `t` e `nil`, para que a seguinte construção
```lua
    for k,v in pairs(t) do body end
```
possa iterar sobre todos os pares de valor-chave da tabela 't'.

Veja a função $next para saber as ressalvas em modificar uma tabela durante sua iteração.
]]
pcall               = [[
Chama a função `f` com os argumentos dados em modo *protegido*. Isto significa que qualquer erro dentro de `f` não é propagado; em vez disso, o `pcall` captura o erro e retorna um código de status. Seu primeiro resultado é o código de status (booleano), que é verdadeiro se a chamada for bem sucedida sem erros. Neste caso, `pcall' também retorna todos os resultados da chamada, após este primeiro resultado. Em caso de qualquer erro, `pcall` retorna `false` mais o objeto de erro.
]]
print               = [[
Recebe qualquer número de argumentos e imprime seus valores na saída padrão `stdout`, convertendo cada argumento em uma string seguindo as mesmas regras do $tostring.
A função `print` não é destinada à saída formatada, mas apenas como uma forma rápida de mostrar um valor, por exemplo, para debugging. Para controle completo sobre a saída, use $string.format e $io.write.
]]
rawequal            = 'Verifica se v1 é igual a v2, sem invocar a metatable `__eq`.'
rawget              = 'Obtém o valor real de `table[index]`, sem invocar a metatable `__index`.'
rawlen              = 'Retorna o comprimento do objeto `v`, sem invocar a metatable `__len`.'
rawset              = [[
Define o valor real de `table[index]` para `value`, sem utilizar o metavalue `__newindex`. `table` deve ser uma tabela, `index` qualquer valor diferente de `nil` e `NaN`, e `value` qualquer valor de tipos do Lua.
Esta função retorna uma `table`.
]]
select              = 'Se `index` é um número, retorna todos os argumentos após o número do argumento `index`; um número negativo de índices do final (`-1` é o último argumento). Caso contrário, `index` deve ser a string `"#"`, e `select` retorna o número total de argumentos extras dados.'
setfenv             = 'Define o ambiente a ser utilizado pela função em questão.'
setmetatable        = [[
Define a metatable para a tabela dada. Se `metatabela` for `nil`, remove a metatable da tabela em questão. Se a metatable original tiver um campo `__metatable', um erro é lançado.

Esta função retorna uma `table`.

Para alterar a metatable de outros tipos do código Lua, você deve utilizar a biblioteca de debugging (§6.10).
]]
tonumber            = [[
Quando chamado sem a base, `tonumber` tenta converter seu argumento para um número. Se o argumento já for um número ou uma string numérica, então `tonumber` retorna este número; caso contrário, retorna `fail`.

A conversão de strings pode resultar em números inteiros ou de ponto flutuante, de acordo com as convenções lexicais de Lua (ver §3.1). A string pode ter espaços antes e depois e um sinal.
]]
tostring            = [[
Recebe um valor de qualquer tipo e o converte em uma string em formato legível por humanos.

Se a metatable de `v` tem um campo `__tostring', então `tostring' chama o valor correspondente usando `v` como argumento, e utiliza o resultado da chamada como seu resultado. Caso contrário, se a metatable de `v` tiver um campo `__name` com um valor do tipo string, `tostring` pode utilizar essa string em seu resultado final.

Para controle completo de como os números são convertidos, utilize $string.format.
]]
type                = [[
Retorna o tipo de seu único argumento, codificado como uma string. Os resultados possíveis desta função são `"nil"` (uma string, não o valor `nil`), `"number"`, `"string"`, `"boolean"`, `"table"`, `"function"`, `"thread"`, e `"userdata"`.
]]
_VERSION            = 'Uma variável global (não uma função) que contém uma string contendo a versão Lua em execução.'
warn                = 'Emite um aviso com uma mensagem composta pela concatenação de todos os seus argumentos (que devem ser strings).'
xpcall['=5.1']      = 'Faz chamada a função `f` com os argumentos dados e em modo protegido, usando um manipulador de mensagens dado.'
xpcall['>5.2']      = 'Faz chamada a função `f` com os argumentos dados e em modo protegido, usando um manipulador de mensagens dado.'
unpack              = [[
Retorna os elementos da lista dada. Esta função é equivalente a
```lua
    return list[i], list[i+1], ···, list[j]
```
]]

bit32               = ''
bit32.arshift       = [[
Retorna o número `x` deslocado `disp` bits para a direita. Deslocamentos negativos movem os bits para a esquerda.

Esta operação de deslocamento é chamada de deslocamento aritmético. Os bits vagos à esquerda são preenchidos com cópias do bit mais significativo de `x`; os bits vagos à direita são preenchidos com zeros.
]]
bit32.band          = 'Retorna a operação bitwise *and* de seus operandos.'
bit32.bnot          = [[
Retorna a negação da operação bitwise de `x`.

```lua
assert(bit32.bnot(x) == (-1 - x) % 2^32)
```
]]
bit32.bor           = 'Retorna a operação bitwise *or* de seus operandos.'
bit32.btest         = 'Retorna um valor booleano verdadeiro se a operação bitwise *and* de seus operandos for diferente de zero. Falso, caso contrário.'
bit32.bxor          = 'Retorna a operação bitwise *exclusive or* de seus operandos.'
bit32.extract       = 'Retorna o número formado pelos bits de `field` a `field + width - 1` de `n`, sem sinal.'
bit32.replace       = 'Retorna uma cópia de `n` com os bits de `field` a `field + width - 1` substituídos pelo valor `v` .'
bit32.lrotate       = 'Retorna o número `x` rotacionado `disp` bits para a esquerda. Rotações negativos movem os bits para a direita. '
bit32.lshift        = [[
Retorna o número `x` deslocado `disp` bits para a esquerda. Deslocamentos negativos movem os bits para a direita. Em ambas as direções, os bits vazios/vagos são preenchidos com zeros.

```lua
assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)
```
]]
bit32.rrotate       = 'Retorna o número `x` rotacionado `disp` bits para a direita. Deslocamentos negativos movem os bits para a esquerda.'
bit32.rshift        = [[
Retorna o número `x` deslocado `disp` bits para a direita. Deslocamentos negativos movem os bits para a esquerda. Em ambas as direções, os bits vazios são preenchidos com zeros.

```lua
assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))
```
]]

coroutine                   = ''
coroutine.create            = 'Cria uma nova `coroutine`, a partir de uma função `f` e retorna esta coroutine como objeto do tipo `"thread"`.'
coroutine.isyieldable       = 'Retorna verdadeiro quando a `coroutine` em execução for finalizada.'
coroutine.isyieldable['>5.4']= 'Retorna verdadeiro quando a `coroutine` `co` for finalizada. Por padrão `co` é uma coroutine em execução.'
coroutine.close             = 'Finaliza a coroutine `co` , encerrando todas as variáveis pendentes e colocando a coroutine em um estado morto.'
coroutine.resume            = 'Inicia ou continua a execução da coroutine `co`.'
coroutine.running           = 'Retorna a `coroutine` corrente e um booleana verdadeiro quando a coroutine corrente é a principal.'
coroutine.status            = 'Retorna o status da `coroutine `co`.'
coroutine.wrap              = 'Cria uma nova `coroutine`, a partir de uma função `f` e retorna uma função que retorna a coroutine cada vez que ele é chamado.'
coroutine.yield             = 'Suspende a execução da coroutine chamada.'
costatus.running            = 'Está em execução.'
costatus.suspended          = 'Está suspenso ou não foi iniciado.'
costatus.normal             = 'Está ativo, mas não está em execução.'
costatus.dead               = 'Terminou ou parou devido a erro'

debug                       = ''
debug.debug                 = 'Entra em modo interativo com o usuário, executando os comandos de entrada.'
debug.getfenv               = 'Retorna o ambiente do objeto `o` .'
debug.gethook               = 'Retorna as configurações do `hook` atual da `thread`.'
debug.getinfo               = 'Retorna uma tabela com informações sobre uma função.'
debug.getlocal['<5.1']      = 'Retorna o nome e o valor da variável local com índice `local` da função de nível `level` da pilha.'
debug.getlocal['>5.2']      = 'Retorna o nome e o valor da variável local com índice `local` da função de nível `f` da pilha.'
debug.getmetatable          = 'Retorna a `metatable` do valor dado.'
debug.getregistry           = 'Retorna a tabela de registro.'
debug.getupvalue            = 'Retorna o nome e o valor da variável antecedente com índice `up` da função.'
debug.getuservalue['<5.3']  = 'Retorna o valor de Lua associado a `u` (i.e., user).'
debug.getuservalue['>5.4']  = [[
Retorna o `n`-ésimo valor de usuário associado
aos dados do usuário `u` e um booleano,
`false`, se nos dados do usuário não existir esse valor.
]]
debug.setcstacklimit        = [[
### **Deprecated in `Lua 5.4.2`**

Estabelece um novo limite para a pilha C. Este limite controla quão profundamente as chamadas aninhadas podem ir em Lua, com a intenção de evitar um transbordamento da pilha.

Em caso de sucesso, esta função retorna o antigo limite. Em caso de erro, ela retorna `false`.
]]
debug.setfenv               = 'Define o ambiente do `object` dado para a `table` dada .'
debug.sethook               = 'Define a função dada como um `hook`.'
debug.setlocal              = 'Atribui o valor `value` à variável local com índice `local` da função de nível `level` da pilha.'
debug.setmetatable          = 'Define a `metatable` com o valor dado para tabela dada (que pode ser `nil`).'
debug.setupvalue            = 'Atribui `value` a variável antecedente com índice `up` da função.'
debug.setuservalue['<5.3']  = 'Define o valor dado como o valor Lua associado ao `udata` (i.e., user data).'
debug.setuservalue['>5.4']  = [[
Define o valor dado como
o `n`-ésimo valor de usuário associado ao `udata` (i.e., user data).
O `udata` deve ser um dado de usuário completo.
]]
debug.traceback             = 'Retorna uma string com um `traceback` de chamadas. A string de mensagen (opcional) é anexada no início do traceback.'
debug.upvalueid             = 'Retorna um identificador único (como um dado de usuário leve) para o valor antecedente de numero `n` da função dada.'
debug.upvaluejoin           = 'Faz o `n1`-ésimo valor da função `f1` (i.e., closure Lua) referir-se ao `n2`-ésimo valor da função `f2`.'
infowhat.n                  = '`name` e `namewhat`'
infowhat.S                  = '`source`, `short_src`, `linedefined`, `lastlinedefined` e `what`'
infowhat.l                  = '`currentline`'
infowhat.t                  = '`istailcall`'
infowhat.u['<5.1']          = '`nups`'
infowhat.u['>5.2']          = '`nups`, `nparams` e `isvararg`'
infowhat.f                  = '`func`'
infowhat.r                  = '`ftransfer` e `ntransfer`'
infowhat.L                  = '`activelines`'
hookmask.c                  = 'Faz chamada a um `hook` quando o Lua chama uma função.'
hookmask.r                  = 'Faz chamada a um `hook` quando o retorno de uma função é executado.'
hookmask.l                  = 'Faz chamada a um `hook` quando encontra nova linha de código.'

file                        = ''
file[':close']              = 'Fecha o arquivo `file`.'
file[':flush']              = 'Salva qualquer dado de entrada no arquivo `file`.'
file[':lines']              = [[
------
```lua
for c in file:lines(...) do
    body
end
```
]]
file[':read']               = 'Lê o arquivo de acordo com o formato fornecido e que especifica o que deve ser lido.'
file[':seek']               = 'Define e obtém a posição do arquivo, medida a partir do início do arquivo.'
file[':setvbuf']            = 'Define o modo de `buffer` para um arquivo de saída.'
file[':write']              = 'Escreve o valor de cada um de seus argumentos no arquivo.'
readmode.n                  = 'Lê um numeral e o devolve como número.'
readmode.a                  = 'Lê o arquivo completo.'
readmode.l                  = 'Lê a próxima linha pulando o final da linha.'
readmode.L                  = 'Lê a próxima linha mantendo o final da linha.'
seekwhence.set              = 'O cursor base é o início do arquivo.'
seekwhence.cur              = 'O cursor base é a posição atual.'
seekwhence['.end']          = 'O cursor base é o final do arquivo.'
vbuf.no                     = 'A saída da operação aparece imediatamente.'
vbuf.full                   = 'Realizado apenas quando o `buffer` está cheio.'
vbuf.line                   = '`Buffered` até que uma nova linha seja encontrada.'

io                          = ''
io.stdin                    = 'Entrada padrão.'
io.stdout                   = 'Saída padrão.'
io.stderr                   = 'Erro padrão.'
io.close                    = 'Fecha o arquivo dado ou o arquivo de saída padrão.'
io.flush                    = 'Salva todos os dados gravados no arquivo de saída padrão.'
io.input                    = 'Define o arquivo de entrada padrão.'
io.lines                    = [[
------
```lua
for c in io.lines(filename, ...) do
    body
end
```
]]
io.open                     = 'Abre um arquivo no modo especificado pela *string* `mode`.'
io.output                   = 'Define o arquivo de saída padrão.'
io.popen                    = 'Inicia o programa dado em um processo separado.'
io.read                     = 'Lê o arquivo de acordo com o formato fornecido e que especifica o que deve ser lido.'
io.tmpfile                  = 'Em caso de sucesso, retorna um `handler` para um arquivo temporário.'
io.type                     = 'Verifica se `obj` é um identificador de arquivo válido.'
io.write                    = 'Escreve o valor de cada um dos seus argumentos para o arquivo de saída padrão.'
openmode.r                  = 'Modo de leitura.'
openmode.w                  = 'Modo de escrita.'
openmode.a                  = 'Modo de anexação.'
openmode['.r+']             = 'Modo de atualização, todos os dados anteriores são preservados.'
openmode['.w+']             = 'Modo de atualização, todos os dados anteriores são apagados.'
openmode['.a+']             = 'Modo de anexação e atualização, os dados anteriores são preservados, a escrita só é permitida no final do arquivo.'
openmode.rb                 = 'Modo de leitura. (em modo binário)'
openmode.wb                 = 'Modo de escrita. (em modo binário)'
openmode.ab                 = 'Modo de anexação. (em modo binário)'
openmode['.r+b']            = 'Modo de atualização, todos os dados anteriores são preservados. (em modo binário)'
openmode['.w+b']            = 'Modo de atualização, todos os dados anteriores são apagados. (em modo binário)'
openmode['.a+b']            = 'Modo de anexação e atualização, todos os dados anteriores são preservados, a escrita só é permitida no final do arquivo. (em modo binário)'


text:
local Lib = LibStub:NewLibrary('Poncho-2.0', 2)
if not Lib then return end

local setmetatable, getmetatable, tinsert, tremove, type = setmetatable, getmetatable, tinsert, tremove, type
local Base = {__type = 'Abstract'}

local ClassMeta =  {
  __index = function(class, key)
    return class.__super[key] or Lib.Types[class.__type][key]
  end,

  __call = function(class, ...)
    return class:New(...)
  end
}

local SuperCall = {
  __index = function(tmp, key)
    local var = ClassMeta.__index(tmp.class, key) or Lib.Types[tmp.frame.__type][key]
    if type(var) == 'function' then
      return function(tmp, ...)  return var(tmp.frame, ...) end
    end

    return var
  end
}

--[[ Static ]]--

function Base:NewClass(kind, name, template)
  assert(not kind or type(kind) == 'string', 'Bad argument #1 to `:NewClass` (string or nil expected)')
  assert(not name or type(name) == 'string', 'Bad argument #2 to `:NewClass` (string or nil expected)')
  assert(not template or type(template) == 'string', 'Bad argument #3 to `:NewClass` (string or nil expected)')

  if kind and not Lib.Types[kind] then
    Lib.Types[kind] = getmetatable(CreateFrame(kind)).__index
  end

  local class = setmetatable({}, ClassMeta)
  class.__super = self
  class.__template = template
  class.__index = class
  class.__type = kind
  class.__name = name

  if class.__type ~= 'Abstract' then
    class.__frames = {}
    class.__count = 0
  end

  return class
end

function Base:New(parent)
  assert(self.__type ~= 'Abstract', 'Cannot initialize frame for absract class')

  local frame = tremove(self.__frames)
  if not frame then
    self.__count = self.__count + 1
    frame = self:Construct()
  end

  self.__frames[frame] = true
  frame:ClearAllPoints()
  frame:SetParent(parent)
  return frame
end

function Base:Bind(frame)
  return setmetatable(frame, self)
end

function Base:Construct()
  return self:Bind(CreateFrame(self.__type, self.__name and (self.__name .. self.__count) or nil, UIParent, self.__template))
end

--[[ Flexible ]]--

function Base:GetClassName()
  return self.__name
end

function Base:GetSuper()
  return self.__super
end

function Base:GetTemplate()
  return self.__template
end

function Base:GetFrameType()
  return self.__type
end

function Base:IsAbstract()
  return self.__type == 'Abstract'
end

function Base:NumActive()
  return self.__count - #self.__frames
end

function Base:NumInactive()
  return #self.__frames
end

function Base:NumFrames()
  return self.__count
end

--[[ Instance ]]--

function Base:GetClass()
  return getmetatable(self)
end

function Base:Release()
  if self:IsActive() then
    tinsert(self.__frames, 1, self)
    self.__frames[self] = nil
    self:Reset()
  end
end

function Base:Reset()
  self:SetParent(UIParent)
  self:ClearAllPoints()
  self:SetPoint('BOTTOM', UIParent, 'TOP', 0, GetScreenHeight()) -- twice outside of screen
end

function Base:IsActive()
  return self.__frames[self]
end

function Base:Super(class)
  assert(class, 'No argument #1 to `:Super`')
  return setmetatable({class = class, frame = self}, SuperCall)
end

--[[ Public ]]--

function Lib:NewClass(kind, name, template)
  return Base:NewClass(kind, name, template)
end

function Lib:Embed(object)
  object.NewClass = Lib.NewClass
end

--[[ Proprieties ]]--

setmetatable(Lib, Lib)
Lib.__call = Lib.NewClass
Lib.Base, Lib.ClassMeta, Lib.SuperCall = Base, ClassMeta, SuperCall
Lib.Types = Lib.Types or {
  Abstract = {},
  Frame = getmetatable(GameMenuFrame).__index,
  Button = getmetatable(GameMenuButtonContinue).__index,
  CheckButton = getmetatable(AddonListForceLoad).__index,
  EditBox = getmetatable(ChatFrame1EditBox).__index,
  GameTooltip = getmetatable(GameTooltip).__index,
}


text:
local DB      = require "kong.db"
local helpers = require "spec.helpers"
local utils   = require "kong.tools.utils"

for _, strategy in helpers.each_strategy() do
  local it_ssl = strategy == "cassandra" and pending or it

  describe("kong.db.init [#" .. strategy .. "]", function()
    describe(".new()", function()
      it("errors on invalid arg", function()
        assert.has_error(function()
          DB.new(nil, strategy)
        end, "missing kong_config")

        assert.has_error(function()
          DB.new(helpers.test_conf, 123)
        end, "strategy must be a string")
      end)

      it("instantiates a DB", function()
        local db, err = DB.new(helpers.test_conf, strategy)
        assert.is_nil(err)
        assert.is_table(db)
      end)

      it("initializes infos", function()
        local db, err = DB.new(helpers.test_conf, strategy)

        assert.is_nil(err)
        assert.is_table(db)

        local infos = db.infos

        if strategy == "postgres" then
          assert.same({
            strategy = "PostgreSQL",
            db_desc = "database",
            db_name = helpers.test_conf.pg_database,
            db_ver  = "unknown",
          }, infos)

        elseif strategy == "cassandra" then
          assert.same({
            strategy = "Cassandra",
            db_desc = "keyspace",
            db_name = helpers.test_conf.cassandra_keyspace,
            db_ver  = "unknown",
          }, infos)

        else
          error("unknown database")
        end
      end)
    end)
  end)

  describe(":init_connector() [#" .. strategy .. "]", function()
    it("initializes infos", function()
      local db, err = DB.new(helpers.test_conf, strategy)

      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local infos = db.infos

      assert.matches("^%d+%.?%d*%.?%d*$", infos.db_ver)
      assert.not_matches("%.$", infos.db_ver)

      if strategy == "postgres" then
        assert.same({
          strategy = "PostgreSQL",
          db_desc = "database",
          db_name = helpers.test_conf.pg_database,
          db_ver  = infos.db_ver,
        }, infos)

      elseif strategy == "cassandra" then
        assert.same({
          strategy = "Cassandra",
          db_desc = "keyspace",
          db_name = helpers.test_conf.cassandra_keyspace,
          db_ver  = infos.db_ver,
        }, infos)

      else
        error("unknown database")
      end
    end)
  end)

  describe(":connect() [#" .. strategy .. "]", function()
    lazy_setup(function()
      helpers.get_db_utils(strategy, {})
    end)

    it("returns opened connection when using cosockets", function()
      -- bin/busted runs with ngx.IS_CLI = true, which forces luasocket to
      -- be used in the DB connector (for custom CAs to work)
      -- Disable this behavior for this test, especially considering we
      -- are running within resty-cli, and thus within timer_by_lua (which
      -- can support cosockets).
      ngx.IS_CLI = false

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)

      db:close()
    end)

    it("returns opened connection when using luasocket", function()
      ngx.IS_CLI = true

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket",
                     db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)

      db:close()
    end)

    it_ssl("returns opened connection with ssl (cosockets)", function()
      ngx.IS_CLI = false

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)

      db:close()
    end)

    it_ssl("returns opened connection with ssl (luasocket)", function()
      ngx.IS_CLI = true

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket",
                     db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)

      db:close()
    end)
  end)

  describe(":setkeepalive() [#" .. strategy .. "]", function()
    lazy_setup(function()
      helpers.get_db_utils(strategy, {})
    end)

    it("returns true when there is a stored connection (cosockets)", function()
      ngx.IS_CLI = false

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)
      assert.is_true(db:setkeepalive())

      db:close()
    end)

    it("returns true when there is a stored connection (luasocket)", function()
      ngx.IS_CLI = true

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket",
                     db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)
      assert.is_true(db:setkeepalive())

      db:close()
    end)

    it_ssl("returns true when there is a stored connection with ssl (cosockets)", function()
      ngx.IS_CLI = false

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)
      assert.is_true(db:setkeepalive())

      db:close()
    end)

    it_ssl("returns true when there is a stored connection with ssl (luasocket)", function()
      ngx.IS_CLI = true

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket",
                     db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)
      assert.is_true(db:setkeepalive())

      db:close()
    end)

    it("returns true when there is no stored connection (cosockets)", function()
      ngx.IS_CLI = false

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      assert.is_nil(db.connector:get_stored_connection())
      assert.is_true(db:setkeepalive())
    end)

    it("returns true when there is no stored connection (luasocket)", function()
      ngx.IS_CLI = true

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      assert.is_nil(db.connector:get_stored_connection())
      assert.is_true(db:setkeepalive())
    end)
  end)

  describe(":close() [#" .. strategy .. "]", function()
    lazy_setup(function()
      helpers.get_db_utils(strategy, {})
    end)

    it("returns true when there is a stored connection (cosockets)", function()
      ngx.IS_CLI = false

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)
      assert.is_true(db:close())
    end)

    it("returns true when there is a stored connection (luasocket)", function()
      ngx.IS_CLI = true

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_false(db.connector:get_stored_connection().ssl)
      assert.is_true(db:close())
    end)

    it_ssl("returns true when there is a stored connection with ssl (cosockets)", function()
      ngx.IS_CLI = false

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("nginx", db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)
      assert.is_true(db:close())
    end)

    it_ssl("returns true when there is a stored connection with ssl (luasocket)", function()
      ngx.IS_CLI = true

      local conf = utils.deep_copy(helpers.test_conf)

      conf.pg_ssl = true
      conf.cassandra_ssl = true

      local db, err = DB.new(conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      local conn, err = db:connect()
      assert.is_nil(err)
      assert.is_table(conn)

      if strategy == "postgres" then
        assert.equal("luasocket",
                     db.connector:get_stored_connection().sock_type)
      --elseif strategy == "cassandra" then
      --TODO: cassandra forces luasocket on timer
      end

      assert.is_true(db.connector:get_stored_connection().ssl)
      assert.is_true(db:close())
    end)

    it("returns true when there is no stored connection (cosockets)", function()
      ngx.IS_CLI = false

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      assert.is_nil(db.connector:get_stored_connection())
      assert.is_true(db:close())
    end)

    it("returns true when there is no stored connection (luasocket)", function()
      ngx.IS_CLI = true

      local db, err = DB.new(helpers.test_conf, strategy)
      assert.is_nil(err)
      assert.is_table(db)

      assert(db:init_connector())

      assert.is_nil(db.connector:get_stored_connection())
      assert.equal(true, db:close())
    end)
  end)
end


text:
local K, C, L, _ = select(2, ...):unpack()
if C.Misc.AlreadyKnown ~= true then return end

local _G = _G
local match = string.match
local ceil = math.ceil
local fmod = math.fmod
local IsAddOnLoaded = IsAddOnLoaded
local CreateFrame = CreateFrame
local IsAlreadyKnown = IsAlreadyKnown
local GetItemInfo = GetItemInfo
local GetMerchantNumItems = GetMerchantNumItems
local GetNumBuybackItems = GetNumBuybackItems
local isUsable = isUsable
local GetAuctionItemInfo = GetAuctionItemInfo
local canUse = canUse
local hooksecurefunc = hooksecurefunc

if IsAddOnLoaded("RecipeKnown") or IsAddOnLoaded("AlreadyKnown") then return end
local knowncolor = { r = 0.1, g = 1.0, b = 0.2 }
local tooltip = CreateFrame("GameTooltip")
tooltip:SetOwner(WorldFrame, "ANCHOR_NONE")

local IsAlreadyKnown
do
	local knowns = {}

	-- things we have to care. please let me know if any lack or surplus here.
	local weapon, armor, container, consumable, glyph, trade_goods, recipe, gem, miscallaneous, quest = GetAuctionItemClasses()
	local knowables = { [consumable] = true, [glyph] = true, [recipe] = true, [miscallaneous] = true, }

	local lines = {}
	for i = 1, 40 do
		lines[i] = tooltip:CreateFontString()
		tooltip:AddFontStrings(lines[i], tooltip:CreateFontString())
	end

	function IsAlreadyKnown (itemLink)
		if ( not itemLink ) then
			return
		end

		local itemID = itemLink:match("item:(%d+):")
		if ( knowns[itemID] ) then
			return true
		end

		local _, _, _, _, _, itemType = GetItemInfo(itemLink)
		if ( not knowables[itemType] ) then
			return
		end

		tooltip:ClearLines()
		tooltip:SetHyperlink(itemLink)

		for i = 1, tooltip:NumLines() do
			if ( lines[i]:GetText() == ITEM_SPELL_KNOWN ) then
				knowns[itemID] = true
				return true
			end
		end
	end
end

-- merchant frame
local function MerchantFrame_UpdateMerchantInfo ()
	local numItems = GetMerchantNumItems()

	for i = 1, MERCHANT_ITEMS_PER_PAGE do
		local index = (MerchantFrame.page - 1) * MERCHANT_ITEMS_PER_PAGE + i
		if ( index > numItems ) then
			return
		end

		local button = _G["MerchantItem" .. i .. "ItemButton"]

		if ( button and button:IsShown() ) then
			local _, _, _, _, numAvailable, isUsable = GetMerchantItemInfo(index)

			if ( isUsable and IsAlreadyKnown(GetMerchantItemLink(index)) ) then
				local r, g, b = knowncolor.r, knowncolor.g, knowncolor.b
				if ( numAvailable == 0 ) then
					r, g, b = r * 0.5, g * 0.5, b * 0.5
				end

				SetItemButtonTextureVertexColor(button, r, g, b)
			end
		end
	end
end

hooksecurefunc("MerchantFrame_UpdateMerchantInfo", MerchantFrame_UpdateMerchantInfo)

local function MerchantFrame_UpdateBuybackInfo ()
	local numItems = GetNumBuybackItems()

	for index = 1, BUYBACK_ITEMS_PER_PAGE do
		if ( index > numItems ) then
			return
		end

		local button = _G["MerchantItem" .. index .. "ItemButton"]

		if ( button and button:IsShown() ) then
			local _, _, _, _, _, isUsable = GetBuybackItemInfo(index)

			if ( isUsable and IsAlreadyKnown(GetBuybackItemLink(index)) ) then
				SetItemButtonTextureVertexColor(button, knowncolor.r, knowncolor.g, knowncolor.b)
			end
		end
	end
end

hooksecurefunc("MerchantFrame_UpdateBuybackInfo", MerchantFrame_UpdateBuybackInfo)

-- guild bank frame

local function GuildBankFrame_Update ()
	if ( GuildBankFrame.mode ~= "bank" ) then
		return
	end

	local tab = GetCurrentGuildBankTab()

	for i = 1, MAX_GUILDBANK_SLOTS_PER_TAB do
		local button = _G["GuildBankColumn" .. math.ceil((i - 0.5) / NUM_SLOTS_PER_GUILDBANK_GROUP) .. "Button" .. math.fmod(i, NUM_SLOTS_PER_GUILDBANK_GROUP)]

		if ( button and button:IsShown() ) then
			local texture, _, locked = GetGuildBankItemInfo(tab, i)

			if ( texture and not locked ) then
				if ( IsAlreadyKnown(GetGuildBankItemLink(tab, i)) ) then
					SetItemButtonTextureVertexColor(button, knowncolor.r, knowncolor.g, knowncolor.b)
				else
					SetItemButtonTextureVertexColor(button, 1, 1, 1)
				end
			end
		end
	end
end

local isBlizzard_GuildBankUILoaded
if ( IsAddOnLoaded("Blizzard_GuildBankUI") ) then
	isBlizzard_GuildBankUILoaded = true

	hooksecurefunc("GuildBankFrame_Update", GuildBankFrame_Update)
end

-- auction frame

local function AuctionFrameBrowse_Update ()
	local numItems = GetNumAuctionItems("list")
	local offset = FauxScrollFrame_GetOffset(BrowseScrollFrame)

	for i = 1, NUM_BROWSE_TO_DISPLAY do
		local index = offset + i
		if ( index > numItems ) then
			return
		end

		local texture = _G["BrowseButton" .. i .. "ItemIconTexture"]

		if ( texture and texture:IsShown() ) then
			local _, _, _, _, canUse = GetAuctionItemInfo("list", index)

			if ( canUse and IsAlreadyKnown(GetAuctionItemLink("list", index)) ) then
				texture:SetVertexColor(knowncolor.r, knowncolor.g, knowncolor.b)
			end
		end
	end
end

local function AuctionFrameBid_Update ()
	local numItems = GetNumAuctionItems("bidder")
	local offset = FauxScrollFrame_GetOffset(BidScrollFrame)

	for i = 1, NUM_BIDS_TO_DISPLAY do
		local index = offset + i
		if ( index > numItems ) then
			return
		end

		local texture = _G["BidButton" .. i .. "ItemIconTexture"]

		if ( texture and texture:IsShown() ) then
			local _, _, _, _, canUse = GetAuctionItemInfo("bidder", index)

			if ( canUse and IsAlreadyKnown(GetAuctionItemLink("bidder", index)) ) then
				texture:SetVertexColor(knowncolor.r, knowncolor.g, knowncolor.b)
			end
		end
	end
end

local function AuctionFrameAuctions_Update ()
	local numItems = GetNumAuctionItems("owner")
	local offset = FauxScrollFrame_GetOffset(AuctionsScrollFrame)

	for i = 1, NUM_AUCTIONS_TO_DISPLAY do
		local index = offset + i
		if ( index > numItems ) then
			return
		end

		local texture = _G["AuctionsButton" .. i .. "ItemIconTexture"]

		if ( texture and texture:IsShown() ) then
			local _, _, _, _, canUse, _, _, _, _, _, _, _, saleStatus = GetAuctionItemInfo("owner", index)

			if ( canUse and IsAlreadyKnown(GetAuctionItemLink("owner", index)) ) then
				local r, g, b = knowncolor.r, knowncolor.g, knowncolor.b
				if ( saleStatus == 1 ) then
					r, g, b = r * 0.5, g * 0.5, b * 0.5
				end

				texture:SetVertexColor(r, g, b)
			end
		end
	end
end

local isBlizzard_AuctionUILoaded
if ( IsAddOnLoaded("Blizzard_AuctionUI") ) then
	isBlizzard_AuctionUILoaded = true

	hooksecurefunc("AuctionFrameBrowse_Update", AuctionFrameBrowse_Update)
	hooksecurefunc("AuctionFrameBid_Update", AuctionFrameBid_Update)
	hooksecurefunc("AuctionFrameAuctions_Update", AuctionFrameAuctions_Update)
end

-- for LoD addons

if ( not (isBlizzard_GuildBankUILoaded and isBlizzard_AuctionUILoaded) ) then
	local function OnEvent (self, event, addonName)
		if ( addonName == "Blizzard_GuildBankUI" ) then
			isBlizzard_GuildBankUILoaded = true

			hooksecurefunc("GuildBankFrame_Update", GuildBankFrame_Update)
		elseif ( addonName == "Blizzard_AuctionUI" ) then
			isBlizzard_AuctionUILoaded = true

			hooksecurefunc("AuctionFrameBrowse_Update", AuctionFrameBrowse_Update)
			hooksecurefunc("AuctionFrameBid_Update", AuctionFrameBid_Update)
			hooksecurefunc("AuctionFrameAuctions_Update", AuctionFrameAuctions_Update)
		end

		if ( isBlizzard_GuildBankUILoaded and isBlizzard_AuctionUILoaded ) then
			self:UnregisterEvent(event)
			self:SetScript("OnEvent", nil)
			OnEvent = nil
		end
	end

	tooltip:SetScript("OnEvent", OnEvent)
	tooltip:RegisterEvent("ADDON_LOADED")
end


text:
---@class lstg.mbg.Layer
local M = class('lstg.mbg.Layer')

-- private
M.clcount = 0
M.clwait = 0
M.form = nil
-- public
M.total = 0
M.selection = 0
M.oldcolor = 0
---@type lstg.mbg.Layer[]
M.LayerArray = {} -- List<Layer>

function M:ctor(nm, bg, ed)
    assert(nm and bg and ed)
    self.name = nm
    self.Visible = true
    self.sort = #M.LayerArray
    M.selection = 0
    self.color = M.oldcolor
    M.oldcolor = M.oldcolor + 1
    if M.oldcolor > 6 then
        M.oldcolor = 0
    end
    self.begin = bg
    self['end'] = ed
    M.total = M.total + 1
    self.NeedDelete = false
    --
    ---@type lstg.mbg.Batch[]
    self.BatchArray = {} -- List<Batch>
    self.LaseArray = {} -- List<Lase>
    self.CoverArray = {} -- List<Cover>
    self.ReboundArray = {} -- List<Rebound>
    ---@type lstg.mbg.Force[]
    self.ForceArray = {} -- List<Force>
    ---@type lstg.mbg.Barrage[]
    self.Barrages = {} -- List<Barrage>
    table.insert(M.LayerArray, self)
end

function M:clear()
    M.total = 0
    M.selection = 0
    M.oldcolor = 0
    M.clcount = 0
    M.clwait = 0
    M.LayerArray = {}
end

function M:update()
    local Time = require('game.mbg.Time')
    local Main = require('game.mbg.Main')
    local sw = lstg.StopWatch()
    local tt = 0

    if not Main.Available then
        return
    end
    if self.Visible then
        for i, v in ipairs(self.ForceArray) do
            v.id = i - 1
            v.parentid = self.sort
            if (not Time.Playing) then
                v:update()
            else
                v.copys:update()
            end
        end
        for i, v in ipairs(self.ReboundArray) do
            v.id = i - 1
            v.parentid = self.sort
            if (not Time.Playing) then
                v:update()
            else
                v.copys:update()
            end
        end
        for i, v in ipairs(self.CoverArray) do
            v.id = i - 1
            v.parentid = self.sort
            if (not Time.Playing) then
                v:update()
            else
                v.copys:update()
            end
        end
        for i, v in ipairs(self.LaseArray) do
            v.id = i - 1
            v.parentid = self.sort
            if (not Time.Playing) then
                v:update()
            else
                v.copys:update()
            end
        end
        for i, v in ipairs(self.BatchArray) do
            v.id = i - 1
            v.parentid = self.sort
            if (not Time.Playing) then
                v:update()
            else
                v.copys:update()
            end
        end
        if Time.Playing then
            sw:reset()
            for i, v in ipairs(self.Barrages) do
                v.id = i - 1
                v:update()
                v:lupdate()
            end
            self._Tb = sw:get() * 1000
        end
    end
end

function M.aupdate()
    if (M.clcount == 1) then
        M.clwait = M.clwait + 1
        if (M.clwait > 15) then
            M.clwait = 0
            M.clcount = 0
        end
    end
end

return M


text:
local nn = require 'nn'

local Model = { zSize = 200 }

function Model:createAutoencoder(X)

  local L = X:size(2)

  --[[ ENCODER ]]--------------------------------------------------------------
  -- expected input: (L) x 227 x 227
  self.encoder = nn.Sequential();
  self.encoder:add(nn.SpatialConvolution(L, 64, 5, 5, 2, 2, 1, 1));
  self.encoder:add(nn.SpatialBatchNormalization(64));
  self.encoder:add(nn.LeakyReLU(0.2, true));
  self.encoder:add(nn.Dropout(0.5));
  -- out: 64 x 113 x 113
  self.encoder:add(nn.SpatialConvolution(64, 128, 5, 5, 2, 2, 1, 1));
  self.encoder:add(nn.SpatialBatchNormalization(128));
  self.encoder:add(nn.LeakyReLU(0.2, true));
  self.encoder:add(nn.Dropout(0.5));
  -- out: 128 x 56 x 56
  self.encoder:add(nn.SpatialConvolution(128, 256, 5, 5, 2, 2, 1, 1));
  self.encoder:add(nn.SpatialBatchNormalization(256));
  self.encoder:add(nn.LeakyReLU(0.2, true));
  self.encoder:add(nn.Dropout(0.5));
  -- out: 256 x 27 x 27
  self.encoder:add(nn.SpatialConvolution(256, 128, 5, 5, 2, 2, 1, 1));
  self.encoder:add(nn.SpatialBatchNormalization(128));
  self.encoder:add(nn.LeakyReLU(0.2, true));
  -- out: 128 x 13 x 13
  self.encoder:add(nn.SpatialConvolution(128, 64, 5, 5, 2, 2, 1, 1));
  self.encoder:add(nn.SpatialBatchNormalization(64));
  self.encoder:add(nn.LeakyReLU(0.2, true));
  -- out: 64 x 6 x 6
  self.encoder:add(nn.SpatialConvolution(64, self.zSize, 6, 6, 1, 1, 0, 0));
  self.encoder:add(nn.SpatialBatchNormalization(self.zSize));
  self.encoder:add(nn.Tanh());
  -- out: (self.zSize) x 1 x 1

  --[[ DECODER ]]--------------------------------------------------------------
  -- expected input: (self.zSize) x 1 x 1
  self.decoder = nn.Sequential();
  self.decoder:add(nn.SpatialFullConvolution(self.zSize, 64, 6, 6, 2, 2, 0, 0));
  self.decoder:add(nn.SpatialBatchNormalization(64));
  self.decoder:add(nn.ReLU(true));
  -- out: 64 x 6 x 6
  self.decoder:add(nn.SpatialFullConvolution(64, 128, 5, 5, 2, 2, 1, 1));
  self.decoder:add(nn.SpatialBatchNormalization(128));
  self.decoder:add(nn.ReLU(true));
  -- out: 128 x 13 x 13
  self.decoder:add(nn.SpatialFullConvolution(128, 256, 5, 5, 2, 2, 1, 1));
  self.decoder:add(nn.SpatialBatchNormalization(256));
  self.decoder:add(nn.ReLU(true));
  -- out: 256 x 27 x 27
  self.decoder:add(nn.SpatialFullConvolution(256, 128, 5, 5, 2, 2, 1, 1, 1, 1));
  self.decoder:add(nn.SpatialBatchNormalization(128));
  self.decoder:add(nn.ReLU(true));
  -- out: 128 x 56 x 56
  self.decoder:add(nn.SpatialFullConvolution(128, 64, 5, 5, 2, 2, 1, 1));
  self.decoder:add(nn.SpatialBatchNormalization(64));
  self.decoder:add(nn.ReLU(true));
  -- out: 64 x 113 x 113
  self.decoder:add(nn.SpatialFullConvolution(64, L, 5, 5, 2, 2, 1, 1));
  self.decoder:add(nn.SpatialBatchNormalization(L));
  self.decoder:add(nn.Tanh());
  -- out: (L) x 227 x 227

  --[[ AUTOENCODER ]]----------------------------------------------------------
  self.autoencoder = nn.Sequential()
  self.autoencoder:add(self.encoder)
  self.autoencoder:add(self.decoder)
end

return Model


text:
--由于软件有自动保存
--所以请勿在开启本软件的同时
--用其他编辑器编辑此处打开了的脚本
--以免被覆盖掉
--建议在此处require你在改的脚本

--注册串口接收函数
uartReceive = function (data)
    log.info("uart receive",data)
    sys.publish("UART",data)--发布消息
end

--新建任务，等待接收到消息再继续运行
sys.taskInit(function()
    while true do
        --等待消息，超时1000ms
        local r,udata = sys.waitUntil("UART",1000)
        log.info("uart wait",r,udata)
        if r then
            --发送串口消息，并获取发送结果
            local sendResult = apiSendUartData("ok!")
            log.info("uart send",sendResult)
        end
    end
end)

--新建任务，每休眠1000ms继续一次
sys.taskInit(function()
    while true do
        sys.wait(1000)--等待1000ms
        log.info("task wait",os.time())
    end
end)

--1000ms循环定时器
sys.timerLoopStart(log.info,1000,"timer test")


text:
ITEM.name = "Machete"
ITEM.description = "A machete made for cutting."
ITEM.model = "models/weapons/tfa_nmrih/w_me_machete.mdl"
ITEM.class = "tfa_nmrih_machete"
ITEM.weaponCategory = "secondary"
ITEM.price = 600
ITEM.busflag = {"melee"}
ITEM.height = 1
ITEM.width = 3
ITEM.category = "Melee"
ITEM.repairCost = ITEM.price/100*1
ITEM.canAttach = false

ITEM.weight = 0.800

ITEM.exRender = true
ITEM.iconCam = {
	pos = Vector(0, 34, 0),
	ang = Angle(0, 270, -90),
	fov = 45,
}

ITEM.pacData = {
[1] = {
	["children"] = {
		[1] = {
			["children"] = {
				[1] = {
					["children"] = {
					},
					["self"] = {
						["Angles"] = Angle(0.719, 93.188, -174.281),
						["Position"] = Vector(-7.366, 6.884, 6.301),
						["Model"] = "models/weapons/tfa_nmrih/w_me_machete.mdl",
						["ClassName"] = "model",
						["EditorExpand"] = true,
						["UniqueID"] = "0087994673",
						["Bone"] = "chest",
						["Name"] = "machete",
					},
				},
			},
			["self"] = {
				["AffectChildrenOnly"] = true,
				["ClassName"] = "event",
				["UniqueID"] = "0088770522",
				["Event"] = "weapon_class",
				["EditorExpand"] = true,
				["Name"] = "weapon class find simple\"@@1\"",
				["Arguments"] = "tfa_nmrih_machete@@0",
			},
		},
	},
	["self"] = {
		["ClassName"] = "group",
		["UniqueID"] = "2990076348",
		["EditorExpand"] = true,
	},
},
}

function ITEM:PopulateTooltipIndividual(tooltip)
    ix.util.PropertyDesc(tooltip, "Melee", Color(64, 224, 208))
end


text:
local main = require(game.Nanoblox)
local Command =	{}

Command.name = script.Name
Command.description = "Plays an emote for the player."
Command.aliases	= {}
Command.opposites = {}
Command.tags = {"Fun", "Emote", "Animation"}
Command.prefixes = {}
Command.contributors = {82347291}
Command.blockPeers = false
Command.blockJuniors = false
Command.autoPreview = false
Command.requiresRig = main.enum.HumanoidRigType.R15
Command.revokeRepeats = true
Command.preventRepeats = main.enum.TriStateSetting.Default
Command.cooldown = 0
Command.persistence = main.enum.Persistence.None
Command.args = {"Player", "Speed"}

Command.emoteId = 5104377791

function Command.invoke(job, args)
    local player = args[1]
    local animationId = main.modules.Parser.Args.get("AnimationId"):parse(Command.emoteId)
    local speed = job:getOriginalArg("Speed")
    job:hijackCommand("Animate", {player, animationId, speed})
end

return Command


text:
--[[lit-meta
  name = "creationix/coro-net"
  version = "3.2.0"
  dependencies = {
    "creationix/coro-channel@3.0.0",
    "creationix/coro-wrapper@3.0.0",
  }
  optionalDependencies = {
    "luvit/secure-socket@1.0.0"
  }
  homepage = "https://github.com/luvit/lit/blob/master/deps/coro-net.lua"
  description = "An coro style client and server helper for tcp and pipes."
  tags = {"coro", "tcp", "pipe", "net"}
  license = "MIT"
  author = { name = "Tim Caswell" }
]]

local uv = require('uv')
local wrapStream = require('coro-channel').wrapStream
local wrapper = require('coro-wrapper')
local merger = wrapper.merger
local decoder = wrapper.decoder
local encoder = wrapper.encoder
local secureSocket -- Lazy required from "secure-socket" on first use.

local function makeCallback(timeout)
  local thread = coroutine.running()
  local timer, done
  if timeout then
    timer = uv.new_timer()
    timer:start(timeout, 0, function ()
      if done then return end
      done = true
      timer:close()
      return assert(coroutine.resume(thread, nil, "timeout"))
    end)
  end
  return function (err, data)
    if done then return end
    done = true
    if timer then timer:close() end
    if err then
      return assert(coroutine.resume(thread, nil, err))
    end
    return assert(coroutine.resume(thread, data or true))
  end
end

local function normalize(options, server)
  local t = type(options)
  if t == "string" then
    options = {path=options}
  elseif t == "number" then
    options = {port=options}
  elseif t ~= "table" then
    assert("Net options must be table, string, or number")
  end
  if options.port or options.host then
    options.isTcp = true
    options.host = options.host or "127.0.0.1"
    assert(options.port, "options.port is required for tcp connections")
  elseif options.path then
    options.isTcp = false
  else
    error("Must set either options.path or options.port")
  end
  if options.tls == true then
    options.tls = {}
  end
  if options.tls then
    if server then
      options.tls.server = true
      assert(options.tls.cert, "TLS servers require a certificate")
      assert(options.tls.key, "TLS servers require a key")
    else
      options.tls.server = false
      options.tls.servername = options.host
    end
  end
  return options
end

local function connect(options)
  local socket, success, err
  options = normalize(options)
  if options.isTcp then
    success, err = uv.getaddrinfo(options.host, options.port, {
      socktype = options.socktype or "stream",
      family = options.family or "inet",
    }, makeCallback(options.timeout))
    if not success then return nil, err end
    local res
    res, err = coroutine.yield()
    if not res then return nil, err end
    socket = uv.new_tcp()
    socket:connect(res[1].addr, res[1].port, makeCallback(options.timeout))
  else
    socket = uv.new_pipe(false)
    socket:connect(options.path, makeCallback(options.timeout))
  end
  success, err = coroutine.yield()
  if not success then return nil, err end
  local dsocket
  if options.tls then
    if not secureSocket then secureSocket = require('secure-socket') end
    dsocket, err = secureSocket(socket, options.tls)
    if not dsocket then
      return nil, err
    end
  else
    dsocket = socket
  end

  local read, write, close = wrapStream(dsocket)
  local updateDecoder, updateEncoder
  if options.scan then
    -- TODO: Should we expose updateScan somehow?
    read = merger(read, options.scan)
  end
  if options.decode then
    read, updateDecoder = decoder(read, options.decode)
  end
  if options.encode then
    write, updateEncoder = encoder(write, options.encode)
  end
  return read, write, dsocket, updateDecoder, updateEncoder, close
end

local function createServer(options, onConnect)
  local server
  options = normalize(options, true)
  if options.isTcp then
    server = uv.new_tcp()
    assert(server:bind(options.host, options.port))
  else
    server = uv.new_pipe(false)
    assert(server:bind(options.path))
  end
  assert(server:listen(256, function (err)
    assert(not err, err)
    local socket = options.isTcp and uv.new_tcp() or uv.new_pipe(false)
    server:accept(socket)
    coroutine.wrap(function ()
      local success, failure = xpcall(function ()
        local dsocket
        if options.tls then
          if not secureSocket then secureSocket = require('secure-socket') end
          dsocket = assert(secureSocket(socket, options.tls))
          dsocket.socket = socket
        else
          dsocket = socket
        end

        local read, write = wrapStream(dsocket)
        local updateDecoder, updateEncoder
        if options.scan then
          -- TODO: should we expose updateScan somehow?
          read = merger(read, options.scan)
        end
        if options.decode then
          read, updateDecoder = decoder(read, options.decode)
        end
        if options.encode then
          write, updateEncoder = encoder(write, options.encode)
        end

        return onConnect(read, write, dsocket, updateDecoder, updateEncoder)
      end, debug.traceback)
      if not success then
        print(failure)
      end
    end)()
  end))
  return server
end

return {
  makeCallback = makeCallback,
  connect = connect,
  createServer = createServer,
}


text:
-- The bio reactor was copied from the BioTech mod, who copied it from the Bio Industries mod, who copied it from the Tree Mod

data:extend({

-- Bioreactor 2
  {
    type = "recipe",
    name = "biotech-ext-bioreactor-2",
    enabled = "false",
    ingredients = {
      {"biotech-bioreactor",1},
      {"steel-plate", 10},
      {"biotech-test-tube", 10},
      {"biotech-advanced-circuit", 5},
    },
    result = "biotech-ext-bioreactor-2",
  },

-- Bioreactor 3
  {
    type = "recipe",
    name = "biotech-ext-bioreactor-3",
    enabled = "false",
    ingredients = {
      {"biotech-ext-bioreactor-2",1},
      {"biotech-tempered-glass", 10},
      {"biotech-ext-catalytic-surface", 2},
      {"biotech-neural-circuit", 5},
    },
    result = "biotech-ext-bioreactor-3",
  },

-- Sandminer 2
  {
    type = "recipe",
    name = "biotech-ext-sandminer-2",
    energy_required = 2,
    enabled = "false",
    ingredients = {
      {"electric-sand-mining-drill", 1},
      {"electronic-circuit", 5},
      {"steel-plate", 10},
      {"iron-gear-wheel", 5},
    },
    result = "biotech-ext-sandminer-2",
  },

-- Sandminer 3
  {
    type = "recipe",
    name = "biotech-ext-sandminer-3",
    energy_required = 2,
    enabled = "false",
    ingredients = {
      {"biotech-ext-sandminer-2", 1},
      {"advanced-circuit", 5},
      {"steel-plate", 10},
      {"iron-gear-wheel", 5},
    },
    result = "biotech-ext-sandminer-3",
  },

-- Catalytic Surface
  {
    type = "recipe",
    name = "biotech-ext-catalytic-surface",
    enabled = false,
    energy_required = 4,
    ingredients = {
      {"biotech-carbon-nanotube", 5},
      {"biotech-graphene", 4},
      {"biotech-diamond-substrate", 1},
      {"biotech-optic-fiber", 5},
    },
    result = "biotech-ext-catalytic-surface",
  },

})


text:
---
-- Utility functions to add new discovered targets to Nmap scan queue.
--
-- The library lets scripts to add new discovered targets to Nmap scan
-- queue. Only scripts that run in the script pre-scanning phase
-- (prerule) and the script scanning phase (hostrule and portrule) are
-- able to add new targets. Post-scanning scripts (postrule) are not
-- allowed to add new targets.
--
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
--
-- @args newtargets  If specified, lets NSE scripts add new targets.
-- @args max-newtargets  Sets the number of the maximum allowed
--                       new targets. If set to 0 or less then there
--                       is no limit. The default value is 0.

local type      = type
local select    = select
local unpack    = unpack
local tonumber  = tonumber

local stdnse  = require "stdnse"
local nmap    = require "nmap"

module ("target")

-- This is a special variable and it is a global one, so
-- scripts can check it to see if adding targets is allowed,
-- before calling target.add() function.
-- This variable will be set to true if the script argument
-- 'newtargets' was specified.
ALLOW_NEW_TARGETS = false

local newtargets, max_newtargets = stdnse.get_script_args("newtargets",
                                        "max-newtargets")
if newtargets then
  ALLOW_NEW_TARGETS = true
end

if max_newtargets then
  max_newtargets = tonumber(max_newtargets)
else
  max_newtargets = 0
end

--- Local function to calculate max allowed new targets
local calc_max_targets = function(targets)
  if max_newtargets > 0 then
    local pushed_targets = nmap.new_targets_num()
    if pushed_targets >= max_newtargets then
      return 0
    elseif (targets + pushed_targets) > max_newtargets then
      return (max_newtargets - pushed_targets)
    end
  end
  return targets
end

--- Adds the passed arguments to the Nmap scan queue.
--
-- Only prerule, portrule and hostrule scripts can add new targets.
--
-- @param targets  A variable number of targets. Target is a
-- string that represents an IP or a Hostname. If this function
-- is called without target arguments then it will return true
-- and the number of pending targets (waiting to be scanned).
-- @usage
-- local status, err = target.add("192.168.1.1")
-- local status, err = target.add("192.168.1.1","192.168.1.2",...)
-- local status, err = target.add("scanme.nmap.org","192.168.1.1",...)
-- local status, err = target.add(unpack(array_of_targets))
-- local status, pending_targets = target.add()
-- @return True if it has been able to add a minimum one target, or
--         False on failures and if no targets were added. If this
--         function is called without target arguments then it will
--         return true.
-- @return Number of added targets on success, or a string error
--         message in case of failures. If this function is called
--         without target arguments then it will return the number
--         of targets that are in the queue (waiting to be scanned).
add = function (...)
  -- Force the check here, but it would be better if scripts
  -- check ALLOW_NEW_TARGETS before calling target.add()
  if not ALLOW_NEW_TARGETS then
    stdnse.print_debug(1,
        "ERROR: to add targets run with --script-args 'newtargets'")
    return false, "to add targets run with --script-args 'newtargets'"
  end

  local new_targets = {count = select("#", ...), ...}

  -- function called without arguments
  if new_targets.count == 0 then
    return true, nmap.add_targets()
  end

  new_targets.count = calc_max_targets(new_targets.count)

  if new_targets.count == 0 then
    stdnse.print_debug(3,
        "Warning: Maximum new targets reached, no more new targets.")
    return false, "Maximum new targets reached, no more new targets."
  end

  local hosts, err = nmap.add_targets(unpack(new_targets,1,new_targets.count))

  if hosts == 0 then
    stdnse.print_debug(3, "%s", err)
    return false, err
  end

  return true, hosts
end


text:
class "HitAnimationComponent" {
	extends "DisplayComponent",

	-- Override
	new = function (self, x,y, width,height)
		self:super(x,y, width,height)

		self.useRainbowColor = false
		self.rainbowColorHueShift = 0.5
		self.rainbowColorSaturation = 0.8
		self.rainbowColorValue = 0.8
		self.colorAlpha = 0.8

		self.fadingOutSpeed = 1.0
		self.lengthScale = 1.0
		self.sizeScale = 1.0

		self.useDefaultTheme = true
		self.sprite = Sprite()
	end,

	-- Implement
	update = function (self, dt)
	end,

	-- Implement
	draw = function (self, screenWidth,screenHeight, lowestKey, highestKey, keyGap)
		if not self.enabled then
			return
		end

		love.graphics.push()

		--//////// Common Infomation ////////
		local song = player:getSong()

		local sortedTracks = song:getSortedTracks()
		local time = player:getTimeManager():getTime()

		local timeDivision = song:getTimeDivision()

		if self.orientation == 1 or self.orientation == 3 then
			if self.orientation == 1 then
				love.graphics.translate(0,screenHeight)
				love.graphics.scale(1,-1)
			end
			love.graphics.translate(screenWidth, 0)
			love.graphics.rotate(math.pi/2)

			screenWidth, screenHeight = screenHeight, screenWidth

		elseif self.orientation == 2 then
			love.graphics.translate(screenWidth, 0)
			love.graphics.scale(-1,1)
		end

		local spaceForEachKey = (self.height*screenHeight) / (highestKey-lowestKey+1)
		local keyHeightRatio = 1 - keyGap
		local absoluteKeyGap = keyGap*spaceForEachKey

		local leftBoundary = math.floor(self.x * screenWidth)
		local rightBoundary = leftBoundary + math.floor(self.width * screenWidth)

		local firstNonPlayedNoteIDInTracks = player:getFirstNonPlayedNoteIDInTracks()

		--//////// Main Section ////////
		love.graphics.translate(0, screenHeight*self.y)

		-- love.graphics.translate(0, absoluteKeyGap/2)

		-- local scissorWidth = math.clamp(rightBoundary-leftBoundary, 0,screenWidth)
		-- if self.orientation == 0 then
			-- love.graphics.setScissor(leftBoundary, 0, scissorWidth, screenHeight)
		-- elseif self.orientation == 1 then
			-- love.graphics.setScissor(0, screenWidth-rightBoundary, screenWidth, scissorWidth)
		-- elseif self.orientation == 2 then
			-- love.graphics.setScissor(screenWidth-rightBoundary, 0, scissorWidth, screenHeight)
		-- elseif self.orientation == 3 then
			-- love.graphics.setScissor(0, leftBoundary, screenHeight, scissorWidth)
		-- end

		for i, track in ipairs(sortedTracks) do
			local trackID = track:getID()

			if track:getEnabled() then
				local notes = track:getNotes()

				for noteID = firstNonPlayedNoteIDInTracks[trackID]-1, 1, -1 do

					local note = notes[noteID]
					local noteTime = note:getTime()
					local noteLength = note:getLength() or 0
					local notePitch = note:getPitch()

					if notePitch >= lowestKey and notePitch <= highestKey then
						local noteY = (highestKey-notePitch) * spaceForEachKey
						local noteHeight = math.max(((self.height*screenHeight) / (highestKey-lowestKey+1))*keyHeightRatio, 0)

						local h,s,v,a
						if self.useRainbowColor then
							h,s,v = ((notePitch-lowestKey) / highestKey + self.rainbowColorHueShift) % 1, self.rainbowColorSaturation, self.rainbowColorValue
						else
							h,s,v = unpack(track:getCustomColorHSV())
						end

						local displacement = self.fadingOutSpeed * 100 * (time - noteTime) / timeDivision / 2

						local t = math.max(displacement, 0)
						local size
						a = 1 - math.clamp(displacement / 100, 0, 1)

						if a <= 0 then
							break
						end

						love.graphics.setColor(vivid.HSVtoRGB(h,s,v,self.colorAlpha*a))

						love.graphics.push()
							love.graphics.translate(rightBoundary,noteY)
							love.graphics.translate(2*self.lengthScale*spaceForEachKey,0)

							if self.useDefaultTheme then
								size = spaceForEachKey*t/50
								size = size * self.sizeScale
								love.graphics.rectangle("fill", -size/2 -t*4 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2, size, size)

								love.graphics.push()
									size = spaceForEachKey*t/40
									size = size * self.sizeScale
									love.graphics.rectangle("fill", -size/2 -t*3 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2-(t^2)/200, size, size)
								love.graphics.pop()

								size = spaceForEachKey*t/30
								size = size * self.sizeScale
								love.graphics.rectangle("fill", -size/2 -t*2 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2+(t^2)/200, size, size, 0.2)

							else
								size = spaceForEachKey*t/50
								size = size * self.sizeScale
								self.sprite:draw(-size/2 -t*4 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2, size, size, screenWidth,screenHeight)

								love.graphics.push()
									size = spaceForEachKey*t/40
									size = size * self.sizeScale
									self.sprite:draw(-size/2 -t*3 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2-(t^2)/200, size, size, screenWidth,screenHeight)
								love.graphics.pop()

								size = spaceForEachKey*t/30
								size = size * self.sizeScale
								self.sprite:draw(-size/2 -t*2 * self.lengthScale*spaceForEachKey/16, -size/2 + spaceForEachKey/2+(t^2)/200, size, size, screenWidth,screenHeight)
							end
						love.graphics.pop()
					end
				end
			end
		end

		love.graphics.setScissor()

		love.graphics.pop()
	end,
}