local load = load local loadfile = loadfile local debug = debug local xpcall = xpcall local type = type local debugGetupvalue = debug.getupvalue local debugUpvaluejoin = debug.upvaluejoin local error = error local debugGetinfo = debug.getinfo local getmetatable = getmetatable local setmetatable = setmetatable local debugGetlocal = debug.getlocal local mathAtan = math.atan local stringFormat = string.format local stringMatch = string.match local tonumber = tonumber local mathLog = math.log local osExit = os.exit local stringRep = string.rep local stringGmatch = string.gmatch local tableConcat = table.concat local pairs = pairs local ipairs = ipairs local loadfile = loadfile local EXP = math.exp(1) local PI = math.pi local RAD = PI / 180.0 local lua51 = {} local FenvCache = setmetatable({}, { __mode = 'kv' }) ---@param obj any ---@param expect string | "'nil'" | "'number'" | "'string'" | "'boolean'" | "'function'" | "'table'" | "'userdata'" | "'thread'" local function checkType(obj, expect, level) local tp = type(obj) if tp ~= expect then error(stringFormat("%s expected, got %s", expect, tp), level and (level + 1) or 3) end end local function getFunc(f, level) if type(f) == 'function' then return f end if not level then level = 3 end checkType(f, 'number', level) if f < 0 then error('level must be non-negative', level) end local info = debugGetinfo(f + level - 1, 'f') if not info then error('invalid level', level) end if not info.func then error(stringFormat('no function environment for tail call at level %d', f), level) end return info.func end local function findTable(name) local pg = {} local current = lua51._G for id in stringGmatch(name, '[^%.]+') do id = stringMatch(id, '^%s*(.-)%s*$') pg[#pg+1] = id local field = rawget(current, id) if field == nil then field = {} current[id] = field elseif type(field) ~= 'table' then return nil, tableConcat(pg, '.') end current = field end return current end local function setfenv(f, tbl) local tp = type(f) if tp ~= 'function' and tp ~= 'userdata' and tp ~= 'thread' then error [['setfenv' cannot change environment of given object]] end FenvCache[f] = tbl if debugGetupvalue(f, 1) ~= '_ENV' then return end local function dummy() return tbl end debugUpvaluejoin(f, 1, dummy, 1) end local function getfenv(f) if FenvCache[f] then return FenvCache[f] end local _, v = debugGetupvalue(f, 1) return v end local function copyTable(t) local nt = {} for k, v in pairs(t) do nt[k] = v end return nt end local function requireLoad(name) local msg = '' if type(lua51._G.package.loaders) ~= 'table' then error("'package.loaders' must be a table", 3) end for _, searcher in ipairs(lua51._G.package.loaders) do local f = searcher(name) if type(f) == 'function' then return f elseif type(f) == 'string' then msg = msg .. f end end error(("module '%s' not found:%s"):format(name, msg), 3) end local function requireWithEnv(name, env) local loaded = lua51._G.package.loaded if type(name) ~= 'string' then error(("bad argument #1 to 'require' (string expected, got %s)"):format(type(name)), 2) end local p = loaded[name] if p ~= nil then return p end local init = requireLoad(name) if type(env) == 'table' then if debug.getupvalue(init, 1) == '_ENV' then debug.setupvalue(init, 1, env) end end local res = init(name) if res ~= nil then loaded[name] = res end if loaded[name] == nil then loaded[name] = true end return loaded[name] end lua51.arg = arg lua51.assert = assert lua51.collectgarbage = collectgarbage function lua51.dofile(name) local f, err if name then f, err = loadfile(name) else f, err = loadfile() end if not f then error(err, 2) end return f() end lua51.error = error lua51._G = lua51 function lua51.getfenv(f) f = getFunc(f) return getfenv(f) end lua51.getmetatable = getmetatable lua51.ipairs = ipairs function lua51.load(func, name) checkType(func, 'function') return load(func, name, 'bt', lua51._G) end function lua51.loadfile(name) return loadfile(name, 'bt', lua51._G) end function lua51.loadstring(str, name) checkType(str, 'string') return load(str, name, 'bt', lua51._G) end function lua51.module(name, ...) checkType(name, 'string') local loaded = lua51._G.package.loaded local mod = loaded[name] if type(mod) ~= 'table' then local err mod, err = findTable(name) if not mod then error('name conflict for module ' .. err) end loaded[name] = mod end if mod._NAME == nil then mod._M = mod mod._NAME = name mod._PACKAGE = stringMatch(name, '(.-)[^%.]+$') end local f = getFunc(1) setfenv(f, mod) for _, func in ipairs {...} do func(mod) end end lua51.next = next lua51.pairs = pairs lua51.pcall = pcall lua51.print = print lua51.rawequal = rawequal lua51.rawget = rawget lua51.rawlen = rawlen lua51.rawset = rawset lua51.select = select function lua51.setfenv(f, tbl) f = getFunc(f) setfenv(f, tbl) end lua51.setmetatable = setmetatable lua51.tonumber = tonumber lua51.tostring = tostring lua51.type = type lua51._VERSION = 'Lua 5.1' function lua51.xpcall(f, msgh) checkType(f, 'function') checkType(f, 'function') return xpcall(f, msgh) end function lua51.require(name) return requireWithEnv(name, lua51._G) end lua51.unpack = table.unpack lua51.coroutine = {} lua51.coroutine.create = coroutine.create lua51.coroutine.isyieldable = coroutine.isyieldable lua51.coroutine.resume = coroutine.resume lua51.coroutine.running = coroutine.running lua51.coroutine.status = coroutine.status lua51.coroutine.wrap = coroutine.wrap lua51.coroutine.yield = coroutine.yield lua51.debug = {} lua51.debug.debug = debug.debug lua51.debug.getfenv = getfenv lua51.debug.gethook = debug.gethook lua51.debug.getinfo = debug.getinfo function lua51.debug.getlocal(...) local n = select('#', ...) if n == 2 then local level, loc = ... checkType(level, 'number') return debugGetlocal(level, loc) else local th, level, loc = ... return debugGetlocal(th, level, loc) end end lua51.debug.getmetatable = debug.getmetatable lua51.debug.getregistry = debug.getregistry lua51.debug.getupvalue = debug.getupvalue lua51.debug.getuservalue = debug.getuservalue lua51.debug.setfenv = setfenv lua51.debug.sethook = debug.sethook lua51.debug.setlocal = debug.setlocal lua51.debug.setmetatable = debug.setmetatable lua51.debug.setupvalue = debug.setupvalue lua51.debug.setuservalue = debug.setuservalue lua51.debug.traceback = debug.traceback lua51.io = {} lua51.io.stdin = io.stdin lua51.io.stdout = io.stdout lua51.io.stderr = io.stderr lua51.io.close = io.close lua51.io.flush = io.flush lua51.io.input = io.input lua51.io.lines = io.lines lua51.io.open = io.open lua51.io.output = io.output lua51.io.popen = io.popen lua51.io.read = io.read lua51.io.tmpfile = io.tmpfile lua51.io.type = io.type lua51.io.write = io.write lua51.math = {} lua51.math.abs = math.abs lua51.math.acos = math.acos lua51.math.asin = math.asin function lua51.math.atan(y) return mathAtan(y) end function lua51.math.atan2(y, x) checkType(x, 'number') return mathAtan(y, x) end lua51.math.ceil = math.ceil lua51.math.cos = math.cos function lua51.math.cosh(x) return (EXP ^ x + EXP ^ -x) / 2.0 end function lua51.math.deg(x) return x / RAD end function lua51.math.exp() return EXP end lua51.math.floor = math.floor lua51.math.fmod = math.fmod function lua51.math.frexp(x) if x == 0 then return 0.0, 0 end if x ~= x then return x, 0 end local dump = stringFormat('%q', x + 0.0) local mstr, estr = stringMatch(dump, '^(.-)[pP](.+)$') if not mstr then return x, 0 end local m = tonumber(mstr) local e = tonumber(estr) if m == 0 then return m, e end m = m / 2.0 e = e + 1 return m, e end lua51.math.huge = math.huge function lua51.math.ldexp(m, e) return m * (2 ^ e) end function lua51.math.log(x) return mathLog(x) end function lua51.math.log10(x) return mathLog(x, 10) end lua51.math.max = math.max lua51.math.min = math.min lua51.math.modf = math.modf lua51.math.pi = math.pi function lua51.math.pow(x, y) return x ^ y end function lua51.math.rad(x) return x * RAD end lua51.math.random = math.random lua51.math.randomseed = math.randomseed lua51.math.sin = math.sin function lua51.math.sinh(x) return (EXP ^ x - EXP ^ -x) / 2.0 end lua51.math.sqrt = math.sqrt lua51.math.tan = math.tan function lua51.math.tanh(x) local a = EXP ^ x local b = EXP ^ -x return (a - b) / (a + b) end lua51.os = {} lua51.os.close = os.clock lua51.os.date = os.date lua51.os.difftime = os.difftime lua51.os.execute = os.execute function lua51.os.exit(code) code = tonumber(code) or 0 osExit(code) end lua51.os.getenv = os.getenv lua51.os.remove = os.remove lua51.os.rename = os.rename lua51.os.setlocale = os.setlocale lua51.os.time = os.time lua51.os.tmpname = os.tmpname lua51.package = {} lua51.package.config = package.config lua51.package.cpath = package.cpath lua51.package.loaded = copyTable(package.loaded) lua51.package.loaders = copyTable(package.searchers) lua51.package.loadlib = package.loadlib lua51.package.path = package.path lua51.package.preload = copyTable(package.preload) function lua51.package.seeall(mod) local mt = getmetatable(mod) if not mt then mt = {} setmetatable(mod, mt) end mt.__index = lua51._G end -- WTF ('').format lua51.string = {} lua51.string.byte = string.byte lua51.string.char = string.char lua51.string.dump = string.dump lua51.string.find = string.find lua51.string.format = string.format lua51.string.gmatch = string.gmatch lua51.string.gsub = string.gsub lua51.string.len = string.len lua51.string.lower = string.lower lua51.string.match = string.match function lua51.string.rep(s, n) return stringRep(s, n) end lua51.string.reverse = string.reverse lua51.string.sub = string.sub lua51.string.upper = string.upper lua51.table = {} lua51.table.concat = table.concat lua51.table.insert = table.insert function lua51.table.maxn(t) checkType(t, 'table') local max = 0 for k in pairs(t) do if type(k) == 'number' then if k > max then max = k end end end return max end lua51.table.remove = table.remove lua51.table.sort = table.sort return lua51