local utils utils = { is_list: (t)-> i = 1 for _ in pairs(t) if t[i] == nil then return false i += 1 return true repr: (x, add_quotes=false)-> switch type(x) when 'table' if utils.is_list x "{#{table.concat([utils.repr(i, true) for i in *x], ", ")}}" else "{#{table.concat(["[#{utils.repr(k, true)}]: #{utils.repr(v, true)}" for k,v in pairs x], ", ")}}" when 'string' if not add_quotes x elseif not x\find[["]] "\"#{x}\"" elseif not x\find[[']] "\'#{x}\'" else for i=0,math.huge eq = ("=")\rep(i) if not x\find"%[#{eq}%[" and not x\find"%]#{eq}%]" return "[#{eq}[#{x}]#{eq}]" else tostring(x) split: (str, sep="%s")-> [chunk for chunk in str\gmatch("[^#{sep}]+")] keys: (t)-> [k for k in pairs(t)] values: (t)-> [v for _,v in pairs(t)] set: (list)-> {i,true for i in *list} sum: (t)-> with tot = 0 for _,x in pairs(t) do tot += x all: (t)-> for _,x in pairs t if not x then return false return true any: (t)-> for _,x in pairs t if x then return true return false min: (list, keyFn=((x)->x))-> assert utils.is_list(list), "min() expects to be operating on a list" with best = list[1] if type(keyFn) == 'table' keyTable = keyFn keyFn = (k)->keyTable[k] for i=2,#list if keyFn(list[i]) < keyFn(best) best = list[i] max: (list, keyFn=((x)->x))-> assert utils.is_list(list), "min() expects to be operating on a list" with best = list[1] if type(keyFn) == 'table' keyTable = keyFn keyFn = (k)->keyTable[k] for i=2,#list if keyFn(list[i]) > keyFn(best) best = list[i] sort: (list, keyFn=((x)->x), reverse=false)-> assert utils.is_list(list), "min() expects to be operating on a list" if type(keyFn) == 'table' keyTable = keyFn keyFn = (k)->keyTable[k] comparison = if reverse then ((x,y)->(keyFn(x)>keyFn(y))) else ((x,y)->(keyFn(x) if x == y then return true if type(x) != type(y) then return false if type(x) != 'table' then return false for k,v in pairs(x) if y[k] != v return false for k,v in pairs(y) if x[k] != v return false return true key_for: (t, value)-> for k,v in pairs(t) if v == value return k return nil clamp: (x, min,max)-> if x < min then min elseif x > max then max else x mix: (min,max, amount)-> (1-amount)*min + amount*max sign: (x)-> if x == 0 then 0 elseif x < 0 then -1 else 1 round: (x, increment=1)-> if x >= 0 then math.floor(x/increment + .5)*increment else math.ceil(x/increment - .5)*increment } return utils