dump = function (o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end


-- Minimally effective quoting
quote = function (astring)
    local quoted1 = string.gsub(astring,'\"', '\\"')
    local quoted2 = '"' .. string.gsub(quoted1,"%'", "\\'") .. '"'
	local linefeed = string.gsub(quoted2,"\n", "\\n")
	return linefeed
end


write_saved = function (o)
--	local escaped
   if type(o) == 'table' then
      local s = '{\n'
      for k,v in pairs(o) do
         if type(k) ~= 'number' then
		 k = '"'..k..'"'
		 end
         s = s .. '['..k..'] = ' .. write_saved(v) .. ',\n'
      end
      return s .. '}\n'
   elseif
		type(o) == 'string' then
		return quote(o)
   else
		return tostring(o)
   end
end

_size = function (t)		-- return number of elements in table
	local i = 0
	for _,_ in pairs(t) do
		i = i +1
	end
	return i
end

reverse_id = function (Adata)	-- given a grp-id table like this
	--[[

	Grp_Dat["1N"].id = {
	[294]= {L=1, C=1},		-- "Fungal Grotto I Vanquisher",
	[78]= {L=2, C=1},		-- "Darkshade Caverns I Vanquisher"
	[272]= {L=3, C=1},		-- "Arx Corinium Vanquisher"
	[357]= {L=4, C=1},		-- "Direfrost Keep Vanquisher"
	[393]= {L=5, C=1},		-- "Blessed Crucible Vanquisher"

	return a table like this
	["11"] = 294
	["21"] = 78
	]]
	local rev = {}
	for ach, lc in pairs (Adata) do
		local key
		key = lc.L .. lc.C
		if rev[key] == nil then
			rev[key] = ach
		else
			print ("error dup " .. key)
		end
	end
	return rev
end


reverse_key = function (Adata)
--given a key table like this
 --[[
	 grp1tokey = {
	--EP
	"11",
	"21",
	"31",
	"41",
	"51",
	--DC
	"12",
	"22",
	"32",
	"42",
	"52",
	--AD
	"13",
	"23",
	"33",
	"43",
	"53",
	--Coldharbour
	"54",
	}
	return a reverse table lkiek this --]]


end