local function l(l,G,M)local C=Replicas[l]local s=C.Data local k=C._table_listeners for l=1,#G-1,1 do s=s[G[l]]if k~=nil then k=k[1][G[l]]end end local w=G[#G]local W=s[w]s[w]=M if W~=M and k~=nil then if W==nil then if k[3]~=nil then for l,G in ipairs(k[3])do G(M,w)end end end k=k[1][G[#G]]if k~=nil then if k[2]~=nil then for l,G in ipairs(k[2])do G(M,W)end end end end for l,C in ipairs(C._raw_listeners)do C("\083\101\116\086\097\108\117\101",G,M)end end local function G(l,G,M)local C=Replicas[l]local s=C.Data local k=C._table_listeners for l=1,#G,1 do s=s[G[l]]if k~=nil then k=k[1][G[l]]end end for l,G in pairs(M)do local M=s[l]s[l]=G if M~=G and k~=nil then if M==nil then if k[3]~=nil then for M,C in ipairs(k[3])do C(G,l)end end end local C=k[1][l]if C~=nil then if C[2]~=nil then for l,C in ipairs(C[2])do C(G,M)end end end end end for l,C in ipairs(C._raw_listeners)do C("\083\101\116\086\097\108\117\101\115",G,M)end end local function M(l,G,M)local C=Replicas[l]local s=C.Data local k=C._table_listeners for l=1,#G,1 do s=s[G[l]]if k~=nil then k=k[1][G[l]]end end table.insert(s,M)local w=#s if k~=nil then if k[4]~=nil then for l,G in ipairs(k[4])do G(w,M)end end end for l,C in ipairs(C._raw_listeners)do C("\065\114\114\097\121\073\110\115\101\114\116",G,M,w)end return w end local function C(l,G,M,C)local s=Replicas[l]local k=s.Data local w=s._table_listeners for l=1,#G,1 do k=k[G[l]]if w~=nil then w=w[1][G[l]]end end k[M]=C if w~=nil then if w[5]~=nil then for l,G in ipairs(w[5])do G(M,C)end end end for l,s in ipairs(s._raw_listeners)do s("\065\114\114\097\121\083\101\116",G,M,C)end end local function s(l,G,M)local C=Replicas[l]local s=C.Data local k=C._table_listeners for l=1,#G,1 do s=s[G[l]]if k~=nil then k=k[1][G[l]]end end local w=table.remove(s,M)if k~=nil then if k[6]~=nil then for l,G in ipairs(k[6])do G(M,w)end end end for l,C in ipairs(C._raw_listeners)do C("\065\114\114\097\121\082\101\109\111\118\101",G,M,w)end return w end


local function ReplicaSetValue(replica_id, path_array, value)
	local replica = Replicas[replica_id]
	-- Getting path pointer and listener table:
	local pointer = replica.Data
	local listeners = replica._table_listeners
	for i = 1, #path_array - 1 do
		pointer = pointer[path_array[i]]
		if listeners ~= nil then
			listeners = listeners[1][path_array[i]]
		end
	end
	-- Setting value:
	local key = path_array[#path_array]
	local old_value = pointer[key]
	pointer[key] = value
	-- Signaling listeners:
	if old_value ~= value and listeners ~= nil then
		if old_value == nil then
			if listeners[3] ~= nil then -- "NewKey" listeners
				for _, listener in ipairs(listeners[3]) do
					listener(value, key)
				end
			end
		end
		listeners = listeners[1][path_array[#path_array]]
		if listeners ~= nil then
			if listeners[2] ~= nil then -- "Change" listeners
				for _, listener in ipairs(listeners[2]) do
					listener(value, old_value)
				end
			end
		end
	end
	-- Raw listeners:
	for _, listener in ipairs(replica._raw_listeners) do
		listener("SetValue", path_array, value)
	end
end

local function ReplicaSetValues(replica_id, path_array, values)
	local replica = Replicas[replica_id]
	-- Getting path pointer and listener table:
	local pointer = replica.Data
	local listeners = replica._table_listeners
	for i = 1, #path_array do
		pointer = pointer[path_array[i]]
		if listeners ~= nil then
			listeners = listeners[1][path_array[i]]
		end
	end
	-- Setting values:
	for key, value in pairs(values) do
		-- Set value:
		local old_value = pointer[key]
		pointer[key] = value
		-- Signaling listeners:
		if old_value ~= value and listeners ~= nil then
			if old_value == nil then
				if listeners[3] ~= nil then -- "NewKey" listeners
					for _, listener in ipairs(listeners[3]) do
						listener(value, key)
					end
				end
			end
			local key_listeners = listeners[1][key]
			if key_listeners ~= nil then
				if key_listeners[2] ~= nil then -- "Change" listeners
					for _, listener in ipairs(key_listeners[2]) do
						listener(value, old_value)
					end
				end
			end
		end
	end
	-- Raw listeners:
	for _, listener in ipairs(replica._raw_listeners) do
		listener("SetValues", path_array, values)
	end
end

local function ReplicaArrayInsert(replica_id, path_array, value) --> new_index
	local replica = Replicas[replica_id]
	-- Getting path pointer and listener table:
	local pointer = replica.Data
	local listeners = replica._table_listeners
	for i = 1, #path_array do
		pointer = pointer[path_array[i]]
		if listeners ~= nil then
			listeners = listeners[1][path_array[i]]
		end
	end
	-- Setting value:
	table.insert(pointer, value)
	-- Signaling listeners:
	local new_index = #pointer
	if listeners ~= nil then
		if listeners[4] ~= nil then -- "ArrayInsert" listeners
			for _, listener in ipairs(listeners[4]) do
				listener(new_index, value)
			end
		end
	end
	-- Raw listeners:
	for _, listener in ipairs(replica._raw_listeners) do
		listener("ArrayInsert", path_array, value, new_index)
	end
	return new_index
end

local function ReplicaArraySet(replica_id, path_array, index, value)
	local replica = Replicas[replica_id]
	-- Getting path pointer and listener table:
	local pointer = replica.Data
	local listeners = replica._table_listeners
	for i = 1, #path_array do
		pointer = pointer[path_array[i]]
		if listeners ~= nil then
			listeners = listeners[1][path_array[i]]
		end
	end
	-- Setting value:
	pointer[index] = value
	-- Signaling listeners:
	if listeners ~= nil then
		if listeners[5] ~= nil then -- "ArraySet" listeners
			for _, listener in ipairs(listeners[5]) do
				listener(index, value)
			end
		end
	end
	-- Raw listeners:
	for _, listener in ipairs(replica._raw_listeners) do
		listener("ArraySet", path_array, index, value)
	end
end

local function ReplicaArrayRemove(replica_id, path_array, index) --> removed_value
	local replica = Replicas[replica_id]
	-- Getting path pointer and listener table:
	local pointer = replica.Data
	local listeners = replica._table_listeners
	for i = 1, #path_array do
		pointer = pointer[path_array[i]]
		if listeners ~= nil then
			listeners = listeners[1][path_array[i]]
		end
	end
	-- Setting value:
	local old_value = table.remove(pointer, index)
	-- Signaling listeners:
	if listeners ~= nil then
		if listeners[6] ~= nil then -- "ArrayRemove" listeners
			for _, listener in ipairs(listeners[6]) do
				listener(index, old_value)
			end
		end
	end
	-- Raw listeners:
	for _, listener in ipairs(replica._raw_listeners) do
		listener("ArrayRemove", path_array, index, old_value)
	end
	return old_value
end
