بۆ ناوەڕۆک بازبدە

مۆدیوول:Wikidata2/Copy

لە ئینسایکڵۆپیدیای ئازادی ویکیپیدیاوە
بەڵگەدارکردنی مۆدیوول[دروست بکە]
-- local fallback = {'en', 'nb', 'da', 'nn', 'de', 'fr', 'es', 'it', 'pt'}
local formatera = require('مۆدیوول:Math')
local Frame;
local wikidata2 = require('مۆدیوول:Wikidata2')

local i18n = {
	["errors"] = {
		["property-param-not-provided"] = "Property parameter not provided.",
		["entity-not-found"] = "Entity not found.",
		["unknown-claim-type"] = "Unknown claim type.",
		["unknown-snak-type"] = "Unknown snak type.",
		["unknown-datatype"] = "Unknown datatype.",
		["unknown-entity-type"] = "Unknown entity type.",
		["unknown-value-module"] = "You must set both value-module and value-function parameters.",
		["unknown-claim-module"] = "You must set both claim-module and claim-function parameters.",
		["unknown-property-module"] = "You must set both property-module and property-function parameters.",
		["property-module-not-found"] =  "The module pointed by property-module not found.",
		["property-function-not-found"] = "The function pointed by property-function not found.",
		["value-module-not-found"] = "The module pointed by value-module not found.",
		["value-function-not-found"] = "The function pointed by value-function not found.",
		["claim-module-not-found"] = "The module pointed by claim-module not found.",
		["claim-function-not-found"] = "The function pointed by claim-function not found."
    },
    ["somevalue"] = "", --''غير محدد''
    ["novalue"] =''--قيمة مجهولة
}

local sortingproperties = {'P585','P571','P580','P569','P582','P570'}

function countSiteLinks(id)
	numb = 0
	Table = {}
	local entity = mw.wikibase.getEntityObject(id)
	if entity and entity.sitelinks then
		for i, v in pairs(entity.sitelinks) do 
			Table[v.site] = v.title 
			numb = numb +1
		end
		--return Frame:extensionTag("source", mw.dumpObject( Table ),{ lang= 'lua'})
	end
	return numb
end
			
local cateref = ''

function catewikidatainfo(options)
	local prop = options.property
	local catewikidatainfo = ''
return catewikidatainfo 
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

--auktoritetsdata
function formatcharacters(label, options)
	local formatcharacters = options.formatcharacters
	--if options.FormatfirstCharacter and options.num == 1 then 
		--formatcharacters = options.FormatfirstCharacter 
	--end
	if options.illwd2y and options.illwd2y ~= '' then
		String2 = mw.ustring.gsub( label , '–', '-' )
		ca = 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 )
		ca = ca or mw.ustring.match( String2 , "%d%d%d%d", 1 ) or mw.ustring.match( String2 , "%d%d%d%d%-%d%d", 1 )
		ca = ca or mw.ustring.match( String2 , "%d%d%d%d", 1 ) or String
		return ca
	end
	if not formatcharacters or formatcharacters == '' then
		return label
	end
	if formatcharacters == 'lcfirst' then
		return mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}lcfirst: " .. label .. " }}")
	elseif formatcharacters == 'ucfirst' then
		return mw.language.getContentLanguage():ucfirst( label )
	elseif formatcharacters  == 'lc' then
		return mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}lc: " .. label .. " }}")
	elseif formatcharacters == 'uc' then
		return mw.getCurrentFrame():preprocess("{{ {{{|safesubst:}}}uc: " .. label .. " }}")
	elseif formatcharacters == 'formatnum' then
		return make_format_num( label )
	end
	return label
end

function getqualifierbysortingproperty(claim, sortingproperty)
	for k, v in pairs(sortingproperty) do
		if claim.qualifiers and claim.qualifiers[v] and claim.qualifiers[v][1].snaktype == 'value' then
			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 getDate(claim, options)
	local sortingproperty = sortingproperties
	if type(options.sortingproperty) == 'table' then
		sortingproperty = options.sortingproperty
	elseif type(options.sortingproperty) == 'string' then
		sortingproperty = {options.sortingproperty}
	end
	return getqualifierbysortingproperty(claim, sortingproperty) 
end

function get_entityId(options)
	local id = options.entityId
	if not id or id == "" then
		if options.page and options.page ~= "" then
			id = mw.wikibase.getEntityIdForTitle( options.page )
		end
	end
	--mw.log("id :" .. id)
	return id or ""
end

function getDateArb(claim, options)
	local sortingproperty = options.sortingproperty or 'P569'
	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
		return formatStatements({property = sortingproperty, entityId = item, firstvalue = 'true', sortbytime = 'chronological', noref = 'true'})
	end
end

function descriptionIn(langcode , id) -- returns item description for a given language
	local lan = langcode or 'ckb'
	if not mw.wikibase then return nil end
	local description, lange = mw.wikibase.getDescriptionWithLang( id )
	if lange == lan
	then
		return description
	else
		return nil
	--return str
	end
	--[[local entity = mw.wikibase.getEntityObject(id)
		if entity
		and entity.descriptions 
		and entity.descriptions[''..lan..'']
		and entity.descriptions[''..lan..''].value 
		then
			local lang = entity.descriptions[''..lan..'']
			if lang['language'] == lan then
			return entity.descriptions[''..lan..''].value
			else return nil end
		end
	]]
end

function labelIn(langcode,id) -- returns item label for a given language
	if not mw.wikibase then return nil end
	local lan = langcode or 'ckb'
	local label, lange = mw.wikibase.getLabelWithLang( id )
	if lange == lan
	then
		return label
	else
		return nil
	--return str
	end
	--[[local entity = mw.wikibase.getEntityObject(id)
		if entity
		and entity.labels 
		and entity.labels[''..lan..'']
		and entity.labels[''..lan..''].value 
		then
			local lang = entity.labels[''..lan..'']
				if lang['language'] == lan then
				return entity.labels[''..lan..''].value
				else return nil end
		end
	]]
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 = 'Q' .. snak.datavalue.value['numeric-id']
		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
	local a = tonumber(a) or a
	local b = tonumber(b) or b
	if a and b then
		return a > b
	elseif a then
		return true
	end
end

function getonly(claims, options)
	local claims2 = {}
	--mw.log("wikidata2 : getonly:" .. options.getonly )
	for i, j in pairs(claims) do
		local id = get_snak_id(j)
		--if j.mainsnak and j.mainsnak.snaktype == 'value' and j.mainsnak.datavalue and j.mainsnak.datavalue.value and j.mainsnak.datavalue.value.id then
			--local id = j.mainsnak.datavalue.value.id
		if id then
			local traff = false
			local t2 = formatStatements( {property = (options.getonlyproperty or "P31"), entityId = id, noref = 'true', raw = 'true' })
			if t2 and #t2 > 0 then
				for k, state in pairs( t2 ) do
					for j2, only in pairs(mw.text.split(options.getonly,',')) do
						if state.item == only then
							traff = true
						end
					end
				end
			end
			if traff then
				table.insert(claims2, j)
			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)
	-- to avoid values
	local claims4 = {}
	--mw.log("avoidvalue: " .. options.avoidvalue)
	for i, j in pairs( claims ) do
		local keepwork = true
		ID = get_snak_id(j)
		if ID then
			mw.log("ID:" .. ID)
			for k, t in pairs(mw.text.split(options.avoidvalue,',')) do
				if keepwork == true then
					mw.log('t:' .. t)
					if ID == t then
						keepwork = false
					end
				end
			end
			if keepwork == true then
				table.insert( claims4 , j )
			end
		end
	end
	return claims4
end

function prefervalue(claims, options)
	local claims3 = {}
	--mw.log("prefervalue: " .. mw.dumpobject(options.prefervalue))
	local prefervalue
	if(type(options.prefervalue) == 'string') then prefervalue = mw.text.split(options.prefervalue,',')
		elseif(type(options.prefervalue) == 'table') then prefervalue = options.prefervalue
			else return claims
	end	
	for k, t in pairs(prefervalue) do
		--mw.log('t:' .. t)
		for i, j in pairs( claims ) do
			local active = false
			ID = get_snak_id(j)
			if ID then
				--mw.log("ID: " .. ID)
				if ID == t and not active then
					table.insert( claims3, j)
					active = true
					--mw.log("ID == t" .. t)
				end
			end
		end
	end
	return claims3
end
function preferqualifier(claims, options)
	mw.log("preferqualifier: " .. options.preferqualifier)
	local claims2 = {}
	for i, statement in pairs( claims ) do -- 
		if statement.qualifiers and statement.qualifiers[options.preferqualifier:upper()] then
			if options.preferqualifiervalue and options.preferqualifiervalue ~= '' then
				local active = false
				for k, t in pairs(mw.text.split(options.preferqualifiervalue,',')) do
					--mw.log( "t " .. t )
					--kaso = formatStatements({property=options.preferqualifier:upper(), raw = 'true',  formatting  = 'raw'}, statement.qualifiers)
					----kaso = formatStatements({property=options.preferqualifier:upper(), formatting  = 'raw'}, statement.qualifiers)
					----value = kaso
					for ii, quall in pairs( statement.qualifiers[options.preferqualifier:upper()] ) do
						--mw.log( "value " .. value )
						snaktype = quall.snaktype
						if snaktype == "value" then
							ty = quall.datavalue.value['id'] 
							if ty and ty == t  and not active then
								--if value == t and not active then
									table.insert( claims2, statement)
									active = true
								--end
							end
						end
					end
				end
			else
				table.insert( claims2, statement)
			end
		end
	end
	return claims2
end

function avoidqualifier(claims, options)
	-- options.avoidqualifier
	-- options.avoidqualifiervalue
	if not options.avoidqualifier or options.avoidqualifier == "" then return claims end
	local av = options.avoidqualifier:upper()
	local claims2 = {}
	for i, statement in pairs( claims ) do	
		if not statement.qualifiers or not statement.qualifiers[options.avoidqualifier:upper()] then
			table.insert( claims2, statement)
		elseif statement.qualifiers and statement.qualifiers[av] then
			if options.avoidqualifiervalue and options.avoidqualifiervalue ~= '' then
				list = {}
				if(type(options.avoidqualifiervalue) == 'string') then 
					list = mw.text.split(options.avoidqualifiervalue,',')
				elseif(type(options.avoidqualifiervalue) == 'table') then 
					list = options.avoidqualifiervalue
				end
				local active = true
				for k, t in pairs( list ) do
					for ii, quall in pairs( statement.qualifiers[av] ) do
						if quall.snaktype == "value" and quall.datavalue and quall.datavalue.value and quall.datavalue.value['id'] then
							if quall.datavalue.value['id'] == t then
								active = false
							end
						end
					end
				end
				if active then 
					table.insert( claims2, statement)
				end
			end
		end
	end
	return claims2
end

function sortbyqualifier(claims, options)
	table.sort(claims, function(a,b)
		local timeA = getDate(a, options)
		local timeB = getDate(b, options)
		if options.sortbytime == 'inverted' then
			return comparedates(timeB, timeA)
		else
			return comparedates(timeA, timeB)
		end
	end
	)
	return claims
end

function getqualifierbysortingproperty2(claim, options)
	local sortingproperty = options.sortingproperty
	if type(options.sortingproperty) == 'string' then
		sortingproperty = {options.sortingproperty}
	end
	for k, v in pairs(sortingproperty) do
		if claim.qualifiers and claim.qualifiers[v] and claim.qualifiers[v][1].snaktype == 'value' then
			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 sortbyqualifiernumber(claims, options)
	table.sort(claims, function(a,b)
		local timeA = getqualifierbysortingproperty2(a, options)
		local timeB = getqualifierbysortingproperty2(b, options)
		if options.sortbynumber == 'inverted' then
			return comparedates(timeB, timeA)
		else
			return comparedates(timeA, timeB)
		end
	end
	)
	return claims
end

function sortbyarb(claims, options)
	--mw.log("sortbyarb: " .. options.sortbyarbitrary)
	table.sort(claims, function(a,b)
		local timeA = getDateArb(a, options)
		local timeB = getDateArb(b, options)
		if options.sortbyarbitrary == 'inverted' then
			return comparedates(timeB, timeA)
		else
			return comparedates(timeA, timeB)
		end
	end
	)
	return claims
end

function Labelfunction( entityId, label ,labeloption , options) -- label with no arwiki sitelink
	if options.illwd2nowd  and options.illwd2nowd  ~= '' then noWD='' else noWD='y' end
	local jlabel = label --formatcharacters(label, options) -- The label
	local ar = labelIn('ar',entityId ) -- The arabic label
	local arlabel = ar --formatcharacters(ar, options) 
	if labeloption and labeloption ~= '' then
			jlabel = labeloption 
	elseif options.illwd2  and options.illwd2  ~= '' then
		if arlabel and arlabel ~= '' then
			jlabel = mw.getCurrentFrame():expandTemplate{ title = 'Ill-WD2', args = {arlabel, id=entityId, y = (options.illwd2y or '') } }
			else 
			jlabel  = mw.getCurrentFrame():expandTemplate{ title = 'Ill-WD2', args = {id=entityId, target='en', y = (options.illwd2y or '') } }
		end
		
	elseif options.enlabelcate and options.enlabelcate  ~= '' then
			if not arlabel or arlabel == '' then
				jlabel = label --formatcharacters(label, options)
				 if jlabel and jlabel ~= '' then
				 jlabel = jlabel --..' [['.. i18n.noarabiclabel ..'|'.. entityId ..']]'
				 mw.log(entityId .. " " .. jlabel)
			end end
			
	else--if options.justarabic and options.justarabic  ~= '' then
			if arlabel and arlabel ~= ''
				then jlabel = arlabel
				else jlabel = nil
			end
	end
	if jlabel and jlabel ~= ''
	then
	return jlabel.. catewikidatainfo(options)
	end
end

function getEntityFromId( id )
        if not mw.wikibase then return nil end
	if id and id ~= "" then 
		return mw.wikibase.getEntityObject( id )
	else
		return mw.wikibase.getEntityObject() 
	end
end
 
function getEntityIdFromValue( value )
    if value then
	    if value['entity-type'] == 'item' then
	        return 'Q' .. value['numeric-id']
	    elseif value['entity-type'] == 'property' then
	        return 'P' .. value['numeric-id']
	    end
    end
    return formatError( 'unknown-entity-type' )
end
 
function formatError( key )
    return i18n.errors[key]
end

function formatOneStatement( statement , ref, options)
	local vava = nil
	local stat = formatStatement( statement, options )
	if stat then
		local s = stat.value
		local d = stat.datum
		local tf = stat.tifr
		local awardqual = stat.foto
		local pr = stat.pr
		local utgivort = stat.utgivort
		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
		--local PQual = stat.PQual

		if s == '' then s = nil end
		if s then
			if reff and options.reff and options.reff ~= ''  then
				s= s .. reff
			end
			if options.template and 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 options.football and options.football ~= '' then
				s =mw.getCurrentFrame():expandTemplate{ title = "صندوق معلومات سيرة كرة قدم/سطر فريق", args = {
				(stat.start1 or ''),
				(stat.finish1 or ''),
				s,
				stat.amatch,
				stat.goal
				} }
			end
			
			if options.office and options.office ~= '' then
				s = mw.getCurrentFrame():expandTemplate{ title = "معلومات صاحب منصب/منصب ويكي بيانات/نواة", args = 
				{office = s, 
				termstart = stat.start1, 
				termend = stat.finish1, 
				constituency = stat.constituency1, 
				predecessor = stat.before1, 
				successor = stat.after1, 
				series= stat.series1,
				of=stat.pp642,
				electedin=stat.electedin1,
				jurisdiction=stat.pp1001,
				employer=stat.pp108,
				entityId=options.entityId
				} } 
			end
			if options.office2 and options.office2 ~= '' then
				s = mw.getCurrentFrame():expandTemplate{ title = "معلومات صاحب منصب/منصب ويكي بيانات2", args = 
					{office = s,
					termstart = stat.start1,
					termend = stat.finish1, 
					constituency = stat.constituency1, 
					predecessor = stat.before1, 
					successor = stat.after1, 
					series= stat.series1, 
					P642= stat.pp642
					
				} }
			end
			local s_after = ""
					if qp1 and options.qual1 and options.qual1 and qp1a and options.qual1a and options.qual1a ~= '' then
						s = s .. '، '.. (options.qual1pref or '') .. qp1  .. (options.qual1suff or '') ..'، ' .. (options.qp1apref or '') .. qp1a
					else
					if qp1 and options.qual1 and options.qual1 ~= '' then
						s = s .. '، '.. (options.qual1pref or '') .. qp1 .. (options.qual1suff or '') 
					else
					if qp1a and options.qual1a and options.qual1a ~= '' then
						s = s .. '، '.. (options.qp1apref or '') .. qp1a
					end end end
					if qp2 and options.qual2 and options.qual2 ~= '' then
						s = s .. ' ('.. (options.qual2pref or '') .. qp2 .. ')'  .. (options.qual2suff or '') 
					end
					if qp3 and options.qual3 and options.qual3 ~= '' then
						s = s ..  ' ('.. (options.qual3pref or '') .. qp3 .. ')' 
					end
					if qp4 and options.qual4 and options.qual4 ~= '' then
						s = s ..' ('.. (options.qual4pref or '') .. qp4 .. ')' 
					end
					if qp5 and options.qual5 and options.qual5 ~= '' then
						s = s .. ' ('.. (options.qual5pref or '') .. qp5 .. ')'
					end
					if options.justthisqual and options.justthisqual ~= '' then 
						if onlyqualifier then 
							s = (options.qualifierprefix or "") .. onlyqualifier
						else
							--if not options.justthisqual ~= '' then s = nil  end
							s = nil-- We need only the qualifier
						end
					end
					if ro and options.withro and options.withro ~= '' then
						s = s ..  ' (' .. ro .. ')'
					end
					if d and options.withdate and options.withdate ~= '' then
						if options.withdate == 'y' then
							s = s ..  ' (سنة ' .. d .. ')'
						elseif options.withdate == 'في' then
							s = s .. ' في ' ..  d
						else
							s = s .. ' (' .. d .. ')'
						end
					end
					if awardqual and options.awardqua and options.awardqua ~= '' then
						s = s ..' (' .. awardqual .. ')'
					end
					local bothdates = options.withintervall or options.bothdates
					if tf and bothdates and bothdates ~= '' then
						if bothdates == 'line' then
							s = s .. mw.text.tag('br') .. '' .. tf .. ''
						elseif bothdates == 'before' then
							s =  '(' .. tf .. ') ' .. s
						else
							s = s .. ' (' .. tf .. ')'
						end
					end
			
					if utgivort and options.withutgivort and options.withutgivort ~= '' then
						if options.withutgivort == 'قوسين' then
							s = s .. ' ' ..  ' (' .. utgivort .. ')'
						else
							s = s .. ' ' .. utgivort
						end
					end
					if options.getsimpleproperty == 'f?dd' and pr and pr ~= '' then
						s = s .. ' ' ..  '(f. ' .. pr .. ')'
					end
					if options.getsimpleproperty == 'parentes' and pr and pr ~= '' then
						s = s .. ' ' .. mw.text.tag('span', {}, '(' .. pr .. ')')
					end
					if options.getsimpleproperty == 'avnågon' and pr and pr ~= '' then
						s = s .. ' ' .. mw.text.tag('span', {}, ' av ' .. pr .. '')
					end
					
					--if PQual and PQual ~= '' then
					--	if options.preferqualifiervalue == Q 
							--then s = s .. ' ' .. Q
							--else s = nil
						--end
					--end

			if type(ref) == 'table' or (options.noref and options.noref ~='') or (options.justthisqual and options.justthisqual ~='') -- or (options.preferqualifiervalue and options.preferqualifiervalue ~='') 
				then --Do not look for references if the call is made from a reference
					--table.insert( valuetable, s )
					vava =  s 
			else
				local t = formatReferences( statement, options )
				stat.ref = t
					if options.justref and options.justref ~= '' 
					then
						--table.insert( valuetable, t )
						vava =  t
					else 
						--table.insert( valuetable, s .. t )
						vava =  s .. t 
					end
			end
		end
	--table.insert(statementsraw, stat)
	end
	
	return { v = vava , raw = stat}
end

function formatStatements( options, ref )
   	local valuetable = {}
   	local claims = {}
   	if not options.property then return formatError( 'property-param-not-provided' ) end

    if type(ref) == 'table' then -- f?r de fall d?r funktionen anropas och alla claims redan finns i en tabell
		claims = ref[options.property] or {}
	else
    	--Get entity
    	local entity = nil
    	if options.entity and type( options.entity ) == "table" then
        	entity = options.entity
    	else 
        	--entity = getEntityFromId( options.entityId )
        	id = get_entityId( options )
        	entity = getEntityFromId( id )
    	end
    	local property = mw.wikibase.resolvePropertyId( options.property:upper() )
 
    	if not entity then return '' end --TODO error? 
    	if not entity.claims or not entity.claims[property] then
	    	if options.otherproperty and options.otherproperty ~= "" then 
	    		options.property = options.otherproperty
	    		property = mw.wikibase.resolvePropertyId( options.property:upper() )
	    	end
    	end
    	if not property then return '' end --TODO error? 
    	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 not options.rank then 
			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
		--======================================================
		--[[if options.avoidqualifier and options.avoidqualifier ~= '' then  -- to avoid value with a given qualifier
			local claims2 = {}
			for i, statement in pairs( claims ) do	
				if not statement.qualifiers or not statement.qualifiers[options.avoidqualifier:upper()] then
					table.insert( claims2, statement)
				end
			end
			claims = claims2
		end
		]]
		--======================================================
		if options.avoidqualifier and options.avoidqualifier ~= '' then 		-- to avoid value with a given qualifier
			claims = avoidqualifier(claims, options)
		end
		--======================================================
		if options.preferqualifier and options.preferqualifier ~= '' then
			claims = preferqualifier(claims, options)
		end
		--======================================================
		-- options.avoidvalue
		if options.avoidvalue and options.avoidvalue ~= '' then
			claims = avoidvalue(claims, options)
		end
		--======================================================
		-- options.prefervalue
		if options.prefervalue and options.prefervalue ~= '' then
			claims = prefervalue(claims, options)
		end
		--======================================================
		-- options.getonly
		if options.getonly and options.getonly ~= '' then
			claims = getonly(claims, options)
		end
		--======================================================
		if not options.langpref or options.langpref == '' then
			local claims2 = {}
			for i, statement in pairs( claims ) do
				if statement.qualifiers and statement.qualifiers.P407 then
					for k, v in pairs( statement.qualifiers.P407 ) do
						if v.snaktype == 'value' and v.datavalue.value['numeric-id'] == 13955 then -- Q13955 = 'العربية'
							table.insert( claims2, statement )
						end
					end
				elseif statement.qualifiers and statement.qualifiers.P282 then
					for k, v in pairs( statement.qualifiers.P282 ) do
						if v.snaktype == 'value' and v.datavalue.value['numeric-id'] == 8196 then -- Q8196 = 'أبجدية عربية'
							table.insert( claims2, statement )
						end
					end
				end
			end
			if #claims2 > 0 then
				claims = claims2
			end
		end
		--======================================================
		if options.sortbytime == 'chronological' or options.sortbytime == 'inverted' then
			claims = sortbyqualifier(claims, options)
		elseif options.sortbynumber == 'chronological' or options.sortbynumber == 'inverted' then
			claims = sortbyqualifiernumber(claims, options)
		elseif options.sortbyarbitrary == 'chronological' or options.sortbyarbitrary == 'inverted' then
			claims = sortbyarb(claims, options)
		end
		--======================================================
	end
	local firstvalue =  options.enbarten or  options.firstvalue
	if firstvalue and firstvalue ~='' and #claims > 1 then
		if firstvalue == '2' then
			claims = {claims[2]}
			elseif firstvalue == '3' and #claims > 2 then
			claims = {claims[3]}
			elseif firstvalue == '4' and #claims > 3 then
			claims = {claims[4]}
			elseif firstvalue == '5' and #claims > 4 then
			claims = {claims[5]}
			elseif firstvalue == '6' and #claims > 5 then
			claims = {claims[6]}
			elseif firstvalue == '7' and #claims > 6 then
			claims = {claims[7]}
			elseif firstvalue == '8' and #claims > 7 then
			claims = {claims[8]}
			elseif firstvalue == '9' and #claims > 8 then
			claims = {claims[9]}
			else
			claims = {claims[1]}
		end
	end
	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,ref ,  options )
				if va.v then
					table.insert( valuetable, va.v )
				end
				table.insert( statementsraw, va.raw )
			end
		end
	end
	local priff = ""
	local Separator = options.separator 
	local Conjunction = options.conjunction
	
	if not options.separator then Separator = "، و" end
	if not options.conjunction then Conjunction = "، و" end

	if Conjunction and Conjunction == "br" then Conjunction =  "\n" end
	if Separator and Separator == "*" 
	then 
		priff = "\n*" 
		Separator = "\n*" 
		Conjunction = "\n*" 
	end
	if Separator and Separator == "#" 
	then 
		priff = "\n#" 
		Separator = "\n#" 
		Conjunction = "\n#" 
	end
	if options.separator and options.separator == "br" or ( options.conjunction  and options.conjunction   == "br" ) 
	then 
		Separator = "\n" 
		Conjunction = "\n" 
	end
	local tot = mw.text.listToText( valuetable, Separator, Conjunction )
	if #valuetable > 1 then
		tot = priff .. tot
	end
	if tot == '' then tot = nil end
	if options.raw and options.raw ~= '' then
		return statementsraw
	end
	if options.numberofclaims and options.numberofclaims ~= '' then
		return #All_claims
	end
	return tot
end

function formatReferences( statement, options )
	local reference = {}
	if statement.references then
		local cite = require('مۆدیوول:Cite/Copy')
		for i, ref in pairs(statement.references) do
			local items, s = {}, nil
			if ref.snaks then

				if ref.snaks.P248 then
					for j, prop in pairs(ref.snaks.P248) do
						if prop.snaktype == 'value' then
							table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
					end end
				elseif ref.snaks.P143 then
					for j, prop in pairs(ref.snaks.P143) do
						if prop.snaktype == 'value' then
						table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
					end end
				end
				s = cite.citeitem( items , ref.snaks , ref.hash , options )

			end
			table.insert(reference, s)

		end
	end
	local final = table.concat(reference)
	return final
end

function formatqualifiers( statement,s, options )
	local ccid = ""
	if statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value['numeric-id'] then 
		ccid = 'Q' .. statement.mainsnak.datavalue.value['numeric-id']
	end
	s.ID = ccid
	function qua( p , firstvalue , modifytime , Formatting )
		if p and p ~='' then return (formatStatements({
			property =p,
			enlabelcate = 't', 
			illwd2 = options.illwd2, 
			firstvalue = (firstvalue or ''),
			modifytime = (modifytime or 'longdate'), 
			formatting = Formatting or "" , 
			noref = 'true' , 
			formatcharacters = options.formatcharacters
			
		}
		, statement.qualifiers) or '') end
	end
	if options.template and options.template ~= '' then
		s.QQ1 = qua(options.Q1 , "" , "" , options.Q1formatting )
		s.QQ2 = qua(options.Q2 , "" , "" , options.Q2formatting )
		s.QQ3 = qua(options.Q3 , "" , "" , options.Q3formatting )
		s.QQ4 = qua(options.Q4 , "" , "" , options.Q4formatting )
		s.QQ5 = qua(options.Q5 , "" , "" , options.Q5formatting )
		s.QQ6 = qua(options.Q6 , "" , "" , options.Q6formatting )
		s.QQ7 = qua(options.Q7 , "" , "" , options.Q7formatting )
		s.QQ8 = qua(options.Q8 , "" , "" , options.Q8formatting )
		s.QQ9 = qua(options.Q9 , "" , "" , options.Q9formatting )
		s.QQ10 = qua(options.Q10 , "" , "" , options.Q10formatting )
		--mw.log("id: " .. s.ID)
		--mw.log(s.QQ1 )
	end
	if statement.qualifiers.P1350 or statement.qualifiers.P1351 then
		s.amatch = qua("P1350",'true')
		s.goal = qua("P1351",'true')
	end
	if statement.qualifiers.P580 or statement.qualifiers.P582 or statement.qualifiers.P1365 or statement.qualifiers.P1366 then
		s.start1 = qua("P580",'true')
		s.finish1 = qua("P582",'true')
		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
	if statement.qualifiers.P585 then
		s.datum = qua("P585",'true',options.modifyqualifiertime)
	end
    local qwe = options.qwer
	if statement.qualifiers.qwe  then
		s.ro = qua(qwe,'true')
	end
	if statement.qualifiers.P574 then
		s.dateoftaxpub = qua("P574",'true',options.modifyqualifiertime)
	end
	if statement.qualifiers.P405 then
		local author = {}
		for i, j in pairs(statement.qualifiers.P405) do
			if j.snaktype == 'value' then
				local item = 'Q' .. j.datavalue.value['numeric-id']
				local authorname = formatStatements({property = "P428", entityId = item, noref = 'true', firstvalue = 'true'})
				if author and authorname ~= '' then
					table.insert(author, formatEntityId(item, {label = authorname}).value)
				else
					table.insert(author, formatEntityId(item, {}).value)
				end
			end
		end
		s.auktor = mw.text.listToText(author, ', ', ' & ')
	end	
	if statement.qualifiers.P580 or statement.qualifiers.P582 then 
		local f = qua("P580",'true',options.modifyqualifiertime)
		if statement.qualifiers.P582 
		then
			local t =  qua("P582",'true',options.modifyqualifiertime)
			s.tifr = f .. '–' .. t
				if not statement.qualifiers.P580 then  s.tifr = 'ھەتا ' .. t end
		else 
			s.tifr = 'منذ '.. f 
		end
	end
	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
	function quaaal(opti,options)
		if opti and opti ~=''  and statement.qualifiers[opti] then
			return (formatStatements({property = opti, noref = 'true', 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 '')
		end
	end
	if statement.qualifiers.P291 then       -- خاصية بلد النشر
		s.utgivort = formatStatements({property = "P291",illwd2 ='t', noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
	end
	if statement.qualifiers.P2096 then
		s.bildtext = formatStatements({property = "P2096",illwd2 ='t',  noref = 'true', langpref = (options.langpref or 'ckb')}, statement.qualifiers)
	end
	if s then
		if options.justthisqual and options.justthisqual ~= '' and statement.qualifiers[options.justthisqual] then
			s.onlyqualifier = formatStatements({property = options.justthisqual ,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,modifytime = options.modifyqualifiertime,formatcharacters = options.formatcharacters}, statement.qualifiers)
		end
		if options.qual1 and options.qual1 ~= '' and statement.qualifiers[options.qual1] then         -- عرض تصفيات لبنود الخاصية
			s.qp1 = formatStatements({property = options.qual1, illwd2 ='t', noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,size =options.size,image =options.image,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
		if options.qual1a and options.qual1a ~= '' and statement.qualifiers[options.qual1a] then
			s.qp1a = formatStatements({property = options.qual1a,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
		if options.qual2 and options.qual2 ~= '' and statement.qualifiers[options.qual2] then
			s.qp2 = formatStatements({property = options.qual2,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,size =options.size,image =options.image,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
		
		if options.qual3 and options.qual3 ~= '' and statement.qualifiers[options.qual3] then
			s.qp3 = formatStatements({property = options.qual3,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
		if options.qual4 and options.qual4 ~= '' and statement.qualifiers[options.qual4] then
			s.qp4 = formatStatements({property = options.qual4,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
		if options.qual5 and options.qual5 ~= '' and statement.qualifiers[options.qual5] then
			s.qp5 = formatStatements({property = options.qual5,illwd2 ='t',  noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction,modifytime = options.modifyqualifiertime}, statement.qualifiers)
		end
	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 not formatter then
            return {value = formatError( 'claim-module-not-found' )}
        end
        local fun = formatter[options['claim-function']]
        if not fun 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 s and s ~= ''  then
			if statement.references then
				if options.reff and options.reff ~= ''  then
					s.reff  = formatReferences( statement, options )
				end 
			end
			if statement.qualifiers then
				qualu = formatqualifiers( statement,s, options )
				if qualu and qualu ~= '' then table.insert(qualu) end
			end
		end
		return s
		--==========================================
	elseif not statement.type then
		return formatSnak( statement, options )
    end
	return {value = formatError( 'unknown-claim-type' )}
end
 
function formatSnak( snak, options )
    if snak.snaktype == 'somevalue' then
    	if options.somevalue then
    		if options.somevalue == '' then
    			return nil
    		else
    			return {value = options.somevalue}
    		end
    	end
        return {value =  i18n['somevalue']}
    elseif snak.snaktype == 'novalue' then
    	if options.novalue then
    		if options.novalue == '' then
    			return nil
    		else
    			return {value = options.novalue}
    		end
    	end
        return {value = i18n['novalue']}
    elseif snak.snaktype == 'value' then
    	local s = formatDatavalue( snak.datavalue, snak.datatype, options )
    	if s and s.value and options.prefix and options.prefix ~= '' then
    		s.value = options.prefix .. " " .. s.value
    	end
    	if s and s.value and options.suffix and options.suffix ~= '' then
    		s.value = s.value .. " " .. options.suffix
    	end
        if s and s.value and s.item and options.getsimpleproperty and options.getsimpleproperty ~= '' and options.getproperty and options.getproperty ~= '' then
        	local pr = formatStatements({property = options.getproperty, entityId = s.item, firstvalue = options.getenbarten, noref = 'true', modifytime = options.getmodifytime, raw = options.getraw})
        	if pr then s.pr = pr end
        end
        return s
    else
        return {value = formatError( 'unknown-snak-type' )}
    end
end

 --[[ datatype  wikibase-item  ]]

local skiip = {
	["P106"] = {"Q42857"}
	}
function formatwikibaseitem( datavalue, datatype, options )
	local item = getEntityIdFromValue( datavalue.value )
	local itemValue = formatEntityId( item , options ).value
	local Format = options.formatting or options["formatting"]
	local Skipped = skiip[options.property] or {}
	for k, v in pairs(Skipped) do
		if datavalue.value.id == v then 
			return {value = ""}    	
		end
	end
    if options.formatting and options.formatting  ~= '' 
	then
		if options.formatting == 'raw' then 
			--mw.log("raw: " .. item )
			return {value = item}
		elseif options.formatting == 'rawtotemplate' then 
			mw.log('options')
			mw.log(options)
			if options.rawtotemplate  and options.rawtotemplate ~= ''  then 
				return {value = mw.getCurrentFrame():expandTemplate{ title = options.rawtotemplate, args = {
					q = item , no1 = options.no1 or '' , no2 = options.no2 or ''
					
				}} .. '\n'
				}
			else
			end
		elseif options.formatting == 'fu' then 
			fu_temp = "Cycling race/stageclassification2"
			return {value = mw.getCurrentFrame():expandTemplate{ title = fu_temp , args = {item}}}
		elseif options.formatting == 'sitelink' then  -- for Wikidata property giving Wikimedia list
			return {value = formatsitelink(datavalue.value.id , options ) }
		elseif options.formatting == 'sitelink1' then 
			return {value = formatsitelink1(datavalue.value.id , options ) }
		else
			return {value = formatFromPattern( formatcharacters(datavalue.value, options), options )}
		end
	------------------------------
	elseif options.property1 and options.property1 ~= '' then
		for i, statement in pairs( datavalue ) do
    		caca = formatStatements( {
    			property =options.property1
    			, entityId = item
    			, noref =options.noref 
    			,rank=options.property1rank
    			,pattern =options.property1pattern
    			,formatting=options.property1formatting
    			,size =options.size
    			,image =options.image
    			,noref='true'
    			,firstvalue ='true' })
			if itemValue and itemValue  ~= '' then
				if caca and caca  ~= '' then 
					cooooca = (options.property1pref or '') ..''.. caca ..''.. (options.property1suff or '')
					if options.property1after and options.property1after ~= "" then
						return {value = itemValue .. cooooca } 
					else
						return {value = cooooca .. ' '.. itemValue } 
					end
				else
					return {value = itemValue  }
				end
			end
		end 
	------------------------------
	elseif options.propertyimage and options.propertyimage ~= '' then
		mw.log("propertyimage")
		local p_f = options.propertyimageformatting or options.formattingpropertyimage
		for i, statement in pairs( datavalue ) do
			local vas = formatStatements( {
				property =options.propertyimage 
				,formatting= p_f
				,entityId = item
				,noref =options.noref
				,rank=options.rank
				,pattern =options.pattern
				,size =options.size
				,image =options.image
				,noref='true'
				,avoidvalue = options.avoidvaluepropertyimage
				,firstvalue ='true'
				,nolink=options.nolink 
			})
			if vas and vas  ~= '' then 
				return {value =  vas }
			end
		end 
	------------------------------
	elseif options.property2 and options.property2 ~= '' then
		for i, statement in pairs( datavalue ) do
			local caca = formatStatements( 
				{property =options.property2
				, entityId = item
				, noref =options.noref 
				,rank=options.rank
				,pattern =options.property2pattern
				,size =options.size
				,image =options.image
				,propertyimage =options.property3
				,firstvalue ='true'
				})
			if itemValue and itemValue  ~= '' then
				if caca and caca  ~= '' then 
					return {value =  caca .. ' '.. itemValue  } 
				else 
					return {value = itemValue  } 
				end
			end
		end 
	------------------------------
	elseif options.cateforjop and options.cateforjop ~= '' then
		for i, statement in pairs( datavalue ) do
			local caca = formatStatements(
				{property =options.cateforjop
				,entityId = item
				,noref ='true'
				,rank=options.rank
				,pattern =options.pattern
				,size =options.size
				,image =options.image
				,propertyimage =options.cateforjop1
				,firstvalue ='true' 
				,formattingpropertyimage=options.formattingcateforjop
				,nolink=options.nolink
				})
			if caca and caca  ~= '' then
				return {value =  caca }
			else 
			end
		end 
	------------------------------
	else
		return {value = formatEntityId( item, options ).value, item = item}		
	end 
end

 --[[ datatype  wikibase-property   ]]
 
function formatwikibaseproperty( datavalue, datatype, options )
	if options.formatting and options.formatting  ~= '' 
		then
			if options.formatting == 'raw' then 
				tid = getEntityIdFromValue( datavalue.value )
				else
			end
		else 
		tid =  formatEntityId( getEntityIdFromValue( datavalue.value ), options ).value
	end
	return {value = tid}
end

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

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

 --[[  commonsMedia ]]
 
function formatcommonsMedia( datavalue, datatype, options )
	if options.image and options.image ~= '' then
		tid = '[[file:' .. datavalue.value  .. '|'.. (options.size or '120')..'px|'..'border'..']]'
	else
		tid = formatcharacters(datavalue.value, options)--, label = datavalue.value}
	end
	return {value = tid}
end

 --[[ datatype math ]]
 
function formatmath( datavalue, datatype, options )
		 --return	{value = mw.text.tag('math', {}, ''.. datavalue.value..'') }
		 return	{value =mw.getCurrentFrame():callParserFunction( '#tag:math', ''.. datavalue.value..'' ) }
end

 --[[ datatype  string  -  external-id ]]
 
 function formatstring( datavalue, datatype, options )
        if options.pattern and options.pattern ~= '' then
        		local patter = formatStatements( {property = "P1630", entityId = options.property, firstvalue = 'true', noref = 'true',rank='all' }) -- get formatter URL
        		local ppp = formatFromPattern( datavalue.value, {pattern = patter} )
        		local plabel = mw.wikibase.label( options.property ) or ppp 
        	if options.pattern ==  "autourl" then -- like http://example.com/$1.html
        		 tid =  ppp
        	elseif options.pattern ==  "autourl2" then  -- like [http://example.com/$1.html $1]
        		 tid =  '[' .. ppp .. ' ' .. datavalue.value .. ']' 
        	elseif options.pattern ==  "autourl3"  then  -- like [http://example.com/$1.html http://example.com/$1.html]
        		 tid =  '[' .. ppp .. ' ' .. ppp .. ']' 
        	elseif options.pattern == "autourl4"  then
        		 tid =  '[' .. ppp .. ' ' .. plabel .. ']' 
        	else
            	 tid =  formatFromPattern( formatcharacters(datavalue.value, options), options )
            end
        else
             tid =  formatcharacters(datavalue.value, options)
        end
	return {value = tid}	
end
 --[[ datatype  time]]
function formattime( datavalue, datatype, options )
        local ModuleTime = require 'Module:wikidata2/time'
        local timen = datavalue.value 
        local modifytime = (options.modifytime or '')
        local tid = ModuleTime.getdate( timen , options)
       -- local tid =  mw.getCurrentFrame():preprocess(mall)
        if options.modifytime and 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
--[[ datatype  globe-coordinate]] 
function formatcoordinate( datavalue, datatype, options )
	--local GlobeCoordinate = require 'Module:GlobeCoordinate'
	--return {value = GlobeCoordinate.newFromWikidataValue( datavalue.value ):toHtml()}
	local coord = datavalue.value
	local globe = datavalue.value.globe
	local globe2 =  require('Module:Wikidata2/Globes')[globe]
	if options.formatting  and options.formatting  ~= '' then
		if options.formatting == 'latitude' then
			pro =coord.latitude 
		elseif options.formatting == 'longitude' then 
			pro =coord.longitude 
		elseif options.formatting == 'dimension' then 
			pro =coord.dimension  
		elseif options.formatting == 'precision' then 
			pro =coord.precision 
		elseif options.formatting == 'globe' then 
			pro = globe:match('Q%d+') 
		elseif options.formatting == 'globe2' then 
			pro = globe2 
		--elseif options.formatting == 'coord' then
			--return {value = }
		else
		end
	else
		pro =
			mw.getCurrentFrame():expandTemplate{ title = "coord"
			, args = {
				coord.latitude,
				coord.longitude,
				display=inline
				}
			} .. catewikidatainfo(options)
	end
	return {value = pro }
end
 --[[ datatype quantity]] 
function formatquantity( datavalue, datatype, options )
	local amount, unit, cat = datavalue.value.amount, datavalue.value.unit, nil
	amount = mw.ustring.gsub( amount , '+', '' )
	if unit then
		unit = unit:match('Q%d+')
	end
	local number = formatera.newFromWikidataValue(datavalue.value)

	local unitraw = unit
	if unit then
		-- يتحقق اذا كان هناك اي اختصار لوحدة القياس
		local lab = options.label 
		--or formatStatements({property = 'P498', entityId = unit, firstvalue = 'true', noref = 'true'}) 
		or formatStatements({property = 'P5061', entityId = unit, firstvalue = 'true', noref = 'true' , langpref = "ckb"}) or ""
		if lab and ( not options.nounitshort or options.nounitshort == '' )  then
			local s = formatEntityId( unit, {label = lab, nolink = (options.nounitlink or options.nolink) })
			unit = s.value
			cat = s.cat
		else -- om det inte finns en f?rkortning
			local s = formatEntityId( unit, {nolink = options.nounitlink})
			unit = s.value
			cat = s.cat
		end
	end
	if options.formatcharacters and options.formatcharacters =="formatnum" then
		amount = make_format_num( amount )
	end
	local Value = amount  .. ' ' .. (unit or '')
	if options.nounit and options.nounit ~= "" then
		Value = amount
	end
	return {value = Value , amount = amount, unit = unit, unitraw = unitraw, cat = cat}
		
end

 --[[ datatype  url ]]  
function formaturl( datavalue, datatype, options )
	local label = options.label
	if options.urllabel and options.urllabel  ~= '' then
		label = options.urllabel     
	end
	va =  mw.ustring.gsub( datavalue.value, ' ', '_' )
	--if not label and options.property =='P856' then label = 'الموقع الرسمي' end
		if label and label ~= '' then
		pro = '[' .. va .. ' ' .. label .. ']' 
		else
		--	if property =='P856' then 	pro =  formatFromPattern( formatcharacters(va, options), {pattern = '[$1 الموقع الرسمي]'} )
			--	else
					pro = va
		--		end
		end
	return {value = pro }
end

 --[[ datatype   monolingualtext ]] 
function formatmonolingualtext( datavalue, datatype, options )
	local langcode = datavalue.value.language
		local lang = mw.language.fetchLanguageName( langcode, 'ckb'  )
		local text = datavalue.value.text --mw.text.tag('span', {title = lang }, datavalue.value.text)

		if options.showlang and options.showlang ~= '' then
			text = text ..  ' ('.. lang ..')'
		end
			if options.langpref and options.langpref ~= '' then
				if options.langpref == datavalue.value.language then return  {value =text} 
					elseif options.langpref =='justlang' then return  {value =lang}  
					elseif options.langpref =='langcode' then return  {value =langcode}
				end
			else 
				return  {value =text}
			end
			
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 formatters
 		if datatype == 'wikibase-item' then return   formatwikibaseitem( datavalue, datatype, options ) 
 	elseif datatype == 'wikibase-property' then return   formatwikibaseproperty( datavalue, datatype, options)
 	elseif datatype == 'commonsMedia' then return   formatcommonsMedia( datavalue, datatype, options)
 	elseif datatype == 'math' then return       formatmath( datavalue, datatype, options )
 	elseif datatype == 'time' then return formattime( datavalue, datatype, options )
 	elseif datatype == 'external-id' then return  formatexternalid( datavalue, datatype, options )
 	elseif datatype == 'string' then return  formatstring( datavalue, datatype, options )
 	elseif datatype == 'globe-coordinate' then return  formatcoordinate( datavalue, datatype, options )
 	elseif datatype == 'quantity' then return   formatquantity( datavalue, datatype, options )
 	elseif datatype == 'url' then return   formaturl( datavalue, datatype, options )
 	elseif datatype == 'monolingualtext' then return  formatmonolingualtext( datavalue, datatype, options )
 	elseif datatype == 'geo-shape' then return formatgeoshape( datavalue, datatype, options )
 	elseif datatype == 'tabular-data' then return formattabulardata( datavalue, datatype, options )
    else
        return {value = formatError( 'unknown-datatype' )}
    end
end

function formatEntityId( entityId, options )
	local label = options.label or mw.wikibase.label( entityId )
	if label == '' then
		label = mw.wikibase.label( entityId ) or nil
	end
    local link = mw.wikibase.sitelink( entityId )
    if link and (not options.nolink or options.nolink == '') then
        if label and label ~= '' then
        	if link == formatcharacters(label, options) then 
        	    return {value = '[[' .. link .. ']]'.. catewikidatainfo(options), label = label }
        	else
        	    return {value = '[[' .. link .. '|' .. formatcharacters(label, options) .. ']]'.. catewikidatainfo(options), label = label }
        	end
        else
        	if link == formatcharacters(link, options) then 
        	    return {value = '[[' .. link .. ']]'.. catewikidatainfo(options), label = link }
        	else
        	    return {value = '[[' .. link .. '|' .. formatcharacters(link, options) .. ']]'.. catewikidatainfo(options), label = link }
        	end
        	  --return {value = '[[' .. link .. '|' .. formatcharacters(link, options) .. ']]'.. catewikidatainfo(options), label = link }
        end
    else
    	if label and label ~= '' 
    		then
    		local label3 = Labelfunction( entityId, label,options.label, options)
    		return {value = label3 , label = label}
    	else return ''

    	end
    	return '' --{value = entityId, cat = 'som har labels med Qid', label = entityId}
    end
end
 --[[ function to get any link from any sister project]] 
function sitelink( id , wikisite )
	if not mw.wikibase then return '' end
	local site = wikisite or 'ckbwiki'
	local link = mw.wikibase.sitelink( id , site ) or ""
	mw.log("mw.wikibase.sitelink,site: " .. site.. ",link:" .. link )
	return link
end

function sitelink_s( id , wikisite )
	if not mw.wikibase then return '' end
	local site = wikisite
	if not site or site == "" then site = "ckbwiki" end
	local link = "" --mw.wikibase.sitelink( id , site )
	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
				--mw.log("mw.wikibase.getEntityObject : " .. link)
			end
		end
	--mw.log("mw.wikibase.sitelink," .. "site: " .. site .. ": " .. link)
	return link
end

 --[[ function to get only the value with link]] 
function formatsitelink( entityId, options )
    local label = labelIn('ckb',entityId )
	if options.label and options.label ~= "" then
		label = options.label
	end
    local link = mw.wikibase.sitelink( entityId )
	if link and link ~= ''  
		then
			if label and label ~= ''  
				then
					return '[[' .. link .. '|'.. label .. ']]'
				else
					return '[[' .. link .. ']]'
			end
		else 
			--if link and link ~= ''  then
			--	return formatcharacters(link, options)
			--end
	end
end

function formatsitelink1( entityId, options )
    local link = mw.wikibase.sitelink( entityId )
	if link and link ~= ''  
		then
			if options.nolink and options.nolink ~= ''  
				then
					return  link 
				else
					return '[[' .. link .. ']]'
			end

	end
end

 --[[ function to replace $1 with string ]] 
function formatFromPattern( str, options )
	--if options.pattern and options.pattern ~='' then
			mw.log( str .. ':' .. options.pattern )
			return mw.ustring.gsub( options.pattern, '$1', str )  --الحصول على اول نتيجة للدالة
	--	else return str
	--end
end

function addTrackingCategory(prop,options)
	--local cat =  require('Module:Wikidata/تتبع').makecategory1
	--local category =  cat(options)
	--if prop and prop ~= '' then
		--if category and category ~= '' then
			--return prop .. '  ' .. category
		--else 
			--return prop .. '  ' 
		--end
	--end
	return prop
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
	 	if not mw.wikibase then return false end
	local entity = mw.wikibase.getEntity(pItem)
	if not entity then return false end
	local claims31
	local claims279
	if entity.claims then 
		if property and property ~= '' then
			claims31 = entity.claims[mw.wikibase.resolvePropertyId(property)] 
		else
			claims31 = entity.claims[mw.wikibase.resolvePropertyId('P31')] 
			claims279 = entity.claims[mw.wikibase.resolvePropertyId('P279')] 
		end
	else
		return false
	end
		function getSnakValue(snak)
		if snak.snaktype == "value" then
			if snak.datavalue.type == "wikibase-entityid" then 
				data = "Q" .. snak.datavalue.value['numeric-id']
				return data
			end
		end
		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] = getSnakValue(v.mainsnak) end
		end
		if claims279 and #claims279 > 0 then
			for i, v in ipairs(claims279) do parentIds[#parentIds+1] = getSnakValue(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 isSubclass(options)
	if not options.parent then return false end
	local maxDepth
	maxDepth = tonumber(options.maxDepth) or 10
	if not type(maxDepth) == "number" then maxDepth = 5 end
	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

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

function formatEntityId2( entityId, options )
	local label = options.label or mw.wikibase.label( entityId )
	if label == '' then
		label = mw.wikibase.label( entityId ) or nil
	end
	
    local link = mw.wikibase.sitelink( entityId )

    if link and (not options.nolink or options.nolink == '') then
        if label and label ~= '' then
            return {value = '[[' .. link .. '|' .. formatcharacters(label, options) .. ']]'.. catewikidatainfo(options), label = label }
        else
            return {value = '[[' .. formatcharacters(link, options) .. ']]'.. catewikidatainfo(options), label = link }
        end
    else
    	if label then
    		return {value = formatcharacters(label, options), label = label}
    	else return ''

    	end
    	return '' --{value = entityId, cat = 'som har labels med Qid', label = entityId}
    end
end

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

function p.formatStatements( frame, key )
    local args = frame.args
    --If a value if already set, use it
    if args.value and args.value ~= '' then
        return args.value
    end
    local prop = formatStatements( frame.args, key )
	if prop and prop ~= '' then
    	if args.mainprefix and args.mainprefix ~= '' then -- mainprefix
    		prop = args.mainprefix .. " " .. prop
    	end
    	if args.mainsuffix and args.mainsuffix ~= '' then  -- mainsuffix
    		prop = prop .. " " .. args.mainsuffix
    	end
		if args.mainsuffixAfterIcon and args.mainsuffixAfterIcon ~= '' then   -- another suffix but after wikidata icon
		prop =  prop .. args.mainsuffixAfterIcon 
		end
	else 
    	if args.NoPropValue and args.NoPropValue ~= '' then -- value if no local value and no wikidata value  
    		prop = args.NoPropValue
    	end
	end
    return prop
end
 
function p.formatStatementsFromLua( options, key ) --  main function but to use from lua module
    --If a value if already set, use it
    if options.value and options.value ~= '' then
        return options.value
    end
    local s = formatStatements( options, key )
    if s == '' then
    	s = nil
    end
	if options.addTrackingCat and options.addTrackingCat ~= '' then   -- add tracking cat
		s=  addTrackingCategory(s,options)
	end
    return s
end
 
function p.isSubclass(frame)
	return isSubclass(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 )
	if not mw.wikibase then return '' end
	Frame = 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 not id or id == "" then
		if frame.args.page and frame.args.page ~= "" then
			id = mw.wikibase.getEntityIdForTitle( frame.args.page )
		end
	end
	if count and count ~= "" then 
		return countSiteLinks(id)
	end
    local link = sitelink( id , site )
    if link and link ~= ''  then
        return link
	end
end

-- returns the page id (Q...) of the current page or nothing of the page is not connected to Wikidata
function p.pageId(frame)
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil else return entity.id end
end

function p.descriptionIn(frame)
	local langcode = frame.args[1]
	local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration

	return descriptionIn( langcode ,id  )
end

function p.labelIn(frame)
	local langcode = frame.args[1]
	local id = frame.args[2] -- "id" must be nil, as access to other Wikidata objects is disabled in Mediawiki configuration

	return labelIn( langcode ,id  )
end

function p.ViewSomething(frame)   -- from en:Module:Wikidata
	local f = (frame.args[1] or frame.args.id) and frame or frame:getParent()
          if f.args.id and f.args.id ~='' then aa = f.args.id end
	local data = mw.wikibase.getEntityObject(aa)
	if not data then
		return nil
	end
	local i = 1
	while true do
		local index = f.args[i]
		if not index 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 not data 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()
          if f.args.id and f.args.id ~='' then aa = f.args.id end
	local data = mw.wikibase.getEntityObject(aa)
	if not data then
		return i18n.warnDump
	end
	local i = 1
	while true do
		local index = f.args[i]
		if not index then
			return frame:extensionTag("source", mw.dumpObject(data),{ lang= 'lua'}).. i18n.warnDump
		end
		data = data[index] or data[tonumber(index)]
		if not data then
			return i18n.warnDump
		end
		i = i + 1
	end
end

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

return p