function push(t,v) table.insert(t,v) end
function pop(t) return table.remove(t) end
function len(t) return #t end
function shift(t) return table.remove(t,1) end
function pick(v,a,b) if v then return a end return b end
function bool(v) return not not v end
min = math.min
max = math.max
abs = math.abs
function round(v) return math.floor(v + 0.5) end
function sign(v) if v > 0 then return 1 end if v < 0 then return -1 end return 0 end
function ucfirst(s)
    return string.upper(string.sub(s,1,1))..string.sub(s,2)
end
function shuffle(t)
    for i,v in ipairs(t) do
        local n = math.random(i,#t)
        t[i] = t[n]
        t[n] = v
    end
end    
function find(t,v)
    for kk,vv in ipairs(t) do
        if vv == v then return kk end
    end
    return false
end

function class(name,base)
    local G = _ENV or _G
    if global ~= nil then global(name) end
    G[name] = G[name] or {}
    local klass = G[name]
    if base ~= nil then for k,v in pairs(base) do klass[k] = v end end
    klass.__index = klass
    function klass:method(k)
        return klass[k] ~= null
    end
    local meta = {}
    function meta:__call(...)
        local obj = {}
        setmetatable(obj,klass)
        obj:init(...)
        return obj
    end
    setmetatable(klass,meta)
    return klass
end

function namespace(ns)
    local G = _ENG or _G
    if global ~= nil then global(ns) end
    if G[ns] == nil then G[ns] = {} end
    return G[ns]
end

function ns_class(ns,name,base)
    local NS = namespace(ns)
    local klass = class(ns..":"..name,base)
    NS[name] = klass
    return klass
end

function deepcopy(o)
    if type(o) ~= 'table' then return o end
    local r = {}
    for k,v in pairs(o) do r[k] = deepcopy(v) end
    return r
end

function shallowcopy(o)
    if type(o) ~= 'table' then return o end
    local r = {}
    for k,v in pairs(o) do r[k] = v end
    return r
end

function mknumber(v)
    v = tonumber(v)
    if v ~= nil then return v end
    return 0
end
function str_split(str,delim)
    local r = {}
    for k in (str..delim):gmatch("([^"..delim.."]*)"..delim) do
        r[#r+1] = k
    end
    return r
end
function trim(s)
  return (s:gsub("^%s*(.-)%s*$", "%1"))
end
-- str_clean: removes all excess whitespace
function str_clean(v)
    v = v:gsub("\t"," ")
    v = v:gsub("\n"," ")
    v = v:gsub("\r"," ")
    v = v:gsub(" +"," ")
    v = trim(v)
    return v
end

function number_format_long(v)
    v = tostring(math.floor(mknumber(v)))
    local n = 1
    while n > 0 do
        v,n = v:gsub("(%d+)(%d%d%d)","%1,%2")
    end
    return v 
end
