assert(LibStub,"\076\105\098\068\097\116\097\066\114\111\107\101\114-\049\046\049 \114\101\113\117\105\114\101\115 \076\105\098\083\116\117\098")assert(LibStub:GetLibrary("\067\097\108\108\098\097\099\107\072\097\110\100\108\101\114-\049\046\048",true),"\076\105\098\068\097\116\097\066\114\111\107\101\114-\049\046\049 \114\101\113\117\105\114\101\115 \067\097\108\108\098\097\099\107\072\097\110\100\108\101\114-\049\046\048")local c,y=LibStub:NewLibrary("\076\105\098\068\097\116\097\066\114\111\107\101\114-\049\046\049",4)if not c then return end y=y or 0 c.callbacks=c.callbacks or(LibStub:GetLibrary("\067\097\108\108\098\097\099\107\072\097\110\100\108\101\114-\049\046\048")):New(c)c.attributestorage,c.namestorage,c.proxystorage=c.attributestorage or{},c.namestorage or{},c.proxystorage or{}local K,T,X=c.attributestorage,c.namestorage,c.callbacks if y<2 then c.domt={__metatable="\097\099\099\101\115\115 \100\101\110\105\101\100";__index=function(c,y)return K[c]and K[c][y]end}end if y<3 then c.domt.__newindex=function(c,y,z)if not K[c]then K[c]={}end if K[c][y]==z then return end K[c][y]=z local B=T[c]if not B then return end X:Fire("\076\105\098\068\097\116\097\066\114\111\107\101\114\095\065\116\116\114\105\098\117\116\101\067\104\097\110\103\101\100",B,y,z,c)X:Fire("\076\105\098\068\097\116\097\066\114\111\107\101\114\095\065\116\116\114\105\098\117\116\101\067\104\097\110\103\101\100\095"..B,B,y,z,c)X:Fire("\076\105\098\068\097\116\097\066\114\111\107\101\114\095\065\116\116\114\105\098\117\116\101\067\104\097\110\103\101\100\095"..(B..("\095"..y)),B,y,z,c)X:Fire("\076\105\098\068\097\116\097\066\114\111\107\101\114\095\065\116\116\114\105\098\117\116\101\067\104\097\110\103\101\100\095\095"..y,B,y,z,c)end end if y<2 then function c.NewDataObject(K,c,y)if K.proxystorage[c]then return end if y then assert(type(y)=="\116\097\098\108\101","\073\110\118\097\108\105\100 \100\097\116\097\111\098\106\044 \109\117\115\116 \098\101 \110\105\108 \111\114 \097 \116\097\098\108\101")K.attributestorage[y]={}for c,T in pairs(y)do K.attributestorage[y][c]=T y[c]=nil end end y=setmetatable(y or{},K.domt)K.proxystorage[c],K.namestorage[y]=y,c K.callbacks:Fire("\076\105\098\068\097\116\097\066\114\111\107\101\114\095\068\097\116\097\079\098\106\101\099\116\067\114\101\097\116\101\100",c,y)return y end end if y<1 then function c.DataObjectIterator(c)return pairs(c.proxystorage)end function c.GetDataObjectByName(y,c)return y.proxystorage[c]end function c.GetNameByDataObject(y,c)return y.namestorage[c]end end if y<4 then local y=pairs(K)function c.pairs(T,c)local X=type(c)assert(X=="\115\116\114\105\110\103"or X=="\116\097\098\108\101","\085\115\097\103\101\058 \108\100\098\058\112\097\105\114\115\040\'\100\097\116\097\111\098\106\101\099\116\110\097\109\101\'\041 \111\114 \108\100\098\058\112\097\105\114\115\040\100\097\116\097\111\098\106\101\099\116\041")local z=T.proxystorage[c]or c assert(K[z],"\068\097\116\097 \111\098\106\101\099\116 \110\111\116 \102\111\117\110\100")return y,K[z],nil end local T=ipairs(K)function c.ipairs(y,c)local X=type(c)assert(X=="\115\116\114\105\110\103"or X=="\116\097\098\108\101","\085\115\097\103\101\058 \108\100\098\058\105\112\097\105\114\115\040\'\100\097\116\097\111\098\106\101\099\116\110\097\109\101\'\041 \111\114 \108\100\098\058\105\112\097\105\114\115\040\100\097\116\097\111\098\106\101\099\116\041")local z=y.proxystorage[c]or c assert(K[z],"\068\097\116\097 \111\098\106\101\099\116 \110\111\116 \102\111\117\110\100")return T,K[z],0 end end

assert(LibStub, "LibDataBroker-1.1 requires LibStub")
assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")

local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
if not lib then return end
oldminor = oldminor or 0


lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks

if oldminor < 2 then
	lib.domt = {
		__metatable = "access denied",
		__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
	}
end

if oldminor < 3 then
	lib.domt.__newindex = function(self, key, value)
		if not attributestorage[self] then attributestorage[self] = {} end
		if attributestorage[self][key] == value then return end
		attributestorage[self][key] = value
		local name = namestorage[self]
		if not name then return end
		callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
		callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
		callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
		callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
	end
end

if oldminor < 2 then
	function lib:NewDataObject(name, dataobj)
		if self.proxystorage[name] then return end

		if dataobj then
			assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
			self.attributestorage[dataobj] = {}
			for i,v in pairs(dataobj) do
				self.attributestorage[dataobj][i] = v
				dataobj[i] = nil
			end
		end
		dataobj = setmetatable(dataobj or {}, self.domt)
		self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
		self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
		return dataobj
	end
end

if oldminor < 1 then
	function lib:DataObjectIterator()
		return pairs(self.proxystorage)
	end

	function lib:GetDataObjectByName(dataobjectname)
		return self.proxystorage[dataobjectname]
	end

	function lib:GetNameByDataObject(dataobject)
		return self.namestorage[dataobject]
	end
end

if oldminor < 4 then
	local next = pairs(attributestorage)
	function lib:pairs(dataobject_or_name)
		local t = type(dataobject_or_name)
		assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")

		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
		assert(attributestorage[dataobj], "Data object not found")

		return next, attributestorage[dataobj], nil
	end

	local ipairs_iter = ipairs(attributestorage)
	function lib:ipairs(dataobject_or_name)
		local t = type(dataobject_or_name)
		assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")

		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
		assert(attributestorage[dataobj], "Data object not found")

		return ipairs_iter, attributestorage[dataobj], 0
	end
end
