local p={}p.contains=function(p,d)for p,L in pairs(p)do if L==d then return p end end return false end p.len=function(p)local d=0 for p,L in pairs(p)do d=d+1 end return d end p.keys=function(p)local d={}for p,L in pairs(p)do table.insert(d,p)end return d end p.values=function(p)local d={}for p,L in pairs(p)do table.insert(d,L)end return d end p.xsort=function(d,L)local J=p.keys(d)table.sort(J,L)return function()if#J==0 then return nil end local p=table.remove(J,1)return p,d[p]end end p.vsort=function(d,L)L=L or function(p,d)return p>d end return p.xsort(d,function(p,J)return L(d[p],d[J])end)end p.choice=function(d,L)L=L or 1 local J={}local W={}for p,d in pairs(d)do W[p]=d end local F=p.keys(W)for p=1,math.min(#d,math.max(L,1)),1 do table.insert(J,d[table.remove(F,math.random(#F))])end return unpack(J)end p.one=function(p)return p[math.random(#p)]end p.shallow=function(p)local d={}for p,L in pairs(p)do d[p]=L end return d end p.deep=function(d)local L={}for d,J in pairs(d)do if typeof(J)=="\116\097\098\108\101"then L[d]=p.deep(J)else L[d]=J end end return L end p.cloneKeys=function(p)local d={}for p,L in pairs(p)do d[p]=true end return d end p.dump=function(d,L)L=L or""for d,J in pairs(d)do print(("\037\115\037\115 \061 \037\115"):format(L,tostring(d),tostring(J)))if typeof(J)=="\116\097\098\108\101"then p.dump(J,("\037\115\046\037\115"):format(L,d))end end end p.merge=function(p,...)local d={}for p,L in pairs({p,...})do for p,L in pairs(L)do table.insert(d,L)end end return d end return setmetatable(p,{__index=table})
local newTable = {}

newTable.contains = function(tbl, val)
	for i,v in pairs(tbl) do
		if v == val then
			return i
		end
	end
	
	return false
end

newTable.len = function(tbl)
	local len = 0
	
	for _,_ in pairs(tbl) do
		len = len + 1
	end
	
	return len
end

newTable.keys = function(tbl)
	local ret = {}
	
	for key,_ in pairs(tbl) do
		table.insert(ret, key)
	end
	
	return ret
end

newTable.values = function(tbl)
	local ret = {}
	
	for _,val in pairs(tbl) do
		table.insert(ret, val)
	end
	
	return ret
end

--sort by keys
newTable.xsort = function(tbl, sort)
	local keys = newTable.keys(tbl)
	
	table.sort(keys, sort)
	
	return function()
		if #keys == 0 then
			return nil
		end
		
		local nextValue = table.remove(keys, 1)
		
		return nextValue, tbl[nextValue]
	end
end

--sort by values
newTable.vsort = function(tbl, sort)
	sort = sort or function(x, y)
		return x > y
	end
	
	return newTable.xsort(tbl, function(x, y)
		return sort(tbl[x], tbl[y])
	end)
end

newTable.choice = function(tbl, resultCount)
	resultCount = resultCount or 1
	
	local results = {}
	
	--clone the table
	local clone = {}
	
	for i,v in pairs(tbl) do
		clone[i] = v
	end
	
	local keys = newTable.keys(clone)
	
	for i=1,math.min(#tbl, math.max(resultCount, 1)) do
		table.insert(results, tbl[table.remove(keys, math.random(#keys))])
	end
	
	return unpack(results)
end

newTable.one = function(tbl)
	return tbl[math.random(#tbl)]
end

newTable.shallow = function(tbl)
	local clone = {}
	
	for key,val in pairs(tbl) do
		clone[key] = val
	end
	
	return clone
end

newTable.deep = function(tbl)
	local clone = {}
	
	for key,val in pairs(tbl) do
		if typeof(val) == "table" then
			clone[key] = newTable.deep(val)
		else
			clone[key] = val
		end
	end
	
	return clone
end

newTable.cloneKeys = function(tbl)
	local ret = {}
	
	for key,_ in pairs(tbl) do
		ret[key] = true
	end
	
	return ret
end

newTable.dump = function(tbl, prefix)
	prefix = prefix or ""
	
	for key,val in pairs(tbl) do
		print(("%s%s = %s"):format(prefix, tostring(key), tostring(val)))
		
		if typeof(val) == "table" then
			newTable.dump(val, ("%s.%s"):format(prefix, key))
		end
	end
end

newTable.merge = function(tbl, ...)
	local ret = {}
	
	for _,tbl in pairs({tbl, ...}) do
		for _,value in pairs(tbl) do
			table.insert(ret, value)
		end
	end
	
	return ret
end

return setmetatable(newTable, {
	__index = table
})
