وحدة:Wikidata2/ملعب: الفرق بين النسختين

من أرابيكا، الموسوعة الحرة
اذهب إلى التنقل اذهب إلى البحث
لا ملخص تعديل
 
لا ملخص تعديل
 
(1 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة)
(لا فرق)

النسخة الحالية 22:21، 30 أغسطس 2023

local p = {}
local Frame_args = {}
local Moduletext
local Modulecite
local Moduleflags
local InfoboxImage
local ModuleGlobes
local formatera
local weblink

local citetitle = "Module:Cite Q"
if nil ~= string.find(mw.getCurrentFrame():getTitle(), "ملعب", 1, true) then
	citetitle = "Module:Cite Q/ملعب"
end

local i18n = {
	["errors"] = {
		["property-param-not-provided"] = "وسيط property غير متوفر.",
		["entity-not-found"] = "الكيان غير موجود.",
		["unknown-claim-type"] = "نوع claim غير معروف.",
		["unknown-snak-type"] = "نوع snak غير معروف.",
		["unknown-datatype"] = "نوع data غير معروف.",
		["unknown-entity-type"] = "نوع entity غير معروف.",
		["unknown-value-module"] = "يجب عليك تعيين كل من  value-module و value-function.",
		["unknown-claim-module"] = "يجب عليك تعيين كل من claim-module و claim-function.",
		["unknown-property-module"] = "يجب عليك تعيين كل من property-module و property-function.",
		["property-module-not-found"] = "الوحدة المستخدمة في وسيط property-module غير موجودة.",
		["property-function-not-found"] = "الوظيفة المستخدمة في وسيط property-function غير موجودة.",
		["value-module-not-found"] = "الوحدة المستخدمة في وسيط value-module غير موجودة.",
		["value-function-not-found"] = "الوظيفة المستخدمة في وسيط value-function غير موجودة.",
		["claim-module-not-found"] = "الوحدة المستخدمة في وسيط claim-module غير موجودة.",
		["claim-function-not-found"] = "الوظيفة المستخدمة في وسيط claim-function غير موجودة."
	},
	["noarabiclabel"] = "تصنيف:صفحات_ويكي_بيانات_بحاجة_لتسمية_عربية",
	["warnDump"] = "[[Category:Called function 'Dump' from module Wikidata]]",
	["somevalue"] = "", --'"غير محدد"'
	["novalue"] = "", --قيمة مجهولة
	["cateref"] = "[[" .. "تصنيف:صفحات بها مراجع ويكي بيانات" .. "]]",
	["to translate"] = "صفحات تستعمل معطيات من ويكي بيانات بحاجة لترجمة",
	["trackingcat"] = "صفحات تستخدم خاصية $1",
	["see-wikidata-value"] = "الاطلاع ومراجعة البيانات على ويكي داتا",
	["see-wikidata"] = "راجع العنصر من ويكي بيانات المقابل",
	["see-another-project"] = "مقالة على $1",
	["see-another-language"] = "مقالة على أرابيكا $1"
}
local sortingproperties = {"P585", "P571", "P580", "P569", "P582", "P570"}
local sorting_methods = {
	["chronological"] = "chronological",
	["تصاعدي"] = "chronological",
	["asc"] = "chronological",
	["inverted"] = "inverted",
	["تنازلي"] = "inverted",
	["desc"] = "inverted"
}

local falsetitles = {
	"قالب:قيمة ويكي بيانات",
	"وحدة:Wikidata2"
}

local skiip_items = {
	["P106"] = {
		"Q42857", -- prophet
		"Q14886050", -- terrorist
		"Q2159907" -- criminal
	}
}

function isvalid(x)
	if x and x ~= "" then return x end
	return nil
end

function isntvalid(x)
	if not x or x == "" or x == nil then return true end
	return false
end

function No_Tracking_cat(options)
	if isvalid(options.formatting) == "raw" or isvalid(options.formatting) == "sitelink" then
		return true
	end
	local notracking = isvalid(options.nocate) or isvalid(options.notracking) or isvalid(Frame_args.notracking)
	local raw = isvalid(options.raw) or isvalid(Frame_args.raw) or isvalid(options.raw2) or isvalid(Frame_args.raw2)
	local nolink = isvalid(options.nolink) or isvalid(Frame_args.nolink)
	if notracking or raw or nolink then
		return true
	end
	local pagetitle = mw.title.getCurrentTitle().text
	for _, title in pairs(falsetitles) do
		if string.find(pagetitle, title, 1, true) then
			mw.log("notracking for title with: " .. title)
			return true
		end
	end
	return false
end

function addTrackingCategory(options)
	if No_Tracking_cat(options) then
		return ""
	end
	local cat = require("Module:Wikidata/تتبع").makecategory1
	local category = cat(options)
	local nbsp = " "
	if isvalid(options.nbsp) then
		nbsp = ""
	end
	if isvalid(category) then
		return nbsp .. category
	end
	return ""
end

function catewikidatainfo(options)
	--[[  function to add tracking category ]]
	if No_Tracking_cat(options) then
		return ""
	end
	local cat = ""
	local prop = options.property
	cat = cat .. " [[" .. "تصنيف:صفحات بها بيانات ويكي بيانات|" .. (prop or "wikidata") .. "]]"
	if isntvalid(options.nolink) then
		return cat
	else
		return ""
	end
end

function getqualifierbysortingproperty(claim, sortingproperty)
	for k, v in pairs(sortingproperty) do
		if claim and claim.qualifiers and claim.qualifiers[v] and claim.qualifiers[v][1].snaktype == "value" then
			local vali = claim.qualifiers[v][1].datavalue.value.time or claim.qualifiers[v][1].datavalue.value.amount
			if vali:sub(1, 1) == "+" then
				vali = vali:sub(2)
			end
			--mw.log(vali)
			return vali
		end
	end
	return nil
end

function get_sorting_properties(options)
	if type(options.sortingproperty) == "table" then
		return options.sortingproperty
	elseif type(options.sortingproperty) == "string" and options.sortingproperty ~= "" then
		return mw.text.split(options.sortingproperty, ",")
	else
		return sortingproperties
	end
end

function getDate(claim, options)
	local sortingproperty = get_sorting_properties(options)
	return getqualifierbysortingproperty(claim, sortingproperty)
end

function get_entityId(options)
	local id = isvalid(options.entityId) or isvalid(options.id) or isvalid(options.qid)
	if id then
		return id
	end
	if isvalid(options.page) then
		id = mw.wikibase.getEntityIdForTitle(options.page)
	else
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	return id or ""
end

function countSiteLinks(id)
	local numb = 0
	local entity = mw.wikibase.getEntityObject(id)
	if entity and entity.sitelinks then
		for i, v in pairs(entity.sitelinks) do
			numb = numb + 1
		end
	end
	return numb
end

function make_format_num(String)
	local line = String
	line = mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}formatnum: " .. String .. " }}")
	line = mw.ustring.gsub(line, "٫", ".")
	line = mw.ustring.gsub(line, "٬", ",")
	return line
end

function formatcharacters(label, options)
	local formatch = options.formatcharacters
	--if options.FormatfirstCharacter and options.num == 1 then
	--formatch = options.FormatfirstCharacter
	--end

	local String2 = mw.ustring.gsub(label, "–", "-")
	local march_y =
		mw.ustring.match(String2, "%d%d%d%d%-%d%d%d%d", 1) or mw.ustring.match(String2, "%d%d%-%d%d%d%d", 1) or
		mw.ustring.match(String2, "%d%d%d%d", 1) or
		mw.ustring.match(String2, "%d%d%d%d%-%d%d", 1) or
		mw.ustring.match(String2, "%d%d%d%d", 1)

	if isvalid(options.illwd2y) then
		return march_y or label
	end
	if isvalid(options.illwd2noy) and march_y then
		label = mw.ustring.gsub(label, march_y, "")
		return label
	end

	if isntvalid(formatch) then
		return label
	end

	local prepr = {
		["lcfirst"] = "{{lcfirst: " .. label .. " }}",
		["lc"] = "{{lc: " .. label .. " }}",
		["uc"] = "{{uc: " .. label .. " }}"
	}
	if prepr[formatch] then
		return mw.getCurrentFrame():preprocess(prepr[formatch])
	elseif formatch == "ucfirst" then
		return mw.language.getContentLanguage():ucfirst(label)
	elseif formatch == "formatnum" then
		return make_format_num(label)
	end
	return label
end

function descriptionIn(langcode, id) -- returns item description for a given language
	if isntvalid(langcode) then
		langcode = "ar"
	end
	langcode = mw.text.trim(langcode or "")
	id = mw.text.trim(id or "")
	if langcode == "ar" then
		local description, lange = mw.wikibase.getDescriptionWithLang(id)
		if lange == langcode then
			return description
		else
			return nil
		end
	else
		local entity = getEntityFromId(id)
		if entity and entity.descriptions then
			local description = entity.descriptions[langcode]
			if description and description.value then
				if description["language"] == langcode then
					return description.value
				end
			end
		end
	end
	return nil
end

function labelIn(langcode, id) -- returns item label for a given language
	if isntvalid(langcode) then
		langcode = "ar"
	end
	if type(id) ~= "string" then
		id = tostring(id)
	end
	langcode = mw.text.trim(langcode or "")
	id = mw.text.trim(id or "")
	local label = mw.wikibase.getLabelByLang(id, langcode) or nil
	return label
end

function get_snak_id(snak)
	if
		snak and snak.type and snak.type == "statement" and snak.mainsnak and snak.mainsnak.snaktype and
			snak.mainsnak.snaktype == "value" and
			snak.mainsnak.datavalue and
			snak.mainsnak.datavalue.type and
			snak.mainsnak.datavalue.type == "wikibase-entityid" and
			snak.mainsnak.datavalue.value and
			snak.mainsnak.datavalue.value.id
	 then
		ID = snak.mainsnak.datavalue.value.id
		return ID
	end
end

function comparedates(a, b) -- returns true if a is earlier than B or if a has a date but not b
	if a and b then
		return a > b
	elseif a then
		return true
	end
end

function getDateArb(claim, sorting_properties)
	local sortingproperty = sorting_properties
	if claim.mainsnak.snaktype == "value" then
		local item = claim.mainsnak.datavalue.value["numeric-id"]
		if claim.mainsnak.datavalue.value["entity-type"] == "item" then
			item = "Q" .. item
		elseif claim.mainsnak.datavalue.value["entity-type"] == "property" then
			item = "P" .. item
		end
		for k, prop in pairs(sortingproperty) do
			local date =
				formatStatements({property = prop, entityId = item, firstvalue = "t", noref = "t", modifytime = "q"})
			if isvalid(date) then
				--mw.log("item:".. item .. ", prop:".. prop .. ", date:".. date)
				return date
			end
		end
	end
end

function table_contains(table, element)
	for _, value in pairs(table) do
		if value == element then
			return true
		end
	end
	return false
end

function dontget(claims, options)
	--[[
	options.dontget
	options.dontgetproperty
	]]
	local claims2 = {}
	local dontget_values = mw.text.split(options.dontget, ",")

	for _, claim in pairs(claims) do
		local id = get_snak_id(claim)
		if id then
			local valid = true
			local t2 =
				formatStatements({property = (options.dontgetproperty or "P31"), entityId = id, noref = "t", raw = "t"})

			if t2 and #t2 > 0 then
				for _, state in pairs(t2) do
					if table_contains(dontget_values, state.item) then
						valid = false
						break
					end
				end
			end

			if valid then
				table.insert(claims2, claim)
			end
		end
	end

	return claims2
end

function getonly(claims, options)
	--[[
	-- options.getonly
	-- options.getonlyproperty
	]]
	local claims2 = {}
	local getonly_values = mw.text.split(options.getonly, ",")

	for _, claim in pairs(claims) do
		local id = get_snak_id(claim)
		if id then
			local t2 =
				formatStatements({property = (options.getonlyproperty or "P31"), entityId = id, noref = "t", raw = "t"})
			if t2 and #t2 > 0 then
				for _, state in pairs(t2) do
					if table_contains(getonly_values, state.item) then
						table.insert(claims2, claim)
						break
					end
				end
			end
		end
	end

	return claims2
end

function claimindex(claims, options)
	local claims2 = {}
	for j, index in pairs(mw.text.split(options.claimindex, ",")) do
		if tonumber(index) and #claims >= tonumber(index) then
			table.insert(claims2, claims[tonumber(index)])
		end
	end
	return claims2
end

function avoidvalue(claims, options)
	local avoidvalue = options.avoidvalue
	if type(avoidvalue) == "string" then
		avoidvalue = mw.text.split(avoidvalue, ",")
	elseif type(avoidvalue) ~= "table" then
		return claims
	end

	local claims4 = {}
	for i, j in pairs(claims) do
		local ID = get_snak_id(j)
		if ID and not table_contains(avoidvalue, ID) then
			table.insert(claims4, j)
		end
	end
	return claims4
end

function prefervalue(claims, options)
	local prefervalue = options.prefervalue
	if type(prefervalue) == "string" then
		prefervalue = mw.text.split(prefervalue, ",")
	elseif type(prefervalue) ~= "table" then
		return claims
	end

	local claims3 = {}
	for _, claim in pairs(claims) do
		local ID = get_snak_id(claim)
		if ID and table_contains(prefervalue, ID) then
			table.insert(claims3, claim)
		end
	end

	return claims3
end

function preferqualifier(claims, options)
	--[[
	-- options.preferqualifier
	-- options.preferqualifiervalue
	]]
	local claims2 = {}
	local preferq_values = mw.text.split(options.preferqualifiervalue or "", ",")

	for _, statement in pairs(claims) do
		if statement.qualifiers and statement.qualifiers[options.preferqualifier:upper()] then
			if isvalid(options.preferqualifiervalue) then
				for _, quall in pairs(statement.qualifiers[options.preferqualifier:upper()]) do
					if quall.snaktype == "value" and table_contains(preferq_values, quall.datavalue.value["id"]) then
						table.insert(claims2, statement)
						break
					end
				end
			else
				table.insert(claims2, statement)
			end
		end
	end

	return claims2
end

function avoidqualifier(claims, options)
	-- options.avoidqualifier
	-- options.avoidqualifiervalue
	if isntvalid(options.avoidqualifier) then
		return claims
	end

	local av = options.avoidqualifier:upper()
	local avoidqualifiervalue_values =
		type(options.avoidqualifiervalue) == "string" and mw.text.split(options.avoidqualifiervalue, ",") or
		options.avoidqualifiervalue
	local claims2 = {}

	for _, statement in pairs(claims) do
		if not statement.qualifiers or not statement.qualifiers[av] then
			table.insert(claims2, statement)
		elseif isvalid(options.avoidqualifiervalue) then
			local active = true
			for _, quall in pairs(statement.qualifiers[av]) do
				if
					quall.snaktype == "value" and quall.datavalue and quall.datavalue.value and
						quall.datavalue.value["id"] and
						table_contains(avoidqualifiervalue_values, quall.datavalue.value["id"])
				 then
					active = false
					break
				end
			end
			if active then
				table.insert(claims2, statement)
			end
		end
	end

	return claims2
end

function claims_limit(claims, limit)
	local newclaims = {}
	if type(limit) ~= "number" then
		limit = tonumber(limit)
	end
	if limit and type(limit) == "number" then
		if limit < 1 or #claims < limit then
			return claims
		end
		for i = 1, #claims do
			if i <= limit then
				newclaims[i] = claims[i]
			end
		end
		return newclaims
	end
	return claims
end

function claims_offset(claims, offset)
	local offsetclaims = {}
	if type(offset) ~= "number" then
		offset = tonumber(offset)
	end
	if offset and type(offset) == "number" then
		for i = offset + 1, #claims do
			offsetclaims[#offsetclaims + 1] = claims[i]
		end
		return offsetclaims
	end
	return claims
end

function sortbyarb(claims, sorting_properties, options)
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	--mw.log("sortbyarb: " .. sortingmethod)

	table.sort(
		claims,
		function(a, b)
			local timeA = getDateArb(a, sorting_properties)
			local timeB = getDateArb(b, sorting_properties)
			if sortingmethod == "inverted" or sorting_methods[sortingmethod] == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sort_langs(claims, options)
	local claims7 = {}
	local arabic_id = {["P407"] = 13955, ["P282"] = 8196} -- Q13955 = "العربية", Q8196 = "أبجدية عربية"

	for _, statement in pairs(claims) do
		for prop, id in pairs(arabic_id) do
			if statement.qualifiers and statement.qualifiers[prop] then
				for _, v in pairs(statement.qualifiers[prop]) do
					if v.snaktype == "value" and v.datavalue.value["numeric-id"] == id then
						table.insert(claims7, statement)
						break
					end
				end
			end
		end
	end

	if #claims7 > 0 then
		claims = claims7
	end

	return claims
end

function sortbyqualifier(claims, sorting_properties, options)
	if not sorting_properties or #sorting_properties == 0 then
		sorting_properties = get_sorting_properties(options)
	end
	
	local sort_by = sorting_methods[options.sortbytime] or options.sortbytime

	table.sort(
		claims,
		function(a, b)
			local timeA = getqualifierbysortingproperty(a, sorting_properties)
			local timeB = getqualifierbysortingproperty(b, sorting_properties)
			if sort_by == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sortbyqualifiernumber(claims, sorting_properties, options)
	if not sorting_properties or #sorting_properties == 0 then
		sorting_properties = get_sorting_properties(options)
	end

	local sort_by = sorting_methods[options.sortbynumber] or options.sortbynumber

	table.sort(
		claims,
		function(a, b)
			local timeA = getqualifierbysortingproperty(a, sorting_properties)
			local timeB = getqualifierbysortingproperty(b, sorting_properties)
			if sort_by == "inverted" then
				return comparedates(timeB, timeA)
			else
				return comparedates(timeA, timeB)
			end
		end
	)
	return claims
end

function sort_claims(claims, options)
	local sortingmethod = options.sortbyarbitrary or options.sortingmethod
	local sorting_properties = get_sorting_properties(options)

	if isvalid(options.sortbytime) and sorting_methods[options.sortbytime] then
		if #sorting_properties == 0 then
			sorting_properties = sortingproperties
		end
		claims = sortbyqualifier(claims, sorting_properties, options)
	elseif isvalid(options.sortbynumber) and sorting_methods[options.sortbynumber] then
		claims = sortbyqualifiernumber(claims, sorting_properties, options)
	elseif isvalid(sortingmethod) and sorting_methods[sortingmethod] then
		claims = sortbyarb(claims, sorting_properties, options)
	end
	return claims
end

function filter_claims(claims, options)
	local claims = claims

	if isntvalid(options.langpref) then
		claims = sort_langs(claims, options)
	end

	claims = sort_claims(claims, options)

	local offset = options.offset
	if isvalid(offset) then
		claims = claims_offset(claims, offset)
	end

	local limit = options.limit
	if isvalid(limit) then
		claims = claims_limit(claims, limit)
	end

	if isvalid(options.avoidqualifier) then -- to avoid value with a given qualifier
		claims = avoidqualifier(claims, options)
	end

	if isvalid(options.preferqualifier) then
		claims = preferqualifier(claims, options)
	end

	-- options.avoidvalue
	if isvalid(options.avoidvalue) then
		claims = avoidvalue(claims, options)
	end

	-- options.prefervalue
	if isvalid(options.prefervalue) then
		claims = prefervalue(claims, options)
	end

	-- options.getonly
	if isvalid(options.getonly) then
		claims = getonly(claims, options)
	end

	-- options.dontget
	if isvalid(options.dontget) then
		claims = dontget(claims, options)
	end

	local firstvalue = options.enbarten or options.firstvalue
	local first = isvalid(tonumber(firstvalue))
	if isvalid(first) and #claims > 1 then
		if #claims > 0 then
			first = tonumber(first) or 1
			if first > 0 and first <= #claims then
				claims = {claims[first]}
			else
				claims = {claims[1]}
			end
		end
	elseif isvalid(firstvalue) and #claims > 0 then
		claims = {claims[1]}
	end

	local numval = options.numval
	if numval and type(numval) ~= "number" then
		numval = tonumber(numval)
	end
	if numval and type(numval) == "number" and #claims > 1 and #claims > numval then
		local claimsnumval = {}
		local ic = 1
		while (numval >= ic) and (#claims >= ic) do
			table.insert(claimsnumval, claims[ic])
			ic = ic + 1
		end
		claims = claimsnumval
	end

	return claims
end

function getEntityFromId(id)
	return isvalid(id) and mw.wikibase.getEntityObject(id) or mw.wikibase.getEntityObject()
end

function formatError(key)
	return i18n.errors[key]
end

function formatOneStatement(statement, ref, options)
	local value = nil
	local stat = formatStatement(statement, options)
	if not stat then
		return {v = value, raw = stat}
	end

	local s = stat.value
	if isntvalid(s) then
		return {v = value, raw = stat}
	end

	if not stat.qualifiers then
		stat.qualifiers = {}
	end

	local P585 = stat.P585 or ""
	local tf = stat.tifr
	local awardqual = stat.foto
	local ro = stat.ro
	local qp1a = stat.qp1a
	local onlyqualifier = stat.onlyqualifier
	local qp1 = stat.qp1
	local qp2 = stat.qp2
	local qp3 = stat.qp3
	local qp4 = stat.qp4
	local qp5 = stat.qp5
	local reff = stat.reff

	if reff and isvalid(options.reff) then
		s = s .. reff
	end
	if isvalid(options.template) then
		s =
			mw.getCurrentFrame():expandTemplate {
			title = options.template,
			args = {
				stat.QQ1,
				s,
				stat.QQ2,
				stat.QQ3,
				stat.QQ4,
				stat.QQ5,
				stat.QQ6,
				stat.QQ7,
				stat.QQ8,
				stat.QQ9,
				stat.QQ10,
				entityId = options.entityId,
				v1 = options.v1,
				id = stat.ID
			}
		}
	end
	if isvalid(options.football) then
		s =
			mw.getCurrentFrame():expandTemplate {
			title = "صندوق معلومات سيرة كرة قدم/سطر فريق",
			args = {
				stat.qualifiers.P580 or "",
				stat.qualifiers.P582 or "",
				s,
				stat.amatch,
				stat.goal
			}
		}
	end

	if isvalid(options.office) then
		s =
			mw.getCurrentFrame():expandTemplate {
			title = "معلومات صاحب منصب/منصب ويكي بيانات/نواة",
			args = {
				office = s,
				termstart = stat.qualifiers.P580 or "",
				termend = stat.qualifiers.P582 or "",
				constituency = stat.qualifiers.P768 or "",
				predecessor = stat.qualifiers.P1365 or "",
				successor = stat.qualifiers.P1366 or "",
				series = stat.qualifiers.P1545 or "",
				of = stat.qualifiers.P642 or "",
				electedin = stat.qualifiers.P2715 or "",
				jurisdiction = stat.qualifiers.P1001 or "",
				employer = stat.qualifiers.P108 or "",
				entityId = options.entityId
			}
		}
	end

	local function qoo(Prefix, qualpref, p, Suffix)
		if isvalid(p) then
			local stri = (Prefix or " (") .. (qualpref or "") .. p .. (Suffix or ")")
			if isvalid(options.nosmall) then
				return stri
			else
				return mw.text.tag("small", {}, stri)
			end
		end
	end
			  
	local QPrefix = isvalid(options.qualifierprefix)
	local QSuffix = isvalid(options.qualifiersuffix)

	if isvalid(qp1) and isvalid(options.qual1) and isvalid(qp1a) and isvalid(options.qual1a) then
		s = s .. 
			qoo(QPrefix, options.qual1pref, qp1, QSuffix) .. qoo(QPrefix, options.qp1apref, qp1a, QSuffix)

	elseif isvalid(qp1) and isvalid(options.qual1) then
		s = s .. qoo(QPrefix, options.qual1pref, qp1, QSuffix)

	elseif isvalid(qp1a) and isvalid(options.qual1a) then
		s = s .. qoo(QPrefix, options.qp1apref, qp1a, QSuffix)
	end

	if isvalid(qp2) and isvalid(options.qual2) then
		s = s .. qoo(QPrefix, options.qual2pref, qp2, QSuffix)
	end

	if isvalid(qp3) and isvalid(options.qual3) then
		s = s .. qoo(QPrefix, options.qual3pref, qp3, QSuffix)
	end
	if isvalid(qp4) and isvalid(options.qual4) then
		s = s .. qoo(QPrefix, options.qual4pref, qp4, QSuffix)
	end
	if isvalid(qp5) and isvalid(options.qual5) then
		s = s .. qoo(QPrefix, options.qual5pref, qp5, QSuffix)
	end

	if isvalid(options.justthisqual) then
		if onlyqualifier then
			s = onlyqualifier
		else
			s = nil -- We need only the qualifier
		end
	end
	if isvalid(ro) and isvalid(options.withro) then
		s = s .. qoo(QPrefix, "", ro, QSuffix)
	end

	if isvalid(P585) and isvalid(options.withdate) then
			if options.withdate == "y" then
				s = s .. qoo(QPrefix, "سنة ", P585, QSuffix)
			elseif options.withdate == "before" then
				s = "*" .. P585 .. ":" .. s .. "\n"
			else
				s = s .. qoo(QPrefix, "", P585, QSuffix)
			end
		end

	if awardqual and isvalid(options.awardqua) then
		s = s .. qoo(QPrefix, "", awardqual, QSuffix)
	end

	local bothdates = options.withintervall or options.bothdates
	if tf and isvalid(bothdates) then
		if bothdates == "line" then
			s = s .. mw.text.tag("br") .. qoo(QPrefix, "", tf, QSuffix)
		elseif bothdates == "before" then
			s = qoo(QPrefix, "", tf, QSuffix) .. s
		else
			s = s .. qoo(QPrefix, "", tf, QSuffix)
		end
	end

	if type(ref) == "table" or (isvalid(options.noref)) or (isvalid(options.justthisqual)) then
		value = s
	else
		local t = formatReferences(statement, options)
		stat.ref = t
		if isvalid(options.justref) then
			value = t
		elseif isvalid(options.onlyvaluewithref) then
			if isvalid(t) then
				value = s .. t
			end
		else
			value = s .. t
		end
	end
	return {v = value, raw = stat}
end

function formatStatements(options, LuaClaims)
	local valuetable = {} -- formattedStatements
	local claims = {}

	if isntvalid(options.property) and isvalid(options.pid) then
		options.property = options.pid
	end
	
	if isntvalid(options.property) then
		return formatError("property-param-not-provided")
	end
	local option1 = options.option1
	if option1 and options.option1value then
		options[option1] = options.option1value
		options['"' .. option1 .. '"'] = options.option1value
	--mw.log( "option1: " .. option1 .. "value: " .. options.option1value  )
	end
	if type(LuaClaims) == "table" then
		claims = LuaClaims[options.property] or {}
		mw.log("module:wikidata2: claims = LuaClaims[options.property]")
	else
		--Get entity
		local entity = nil
		if options.entity and type(options.entity) == "table" then
			entity = options.entity
		else
			local id = get_entityId(options)
			if isvalid(id) then
				local check = mw.ustring.match(id, "Q%d+") or mw.ustring.match(id, "P%d+")
				if check == nil then
					mw.addWarning(id .. " لا يمثل معرف ويكي بيانات صحيح")
					return ""
				else
					options.entityId = id
					options.qid = id
				end
			end
			entity = getEntityFromId(id)
		end
		--local property = mw.wikibase.resolvePropertyId( options.property:upper() )
		local property = options.property:upper()

		if not entity then
			return ""
		end --TODO error?
		if not entity.claims or not entity.claims[property] then
			if isvalid(options.otherproperty) then
				options.property = options.otherproperty
				property = options.otherproperty:upper()
			end
		end
		if property == nil then
			return ""
		end
		if not entity.claims or not entity.claims[property] then
			return "" --TODO error?
		end

		--Format statement and concat them cleanly
		if options.rank == "best" or isntvalid(options.rank) then
			--claims = entity:getAllStatements( property )
			claims = entity:getBestStatements(property)
		elseif options.rank == "valid" then
			for i, statement in pairs(entity.claims[property]) do
				if statement.rank == "preferred" or statement.rank == "normal" then
					table.insert(claims, statement)
				end
			end
		elseif options.rank == "all" then
			for i, statement in pairs(entity.claims[property]) do
				table.insert(claims, statement)
			end
		else
			for i, statement in pairs(entity.claims[property]) do
				if statement.rank == options.rank then
					table.insert(claims, statement)
				end
			end
		end
	end
	claims = filter_claims(claims, options)
	local statementsraw = {}
	local All_claims = claims
	if claims then
		if options["property-module"] or options["property-function"] then
			if not options["property-module"] or not options["property-function"] then
				return formatError("unknown-property-module")
			end
			local formatter = require("Module:" .. options["property-module"])
			if not formatter then
				return formatError("property-module-not-found")
			end
			local fun = formatter[options["property-function"]]
			if not fun then
				return formatError("property-function-not-found")
			end

			mw.log("work with property-module: " .. options["property-module"] .. "|" .. options["property-function"])
			return fun(claims, options)
		else
			for i, statement in pairs(claims) do
				options.num = i
				local va = formatOneStatement(statement, LuaClaims, options)
				if va.v then
					table.insert(valuetable, va.v)
				end
				table.insert(statementsraw, va.raw)
			end
		end
	end

	if isvalid(options.raw) then
		if isvalid(options.rawtolua) then
			return mw.getCurrentFrame():extensionTag("source", mw.dumpObject(statementsraw), {lang = "lua"})
		end
		return statementsraw
	end

	local priff = ""
	local Separator = options.separator -- or ""
	local Conjunction = options.conjunction -- or ""

	if Separator == "br" or Conjunction == "br" then
		Separator = mw.text.tag("br")
	end
	if Separator == "*" then
		priff = "\n*"
		Separator = "\n*"
	end
	if Separator == "#" then
		priff = "\n#"
		Separator = "\n#"
	end
	if isvalid(options.justref) then
		priff = ""
		Separator = ""
	end

	local tot = mw.text.listToText(valuetable, Separator, Separator)
	if #valuetable > 1 then
		tot = priff .. tot
	end

	if isntvalid(tot) then
		tot = nil
	end
	if isvalid(options.returnnumberofvalues) or options.returnnumberofvalues == true then
		return tot, #valuetable
	end
	if isvalid(options.numberofclaims) then
		return #All_claims
	end
	return tot
end

function p.formatAndCat(args)
	if args == nil then
		return nil
	end

	Frame_args = args
	args.linkback = args.linkback or true
	args.addcat = true
	if isvalid(args.value) and args.value == "-" then
		return nil
	end
	if isvalid(args.value) then
		local val = args.value .. addTrackingCategory(args)
		val = p.addLinkBack(val, args.entity, args.property)
		return val
	end
	return p.formatStatementsFromLua(args)
end

function formatReferences(statement, options)
	local ic = 1
	local reference = {}
	local numberofref = tonumber(options.numberofreferences) or 7
	local qid = get_entityId(options)
	local statementreferences = statement.references

	if statementreferences then
		if Modulecite == nil then
			Modulecite = require(citetitle)
		end
		for i, ref in ipairs(statementreferences) do
			if ref.snaks and numberofref >= ic then
				local s = Modulecite._cite_wikidata(ref, qid)
				if isvalid(s) then
					ic = ic + 1
					table.insert(reference, s)
				end
			end
		end
	end

	local final = table.concat(reference)
	if isvalid(final) then
		final = final .. i18n.cateref
	end
	return final or ""
end

function formatqualifiers(statement, s, options)
	s.qualifiers = {}
	local function qua(p, firstvalue, modifytime)
		local vvv
		if isvalid(p) then
			vvv =
				formatStatements(
				{
					property = p,
					enlabelcate = "t",
					firstvalue = (firstvalue or ""),
					modifytime = (modifytime or "longdate"),
					noref = "t"
				},
				statement.qualifiers
			) or ""
			s.qualifiers[p] = vvv
			return vvv
		end
	end

	if isvalid(options.template) then
		s.ID = statement.mainsnak.datavalue.value.id
		s.QQ1 = qua(options.Q1)
		s.QQ2 = qua(options.Q2)
		s.QQ3 = qua(options.Q3)
		s.QQ4 = qua(options.Q4)
		s.QQ5 = qua(options.Q5)
		s.QQ6 = qua(options.Q6)
		s.QQ7 = qua(options.Q7)
		s.QQ8 = qua(options.Q8)
		s.QQ9 = qua(options.Q10)
		s.QQ10 = qua(options.Q10)
	end
	if isvalid(options.football) then
		if statement.qualifiers.P1350 or statement.qualifiers.P1351 then
			s.amatch = qua("P1350", "true")
			s.goal = qua("P1351", "true")
		end
	end
	if (isvalid(options.football)) or (isvalid(options.office)) then
		s.start1 = qua("P580", "true")

		s.finish1 = qua("P582", "true")
	end
	if isvalid(options.office) then
		if
			statement.qualifiers.P580 or statement.qualifiers.P582 or statement.qualifiers.P1365 or
				statement.qualifiers.P1366
		 then
			s.before1 = qua("P1365", "true")
			s.after1 = qua("P1366", "true")
			s.constituency1 = qua("P768")
			s.series1 = qua("P1545")
			s.electedin1 = qua("P2715", "")
			s.pp1001 = qua("P1001")
			s.pp108 = qua("P108")
			s.pp642 = qua("P642")
		end
	end

	if isvalid(options.withdate) then
		--if statement.qualifiers.P585 then
		s.P585 = qua("P585", "true", options.modifyqualifiertime)
	end
	local qwe = options.qwer
	if statement.qualifiers.qwe then
		s.ro = qua(qwe, "true")
	end
	local bothdates_option = options.withintervall or options.bothdates
	if isvalid(bothdates_option) then
		if statement.qualifiers.P580 or statement.qualifiers.P582 then
			local f = qua("P580", "true", options.modifyqualifiertime)
			local t = qua("P582", "true", options.modifyqualifiertime)
			s.tifr = f .. "–" .. t
		end
	end
	if isvalid(options.awardqua) then
		if statement.qualifiers.P585 or statement.qualifiers.P1346 then
			local fo = qua("P585", "true", options.modifyqualifiertime)
			local to = qua("P1346", "true")
			s.foto = fo .. " " .. mw.text.tag("span", {}, " " .. to .. "")
		end
	end
	local function quaaal(opti, options)
		if isvalid(opti) and statement.qualifiers[opti] then
			local kkk =
				formatStatements(
				{
					property = opti,
					noref = "t",
					separator = options.qualifierseparator,
					conjunction = options.qualifierconjunction,
					size = options.size,
					image = options.image,
					modifytime = options.modifyqualifiertime,
					enlabelcate = "t",
					langpref = options.langpref,
					showlang = options.showlang
				},
				statement.qualifiers
			) or ""

			s.qualifiers[opti] = kkk
			return kkk
		end
	end

	if isvalid(options.justthisqual) and statement.qualifiers[options.justthisqual] then
		s.onlyqualifier = quaaal(options.justthisqual, options)
	end
	if isvalid(options.qual1) and statement.qualifiers[options.qual1] then
		s.qp1 = quaaal(options.qual1, options)
	end
	if isvalid(options.qual1a) and statement.qualifiers[options.qual1a] then
		s.qp1a = quaaal(options.qual1a, options)
	end
	if isvalid(options.qual2) and statement.qualifiers[options.qual2] then
		s.qp2 = quaaal(options.qual2, options)
	end
	if isvalid(options.qual3) and statement.qualifiers[options.qual3] then
		s.qp3 = quaaal(options.qual3, options)
	end
	if isvalid(options.qual4) and statement.qualifiers[options.qual4] then
		s.qp4 = quaaal(options.qual4, options)
	end
	if isvalid(options.qual5) and statement.qualifiers[options.qual5] then
		s.qp5 = quaaal(options.qual5, options)
	end
end

function formatSnak(snak, options)
	if snak.snaktype == "somevalue" then
		local somevalue = options.somevalue or i18n["somevalue"]
		return {value = somevalue}
	elseif snak.snaktype == "novalue" then
		local novalue = options.novalue or i18n["novalue"]
		return {value = novalue}
	elseif snak.snaktype == "value" then
		local s = formatDatavalue(snak.datavalue, snak.datatype, options)
		if s and s.value and isvalid(s.value) then
			s.value = (options.prefix or "") .. s.value .. (options.suffix or "")
		end
		return s
	else
		return {value = formatError("unknown-snak-type")}
	end
end

function formatStatement(statement, options)
	if options["claim-module"] or options["claim-function"] then
		if not options["claim-module"] or not options["claim-function"] then
			return {value = formatError("unknown-claim-module")}
		end
		local formatter = require("Module:" .. options["claim-module"])
		if formatter == nil then
			return {value = formatError("claim-module-not-found")}
		end
		local fun = formatter[options["claim-function"]]
		if fun == nil then
			return {value = formatError("claim-function-not-found")}
		end
		return {value = fun(statement, options)}
	elseif statement.type == "statement" then
		local s = formatSnak(statement.mainsnak, options)
		if isvalid(s) then
			s.qualifiers = {}
			if statement.qualifiers then
				local qualu = formatqualifiers(statement, s, options)
			--if isvalid(qualu) then table.insert(qualu) end
			end
			if statement.references then
				if isvalid(options.reff) then
					s.reff = formatReferences(statement, options)
				end
			end
		end
		return s
	elseif not statement.type then
		return formatSnak(statement, options)
	end
	return {value = formatError("unknown-claim-type")}
end



function get_property1(options, item)
	--[[ function to get countries flags without reload large countries items ]]
	local flagprop = {"p27", "p1532", "p17", "p495", "p1376"}
	local work_flag = false
	if string.lower(options.property1) == "p41" then
		for k, l in pairs(flagprop) do
			if string.lower(options.property) == l then
				work_flag = true
			end
		end
	end
	local caca = ""
	local size = options.size or ""
	if isntvalid(size) then
		size = "20"
	end
	if work_flag then
		if Moduleflags == nil then
			Moduleflags = require("Module:Wikidata2/Flags")
		end
		local flag = Moduleflags[item]
		if isntvalid(flag) then
			flag =
				formatStatements(
				{
					property = options.property1,
					otherproperty = options.otherproperty1,
					entityId = item,
					rank = options.property1rank,
					pattern = options.property1pattern,
					formatting = options.property1formatting,
					noref = "t",
					firstvalue = "t"
				}
			)
		--mw.log("get flag2 :" .. flag .. ", for item ".. item )
		end
		if isvalid(flag) then -- return real image
			if isvalid(options.image) then -- return real image
				caca = "[[file:" .. flag .. "|" .. size .. "px|" .. "border" .. "]]"
			--caca = Infobox_Image( {image=flag, size=size, maxsize = "280x330px", center=options.center} )
			--mw.log("get flag :" .. flag .. ", for item ".. item )
			end
		end
	end
	if isntvalid(caca) then
		caca =
			formatStatements(
			{
				property = options.property1,
				otherproperty = options.otherproperty1,
				entityId = item,
				rank = options.property1rank,
				pattern = options.property1pattern,
				formatting = options.property1formatting,
				size = options.size,
				image = options.image,
				noref = "t",
				firstvalue = "t"
			}
		)
	end
	return caca
end

function formatwikibaseitem(datavalue, datatype, options)
	--[[  datatype	wikibase-item	]]
	local value
	local itemqid = datavalue.value.id
	local Skipped = skiip_items[options.property] or {}
	for k, v in pairs(Skipped) do
		if datavalue.value.id == v then
			return {value = "", item = ""}
		end
	end
	if isvalid(options.formatting) then
		if options.formatting == "raw" then
			return {value = itemqid, item = itemqid}
		elseif options.formatting == "rawtotemplate" and isvalid(options.rawtotemplate) then
			local args = {q = itemqid, no1 = options.no1 or "", no2 = options.no2 or ""}
			value = mw.getCurrentFrame():expandTemplate {title = options.rawtotemplate, args = args} .. "\n"
			return {value = value, item = itemqid}
		elseif options.formatting == "fu" then
			value =
				mw.getCurrentFrame():expandTemplate {
				title = "Cycling race/stageclassification2",
				args = {itemqid, type = "1"}
			}
			return {value = value, item = itemqid}
		elseif options.formatting == "sitelink" then
			value = formatsitelink(datavalue.value.id, options)
			return {value = value, item = itemqid}
		else
			value = formatcharacters(datavalue.value, options)
			if isvalid(options.pattern) then
				value = formatFromPattern(value, options)
			end
			return {value = value, item = itemqid}
		end
	end

	local itemValue = formatEntityId(itemqid, options).value
	if isvalid(itemValue) then
		if isvalid(options.property1) and options.property1:upper():sub(1, 1) == "P" then
			local prop1value = get_property1(options, itemqid)
			if isvalid(prop1value) then
				prop1value = (options.property1pref or "") .. "" .. prop1value .. "" .. (options.property1suff or "")
				value = prop1value .. " " .. itemValue
				if isvalid(options.property1after) then
					value = itemValue .. prop1value
				end
			else
				value = itemValue
			end
			return {value = value, item = itemqid}
		elseif isvalid(options.propertyimage) then
			local p_f = options.propertyimageformatting or options.formattingpropertyimage
			local vas =
				formatStatements(
				{
					property = options.propertyimage,
					formatting = p_f,
					entityId = itemqid,
					rank = options.rank,
					pattern = options.pattern,
					size = options.size,
					image = options.image,
					noref = "t",
					avoidvalue = options.avoidvaluepropertyimage,
					firstvalue = "t",
					nolink = options.nolink
				}
			)
			if isvalid(vas) then
				return {value = vas}
			end
		elseif isvalid(options.property2) then
			local caca =
				formatStatements(
				{
					property = options.property2,
					entityId = itemqid,
					noref = options.noref,
					rank = options.rank,
					pattern = options.property2pattern,
					size = options.size,
					image = options.image,
					propertyimage = options.property3,
					firstvalue = "t"
				}
			)
			if isvalid(caca) then
				return {value = caca .. " " .. itemValue}
			end
		end
	end
	return {value = itemValue, item = itemqid}
end

function formatwikibaseproperty(datavalue, datatype, options)
	--[[  datatype	wikibase-property	]]
	local tid = ""
	if isvalid(options.formatting) then
		if options.formatting == "raw" then
			tid = datavalue.value.id
		end
	else
		tid = formatEntityId(datavalue.value.id, options).value
	end
	return {value = tid}
end

function formattabulardata(datavalue, datatype, options)
	--[[  tabular-data ]]
	local data = "[[commons:" .. datavalue.value .. "|" .. datavalue.value .. "]]"
	return {value = data}
end

function formatgeoshape(datavalue, datatype, options)
	--[[  geo-shape	 ]]
	local shape = "[[commons:" .. datavalue.value .. "|" .. datavalue.value .. "]]"
	return {value = shape}
end

function formatcommonsMedia(datavalue, datatype, options)
	local tid
	--[[ commonsMedia ]]
	local size = options.size or ""
	if isvalid(options.image) then -- return real image
		--tid = "[[file:" .. datavalue.value  .. "|".. (options.size or "20").."px|border]]"
		--if isvalid(options.center) then
		--tid = "[[file:" .. datavalue.value  .. "|".. (options.size or "20").."px|border|center]]"
		--end
		--tid = "[[file:" .. datavalue.value  .. "|".. (options.size or "60").."px|".."border".."]]"
		local params = {image = datavalue.value, maxsize = "280x330px", center = (options.center or "")}
		if isvalid(options.size) then
			params.size = size
		end
		if InfoboxImage == nil then
			InfoboxImage = require("Module:InfoboxImage")
		end
		tid = InfoboxImage.Infobox_Image(params)
	else
		tid = formatcharacters(datavalue.value, options)
	end
	return {value = tid}
end

function formatmath(datavalue, datatype, options)
	--[[datatype math ]]
	--return	{value=mw.text.tag("math", {}, "".. datavalue.value.."") } -- that doesn't work well
	local result = mw.getCurrentFrame():callParserFunction("#tag:math", datavalue.value)
	return {value = result}
end

function formatstring(datavalue, datatype, options)
	--[[  datatype string ]]
	local par = options.pattern
	local result = formatcharacters(datavalue.value, options)
	local tid = result

	if isvalid(options.stringpattern) then
		tid = mw.ustring.gsub(options.stringpattern, "$1", datavalue.value)
	elseif isvalid(par) then
		if par ~= "autourl" and par ~= "autourl2" and par ~= "autourl3" and par ~= "autourl4" then
			tid = formatFromPattern(result, options)
		end
	end
	return {value = tid}
end

function formatexternalid(datavalue, datatype, options)
	local result = formatcharacters(datavalue.value, options)
	if isntvalid(options.pattern) then
		return {value = result} --just return value
	end
	local patter =
		formatStatements({property = "P1630", entityId = options.property, firstvalue = "t", noref = "t", rank = "all"}) -- get formatter URL

	local par = options.pattern
	local tid = result

	if isvalid(patter) then -- if P1630 are there
		local pp = formatFromPattern(datavalue.value, {pattern = patter})
		local plabel = mw.wikibase.label(options.property) or pp
		local ppp = mw.ustring.gsub(pp, " ", "_")

		local results = {
			["autourl"] = ppp, -- like http://example.com/$1.html
			["autourl2"] = "[" .. ppp .. " " .. datavalue.value .. "]", -- like [http://example.com/$1.html $1]
			["autourl3"] = "[" .. ppp .. " " .. ppp .. "]", -- like [http://example.com/$1.html http://example.com/$1.html]
			["autourl4"] = "[" .. ppp .. " " .. plabel .. "]"
		}
		if results[par] then
			tid = results[par]
		else
			tid = formatFromPattern(result, options)
		end
	elseif isvalid(par) then
		if par ~= "autourl" and par ~= "autourl2" and par ~= "autourl3" and par ~= "autourl4" then
			tid = formatFromPattern(result, options)
		end
	end
	return {value = tid}
end

function formattime(datavalue, datatype, options)
	--[[  datatype	time  ]]
	local ModuleTime = require "Module:wikidata2/time"
	local timen = datavalue.value
	local tid = ModuleTime.getdate(timen, options)
	-- local tid = mw.getCurrentFrame():preprocess(mall)
	if isvalid(options.modifytime) then
		if options.modifytime == "q" then
			local mall = datavalue.value.time
			tid = mw.getCurrentFrame():preprocess(mall)
		elseif options.modifytime == "precision" then
			local mall = datavalue.value.precision
			tid = mw.getCurrentFrame():preprocess(mall)
		end
	end
	return {value = tid}
end

function formatcoordinate(datavalue, datatype, options)
	--[[  datatype	globe-coordinate  ]]
	--local GlobeCoordinate = require "Module:GlobeCoordinate"
	--return {value=GlobeCoordinate.newFromWikidataValue( datavalue.value ):toHtml()}
	if ModuleGlobes == nil then
		ModuleGlobes = require("Module:Wikidata2/Globes")
	end
	local coord = datavalue.value
	local globe = datavalue.value.globe
	local globe2 = ModuleGlobes[globe] or ""
	local results = {
		["latitude"] = coord.latitude,
		["longitude"] = coord.longitude,
		["dimension"] = coord.dimension,
		["precision"] = coord.precision,
		["globe"] = globe:match("Q%d+"),
		["globe2"] = globe2
	}

	local pro = options.formatting and results[options.formatting]
	if pro == nil then
		pro =
			mw.getCurrentFrame():preprocess(
			"{{ {{{|safesubst:}}}#invoke:Coordinates|coord" ..
			"|" .. coord.latitude ..
			"|" .. coord.longitude ..
			"|display=inline" ..
			"|globe:" .. globe2 .. "_type:landmark" ..
			"|format=" .. (options.formatcoord or "") .. "}}"
		) .. catewikidatainfo(options)
	end

	return {value = pro}
end

function formatquantity(datavalue, datatype, options)
	--[[  datatype quantity	 ]]
	local amount, unit = datavalue.value.amount, datavalue.value.unit
	amount = mw.ustring.gsub(amount, "+", "")
	if unit then
		unit = unit:match("Q%d+")
	end
	if formatera == nil then
		formatera = require("Module:Wikidata2/Math")
	end
	local number = formatera.newFromWikidataValue(datavalue.value)
	local unitraw = unit
	if unit then
		-- يتحقق اذا كان هناك اي اختصار لوحدة القياس
		--if lab and ( isntvalid(options.nounitshort) ) then
		if isvalid(options.unitshort) then
			local lab =
				options.label or formatStatements({property = "P498", entityId = unit, firstvalue = "t", noref = "t"}) or
				formatStatements(
					{property = "P5061", entityId = unit, firstvalue = "t", langpref = options.langpref, noref = "t"}
				) or
				""
			local s =
				formatEntityId(unit, {label = lab, enlabelcate = "t", nolink = (options.nounitlink or options.nolink)})
			unit = s.value
		else
			local s = formatEntityId(unit, {nolink = options.nounitlink, enlabelcate = "t"})
			unit = s.value
		end
	end
	if options.formatcharacters and options.formatcharacters == "formatnum" then
		amount = make_format_num(amount)
	end
	local Value = amount .. " " .. (unit or "")
	if isvalid(options.nounit) then
		Value = amount
	end
	return {value = Value, amount = amount, unit = unit, unitraw = unitraw}
end

function formaturl(datavalue, datatype, options)
	--[[  datatype	url	 ]]
	local label = options.label
	if isvalid(options.urllabel) then
		label = options.urllabel
	end
	local va = mw.ustring.gsub(datavalue.value, " ", "_")
	if label == nil and options.property == "P856" then
		label = "الموقع الرسمي"
	end
	if isvalid(options.displayformat) == "weblink" then
		if weblink == nil then
			weblink = require("Module:Weblink")
		end
		return {value = weblink.makelink(va)}
	end
	if isvalid(options.formatting) == "raw" then
		return {value = va}
	end
	local pro = va
	if isvalid(label) then
		pro = "[" .. va .. " " .. label .. "]"
	end
	return {value = pro}
end

function formatmonolingualtext(datavalue, datatype, options) -- showlang
	local text = datavalue.value.text
	if isvalid(options.textformat) == "text" then
		return {value = text}
	end
	if Moduletext == nil then
		Moduletext = require "Module:wikidata2/monolingualtext"
	end
	local tid = Moduletext._main(datavalue, datatype, options)
	return {value = tid}
end

function formatDatavalue(datavalue, datatype, options)
	--Use the customize handler if provided
	if options["value-module"] or options["value-function"] then
		if not options["value-module"] or not options["value-function"] then
			return {value = formatError("unknown-value-module")}
		end
		local formatter = require("Module:" .. options["value-module"])
		if not formatter then
			return {value = formatError("value-module-not-found")}
		end
		local fun = formatter[options["value-function"]]
		if not fun then
			return {value = formatError("value-function-not-found")}
		end
		return {value = fun(datavalue, datatype, options)}
	end

	--Default dataformatters
	local dataformatters = {
		["wikibase-item"] = formatwikibaseitem,
		["wikibase-property"] = formatwikibaseproperty,
		["commonsMedia"] = formatcommonsMedia,
		["math"] = formatmath,
		["time"] = formattime,
		["external-id"] = formatexternalid,
		["string"] = formatstring,
		["globe-coordinate"] = formatcoordinate,
		["quantity"] = formatquantity,
		["url"] = formaturl,
		["monolingualtext"] = formatmonolingualtext,
		["geo-shape"] = formatgeoshape,
		["tabular-data"] = formattabulardata
	}

	local dataformatter = dataformatters[datatype]
	if not dataformatter then
		return {value = formatError("unknown-data-type")}
	end
	return dataformatter(datavalue, datatype, options)
end

function Labelfunction(qid, arlabel, options) -- label with no arwiki sitelink
	local value
	local cat = ""
	local use_en_label = isvalid(options.enlabelcate) or isvalid(options.use_en_labels)
	local Args = {fromlua = "t", ["المعرف"] = qid, nocat = "t"}
	if isvalid(options.illwd2noy) then
		Args.noy = "t"
	end
	if isvalid(options.illwd2y) then
		Args.y = "t"
	end

	if isvalid(arlabel) then
		value = arlabel
		if isvalid(options.illwd2) then
			Args.label = arlabel
			value = mw.getCurrentFrame():expandTemplate {title = "Ill-WD2", args = Args}
		end
	elseif isntvalid(options.justarabic) then
		-- else
		--cat = " [[".. i18n.noarabiclabel .."|".. qid .."]]"
		local en_label = mw.wikibase.label(qid) or ""
		if isvalid(options.illwd2noarlabel) then
			if isvalid(en_label) then
				Args.enlabel = en_label
			end
			value = mw.getCurrentFrame():expandTemplate {title = "Ill-WD2", args = Args}
		elseif use_en_label and isvalid(en_label) then
			value = en_label
		end
	end
	return {value = value or "", cat = cat}
end

function formatEntityId(qid, options)
	local labeloption = options.label
	local label = ""
	local value
	local arlabel = labelIn("ar", qid) or "" -- The arabic label
	local link = mw.wikibase.sitelink(qid)

	if isvalid(labeloption) then
		label = labeloption
	elseif isvalid(arlabel) then
		--mw.log("arlabel" .. arlabel)
		label = arlabel
	elseif isvalid(link) then
		label = link
		arlabel = link
	end

	if isvalid(link) then
		-- elseif isvalid(arlabel) then
		local linklabel = isvalid(label) or link
		if (isntvalid(options.nolink)) then
			value = "[[:" .. link .. "|" .. formatcharacters(linklabel, options) .. "]]"
			label = linklabel
		else
			value = formatcharacters(linklabel, options)
			label = linklabel
		end
	else
		local va = Labelfunction(qid, arlabel, options)
		label = va.value
		value = va.value -- .. va.cat
	end
	return {value = value or "", label = label or ""}
end

function sitelink_g(id, wikisite)
	--[[ function to get any link from any sister project ]]
	local site = wikisite or "arwiki"
	local link = mw.wikibase.sitelink(id, site) or ""
	--mw.log("mw.wikibase.sitelink,site: " .. site.. ",link:" .. link )
	return link
end

function sitelink(id, wikisite)
	local site = wikisite or "arwiki"
	local link = ""
	--local link = mw.wikibase.getSitelink( id, site ) or ""

	local entity = mw.wikibase.getEntityObject(id)
	if
		entity and entity.sitelinks and entity.sitelinks["" .. site .. ""] and entity.sitelinks["" .. site .. ""].site and
			entity.sitelinks["" .. site .. ""].title
	 then
		if entity.sitelinks["" .. site .. ""].site == site then
			link = entity.sitelinks["" .. site .. ""].title
		end
	end
	return link
end

function formatsitelink(entityId, options)
	--[[ function to get only the value with link ]]
	local link = sitelink(entityId)
	if isvalid(link) and isntvalid(options.nolink) then
		return "[[" .. link .. "]]" .. catewikidatainfo(options)
	end
	return link
end

function formatFromPattern(str, options)
	-- [[  function to replace $1 with string  ]]
	if isvalid(options.pattern) then
		str = string.gsub(str, "%%", "%%%%")
		str = mw.ustring.gsub(options.pattern, "$1", str)
	end
	return str
end

function p.getEntity(id)
	if type(id) == "table" then
		return id
	end
	return getEntityFromId(id)
end

function p.translate(str, rep1, rep2)
	str = i18n[str] or str
	if rep1 and (type(rep1) == "string") then
		str = str:gsub("$1", rep1)
	end
	if rep2 and (type(rep2) == "string") then
		str = str:gsub("$2", rep2)
	end
	return str
end

function p.getId(snak)
	if (snak.snaktype == "value") then
		if snak.datavalue.type == "wikibase-entityid" then
			return "Q" .. snak.datavalue.value["numeric-id"]
		end
	end
end

function p.addLinkBack(str, id, property)
	if not id then
		id = p.getEntity()
	end
	if not id then
		return str
	end
	if type(property) == "table" then
		property = property[1]
	end
	if type(id) == "table" then
		id = id.id
	end
	local class = ""
	if property then
		class = "wd_" .. string.lower(property)
	end
	local icon = "[[File:Blue pencil.svg|%s|10px|baseline|class=noviewer|link=%s]]"
	local title = i18n["see-wikidata-value"]
	local url = mw.uri.fullUrl("d:" .. id, "uselang=ar")
	url.fragment = property
	url = tostring(url)
	local v =
		mw.html.create("span"):addClass(class):wikitext(str):tag("span"):addClass("noprint wikidata-linkback"):css(
		"padding-left",
		"0.5em"
	):wikitext(icon:format(title, url)):allDone()
	return tostring(v)
end

-- Function to check whether a certain item is a parent of a given item.
-- If pExitItem is reached without finding the searched parent item, the search stops.
-- A parent is connected via P31 or P279.
-- Attention: very intensive function, use carefully!
function isParent(property, pItem, pParent, pExitItem, pMaxDepth, pDepth)
	if not pDepth then
		pDepth = 0
	end

	local entity = mw.wikibase.getEntity(pItem)
	if not entity then
		return false
	end
	local claims31
	local claims279
	if entity.claims then
		if isvalid(property) then
			claims31 = entity.claims[property]
		else
			claims31 = entity.claims["P31"]
			claims279 = entity.claims["P279"]
		end
	else
		return false
	end
	if not claims31 and not claims279 then
		return false
	end
	local parentIds = {}
	if claims31 and #claims31 > 0 then
		for i, v in ipairs(claims31) do
			parentIds[#parentIds + 1] = p.getId(v.mainsnak)
		end
	end
	if claims279 and #claims279 > 0 then
		for i, v in ipairs(claims279) do
			parentIds[#parentIds + 1] = p.getId(v.mainsnak)
		end
	end
	-- check if searched parent or exit item is reached or do recursive call
	if not parentIds[1] or #parentIds == 0 then
		return false
	end
	local itemString = ""
	local result = nil
	for i, qid in ipairs(parentIds) do
		if not qid then
			return false
		end
		--itemString = "Q" .. v
		itemString = qid
		if itemString == pParent then
			-- successful!
			return true
		elseif itemString == pExitItem then --or itemString == "Q35120"
			-- exit if either "exit item" or node item (Q35120) is reached
			return false
		else
			if pDepth + 1 < pMaxDepth then
				result = isParent(property, itemString, pParent, pExitItem, pMaxDepth, pDepth + 1)
			else
				return false
			end

			if result == true then
				return result
			end
		end
	end
	do
		return false
	end
end

function p.Subclass(options)
	if options then
		Frame_args = options
	end
	local parent = options.parent or ""
	local id = options.id or ""
	local Entity = getEntityFromId(id)
	if Entity then
		id = Entity.id
	end
	local property = options.property or "P31"
	if isntvalid(parent) or isntvalid(id) or isntvalid(property) then
		return false
	end
	local tab = mw.text.split(options.parent, ",")
	local result = mw.wikibase.getReferencedEntityId(id, property, tab) -- { "Q5", "Q2095" } )
	if result == nil and property == "P31" then
		result = mw.wikibase.getReferencedEntityId(id, "P279", tab)
	end
	if result then
		return true
	end
end

function old_isSubclass(options)
	if isntvalid(options.parent) then
		return false
	end
	local maxDepth
	maxDepth = tonumber(options.maxDepth) or 10
	if not type(maxDepth) == "number" then
		maxDepth = 5
	end
	local property = options.property
	local result
	result = isParent(property, options.id, options.parent, options.exitItem, maxDepth)
	if options.returnInt then
		if result == true then
			return 1
		else
			return nil
		end
	else
		return result
	end
end

function p.formatSnak(snak, options)
	return formatSnak(snak, options)
end

function p.formatEntityId(entityId, options)
	return formatEntityId(entityId, (options or {}))
end

function p.formatStatements(frame, key)
	if frame.args then
		if type(key) == "table" and key ~= {} then
		else
			Frame_args = frame.args
		end
	end
	--[[ The main function ]]
	local args = frame.args
	--If a value if already set, use it
	if isvalid(args.value) then
		return args.value
	end
	local wd_arg = frame:getParent().args["ويكي بيانات"] or frame.args["ويكي بيانات"] -- arg used to ban wikidata value
	if isvalid(wd_arg) == "لا" then
		return ""
	end

	local valuesnumb = 0
	local s
	local prop = formatStatements(args, key)
	if isvalid(args.returnnumberofvalues) then
		s, valuesnumb = formatStatements(frame.args, key)
	end
	if isvalid(prop) then
		if isvalid(args.mainprefix) then -- mainprefix
			prop = args.mainprefix .. prop
		end
		if isvalid(args.mainsuffix) then -- mainsuffix
			prop = prop .. args.mainsuffix
		end
		if isvalid(args.addTrackingCat) then -- add tracking cat
			prop = prop .. addTrackingCategory(frame.args)
		end
		if isvalid(args.mainsuffixAfterIcon) then -- another suffix but after wikidata icon
			prop = prop .. args.mainsuffixAfterIcon
		end
	else
		if isvalid(args.NoPropValue) then -- value if no local value and no wikidata value
			prop = args.NoPropValue
		end
	end
	if isvalid(args.returnnumberofvalues) then
		mw.log("valuesnumb: " .. valuesnumb)
		return s, valuesnumb
	end
	return prop
end

function p.formatStatementsFromLua(options, key) --	 main function but to use from lua module
	if options then
		if type(key) == "table" and key ~= {} then
		else
			Frame_args = options
		end
	end

	--If a value if already set, use it
	if isvalid(options.value) then
		return options.value
	end
	local valuesnumb = 0
	local s = formatStatements(options, key)
	if isvalid(options.returnnumberofvalues) then
		s, valuesnumb = formatStatements(options, key)
	end
	if isntvalid(s) then
		s = nil
	end
	if isvalid(s) then
		if isvalid(options.mainprefix) then -- mainprefix
			s = options.mainprefix .. s
		end
		if isvalid(options.mainsuffix) then -- mainsuffix
			s = s .. options.mainsuffix
		end
		if isvalid(options.addTrackingCat) then -- add tracking cat
			s = s .. addTrackingCategory(options)
		end
		if isvalid(options.mainsuffixAfterIcon) then -- another suffix but after wikidata icon
			s = s .. options.mainsuffixAfterIcon
		end
	else
		if isvalid(options.NosValue) then -- value if no local value and no wikidata value
			s = options.NosValue
		end
	end
	if isvalid(options.returnnumberofvalues) then
		--	mw.log( "valuesnumb: " .. valuesnumb )
		return s, valuesnumb
	end
	return s
end

function p.isSubclass(frame)
	return p.Subclass(frame.args)
end

-- Return the site link for a given data item and a given site (the current site by default)

function p.getSiteLink(frame)
	local site = frame.args[2] or frame.args.site
	local id = frame.args[1] or frame.args.id
	local count = frame.args.countsitelinks
	if isntvalid(id) then
		if isvalid(frame.args.page) then
			id = mw.wikibase.getEntityIdForTitle(frame.args.page)
		end
	end
	if isvalid(count) then
		return countSiteLinks(id)
	end
	local link = sitelink(id, site)
	if isvalid(link) then
		return link
	end
end

function p.getSiteLink1(frame)
	local project = frame.args[1]
	local id = frame.args[2]
	local link = sitelink(id, project)
	return link
end

-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
function p.pageId(frame)
	return mw.wikibase.getEntityIdForCurrentPage()
end

function p.descriptionIn(frame)
	local langcode = frame.args[1] or frame.args["lang"]
	local id = frame.args[2] or frame.args["id"]
	return descriptionIn(langcode, id)
end

function p.labelIn(frame)
	local langcode = frame.args[1] or frame.args["lang"]
	local id = frame.args[2] or frame.args["id"]
	return labelIn(langcode, id)
end

function p.getLabel(entity, lang)
	return labelIn(lang, entity)
end

function p.ViewSomething(frame) -- from en:Module:Wikidata
	local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
	local aa
	if isvalid(f.args.id) then
		aa = f.args.id
	end
	local data = mw.wikibase.getEntityObject(aa)
	if data == nil then
		return nil
	end
	local i = 1
	while true do
		local index = f.args[i]
		if index == nil then
			if type(data) == "table" then
				return mw.text.jsonEncode(data, mw.text.JSON_PRESERVE_KEYS + mw.text.JSON_PRETTY)
			else
				return tostring(data)
			end
		end
		data = data[index] or data[tonumber(index)]
		if data == nil then
			return
		end
		i = i + 1
	end
end

function p.Dump(frame)
	local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
	local aa
	if isvalid(f.args.id) then
		aa = f.args.id
	end
	local data = mw.wikibase.getEntityObject(aa)
	if data == nil then
		return i18n.warnDump
	end
	local i = 1
	while true do
		local index = f.args[i]
		if index == nil then
			return frame:extensionTag("source", mw.dumpObject(data), {lang = "lua"}) .. i18n.warnDump
		end
		data = data[index] or data[tonumber(index)]
		if data == nil then
			return i18n.warnDump
		end
		i = i + 1
	end
end

function p.countSiteLinks(id)
	return countSiteLinks(id)
end

function p.EntityIdForTitle(frame)
	local title = frame.args[1]
	local str = mw.wikibase.getEntityIdForTitle(title)
	--mw.log(str)
	return str
end

function p.Qidfortitleandwiki(frame)
	local title = frame.args[1]
	local wiki = frame.args[2]
	local str = mw.wikibase.getEntityIdForTitle(title, wiki)
	return str
end

return p