Module:Tests

La bibliothèque libre.
Aller à : navigation, rechercher
Documentation du module Documentation du module[voir] [modifier] [purger]
La documentation de ce module est incluse depuis sa sous-page de documentation.

Test datas.get_item() docs[modifier]

Test mode dats[modifier]

{{#invoke:Tests|dats}} Erreur Lua à la ligne 1628 : attempt to index field 'item' (a nil value).

Test mode edit[modifier]

{{#invoke:Tests|edit}} Erreur Lua à la ligne 308 : attempt to index field 'prop' (a nil value).

Test mode read[modifier]

{{#invoke:Tests|read}} Erreur Lua à la ligne 1242 : attempt to call method 'getLabel' (a nil value).

Test mode tests[modifier]

{{#invoke:Tests|tests}}

  • datas.get_datas(p.args_known, QITEM)
  • , datas.prop.QITEM = nil
  • , datas.prop.description = nil
  • , datas.prop.label = nil
  • , datas.prop.image = nil
  • , datas.prop.P18 = nil

Test MediawikiVersion docs[modifier]

Test MediawikiVersion[modifier]

{{#invoke:MediawikiVersion|read}} 1.31.0-wmf.29 (1cb7198)

local p = {} -- Test of Module:Author3

p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module.
	versionName = "Author3", versionNumber = "180108.0649", versionDate = "2018-01-08 06:49", -- UTC
	sought = "Central-s-fr;Central", -- Sought module and submodules versions
	known = "Central-s-fr;Central", -- Known module and submodules versions
}

local Alert = "The function item:getLabel() return nil if the page is not in the dedicated namespace or if the page title is unknown in the wikibase."
-- local Infos = datas.query_datas(args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.

datas			= {} -- "The Library:datas form some viewers for tables(in lines and columns), dropboxes, luatables..."
lua_table		= {} -- "The Library:lua_table enhances previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table."
viewer			= {} -- "The Library:viewer form tableviews as objects inside the Library:viewer"
langs			= {} -- "The Library:langs supports i18n translations."

-- Central values for langs
langs.content_lang	= "fr"
langs.page_lang		= "es"
langs.user_lang		= "en"
local lang = lang or langs.user_lang or "en"

-- Usefull functions examples
--	datas.entity:getBestStatements('P570')
--	local value = mw.wikibase.entity:getProperty('P569', 1, lang, , , ) -- for item['claims']['P342'][1]['qualifiers']['P342'][1]
--	local snak = datas.item['claims']['P342'][1]['qualifiers']['P342'][1]
--	local snak = datas.item['claims'][prop][1]['qualifiers'][prop][1]

local central_libraries = { -- New libraries to record in package.loaded[]
	{ "activity",	"The Library:activity supports the management of Lua coders sub-tasks and inter-wikis central modules.", },
	{ "datas",		"The Library:datas form some viewers for tables(in lines and columns), dropboxes, luatables...", },
	{ "events",		"The Library:events form events like erros, warnings and categories.", },
	{ "langs",		"The Library:langs supports i18n translations.", },
	{ "lua_table",	"The Library:lua_table enhances previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table.", },
	{ "mathroman",	"The Library:mathroman convert roman numbers and detect errors. It is here as an example of very small central library.", },
	{ "modes",		"The Library:modes support modes and their options, like p.read(frame).", },
	{ "testsgrp",	"The Library:testsgrp, initialises, runs and forms groups of tests for Mediawiki and users.", },
	{ "viewer",		"The Library:viewer form tableviews as objects inside the Library:viewer", },
	{ "versn",		"The Library:versn installs all central libraries, modules and their i18n translations. It also support versions management.", },
	-- Objects have a function object.new() to form several objects.
	{ "args",		"The Object:args form known arguments to import, complete from datas and finalize.", },
	{ "boxview",	"The Object:boxview, in the Library:viewer, forms boxes, their styles and structures.", },
	{ "dropbox",	"The Object:dropbox, in the Library:viewer, forms dropboxes and their styles.", },
	{ "centrobj",	"The Object:centrobj, in the Library:versn, forms the basis of libraries and their properties.", },
	{ "tableview",	"The Object:tableview, in the Library:viewer, forms some viewers for tables, in lines and columns.", },
	{ "tracker",	"The Object:tracker, in the Library:activity, forms parametrables tracks to help to debug the code.", },
}

p.args_known = { -- Table of the definitions of all known arguments at module level.
	-- Arguments in order without names, with their keyword for use as other arguments.
--	[1]					= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "mode", ["syn"] = 2},
	
	-- Special arguments to modify the fonctions and outputs of this module.
	["mode"]			= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "mode"},
	["c"]				= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "c"},
	["options"]			= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "options"},

	["contentlang"]		= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "contentlang"},
	["pagelang"]		= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "pagelang"},
	["userlang"]		= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "userlang"},

	["knownversions"]	= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "knownversions"},
	["soughtversions"]	= { ["typ"] = "config",	["need"] = 0,	["keyword"] = "soughtversions"},
	["debug"]			= { ["typ"] = "opt",	["need"] = 0,	["keyword"] = "debug"},
	["category"]		= { ["typ"] = "ctr",	["need"] = 0,	["keyword"] = "category"},

	-- All arguments have a keyword identical to the registration name, except synonyms.
	["image"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "image",		["prop"] = "P18", },
	["country"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "country",	["prop"] = "P27", },
	["birthyear"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "birthyear",	["prop"] = "P569", ["format"] = "year", },
	["deathyear"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "deathyear",	["prop"] = "P570", ["format"] = "year", },
	["lastname"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", },
	["lastname2"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", ["syn"] = 2, },
	["firstname"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "firstname",	["prop"] = "P735", },
	["firstname2"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "firstname",	["prop"] = "P735", ["syn"] = 2, },
	["initial"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "initial",	["prop"] = "P735", },
	["title"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "title",		["prop"] = "P735", },
	["personlang"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "personlang",	["prop"] = "P1412", },
	["QITEM"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "QITEM",		["prop"] = "Q16222597", },
	["itemid"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "QITEM",		["prop"] = "Q16222597", ["syn"] = 2, },
	["label"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "label" ,		["prop"] = "label", },
	["sitelink"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "sitelink",	["prop"] = "sitelink", },
	["description"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "description",["prop"] = "description", },
	
	["sex"]				= {["keyword"] = "sex", ["typ"] = "dat",	["need"] = 0, ["prop"] = "P21",
		["arg_values"] = "sex_values",	  ["key_values"] = "male;femelle", }, -- values_selectors
	["region"]			= {["keyword"] = "region", ["typ"] = "dat",	["need"] = 0,
		["arg_values"] = "region_values", ["key_values"] = "other;china;india;century" }, -- values_selectors
	["rights"]			= {["keyword"] = "rights", ["typ"] = "dat",	["need"] = 2,
		["arg_values"] = "rights_values", ["key_values"] = "no;none;ONU;none;cn;50;us;70;mpf", -- values_selectors
		["delay_values"] = "0;0;0;0;50;50;70;70;95", ["arg_uses"] = "none;none;none;none;cn;cn;us;us;mpf" }, -- values_selectors
} -- #p.args_known = 29 on 2018-01-15

------------------------------------------------------------------------------------------------
--	Begin of compact Module:Auteur2  2016-12-14T19:18:29‎ Tpt20180122 0715.lua
------------------------------------------------------------------------------------------------

function errorMessage(text)
	-- Return a html formated version of text stylized as an error.
	local html = mw.html.create('div')
	html:addClass('error')
		:wikitext(text)
		:wikitext('[[Catégorie:Pages faisant un appel erroné au modèle Auteur]]')
	return tostring(html)
end

function categorization(baseName, parameter)
	-- Return the categorisation wikitext for each element of parameter prefixed with baseName
	if parameter == nil then return '' end
	local wikitext = ''
	for _,param in pairs(mw.text.split(parameter, '/', true)) do
		wikitext = wikitext .. '[[Catégorie:' .. baseName .. ' ' .. param .. ']]'
	end
	return wikitext
end

function computeCenturyFromYear(year)
	-- Return the correpsonding century for the given year
	if year >= 0 then	return math.ceil(year / 100)
	else				return -math.ceil(-year / 100)
	end
end

function getTextForCentury(century, withHtml)
	-- Return a roman ordinal of century appended with a trailing text precising
	-- if the date is before of after the calendar reference point.
	local romanNumbers1 = {'', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'}
	local romanNumbers2 = {'', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'}
	local text = romanNumbers2[math.floor(math.abs(century) / 10) + 1] .. romanNumbers1[math.floor(math.abs(century) % 10) + 1]
	if withHtml then text = text .. '<sup>e</sup>'
	else text = text .. 'e'	end
	if century > 0 then return text .. ' siècle'
	else return text .. ' siècle av. J.-C.' end
end

function getTextForYear(year)
	local text = math.abs(year)
	if year < 0 then text = text .. ' av. J.-C.' end
	return text
end

function getDateFromArgs(args, field, fieldUpper)
	local struct = {
		year = nil,
		century = nil,
		text = nil,
		precision = 0
	}
	--extract year or century
	local date = args['annee' .. fieldUpper]
	if date == nil then date = args[field] end
	if tonumber(date) ~= nil then
		struct.year = tonumber(date)
		if struct.year == 0 then
			struct.text = errorMessage("Le calendrier grégorien ne possède pas d’année 0 !")
			return struct
		end
		struct.century = computeCenturyFromYear(struct.year)
		struct.precision = 9
	elseif args['siecle' .. fieldUpper] ~= nil then
		struct.century = tonumber(args['siecle' .. fieldUpper])
		struct.precision = 7
	end
	--build text
	if struct.year ~= nil then
		struct.text = getTextForYear(struct.year)
	elseif struct.century ~= nil then
		struct.text = getTextForCentury(struct.century, true)
	else
		struct.text = date
	end
	if args['text' .. fieldUpper] ~= nil then
		struct.precision = 0 --we don't know anything
		struct.text = args['text' .. fieldUpper] .. ' ' .. struct.text
	end
	if args['incertitude' .. fieldUpper] ~= nil and struct.text ~= nil then
		struct.precision = 0 --we don't know anything
		struct.text = args['incertitude' .. fieldUpper] .. ' ' .. struct.text
	end
	return struct
end

function getDateFromTimeStatements(statements, field)
	if #statements == 0 then return { precision = 0 } end
	local time = nil
	for _, statement in pairs(statements) do
		local newTime = getDateFromTimeStatement(statement, field)
		if time == nil then time = newTime
		elseif time.year ~= newTime.year then --années contradictoires
			return {
				text = errorMessage('Plusieurs années de ' .. field .. ' possibles sur Wikidata. Une manière simple de résoudre se problème est de mettre la date à afficher au rang "préféré".'),
				precision = 0
			}
		end
	end
	if time == nil then return { precision = 0 } end
	return time
end

function parseWbTime(value)
	local _,_, year = string.find(value.time, '([%+%-]%d%d%d+)%-')
	year = tonumber(year)
	return {
		year = year,
		century = computeCenturyFromYear(year),
		text = nil,
		precision = value.precision
	}
end

function getDateFromTimeStatement(statement, field)
	local struct = {
		year = nil,
		century = nil,
		text = nil,
		precision = 0
	}
	local snak = statement.mainsnak
	if snak.snaktype == 'novalue' then return struct end
	if snak.snaktype == 'somevalue' then struct.text = '??' ; return struct end
	struct = parseWbTime(snak.datavalue.value)
	local prefix = ''
	if struct.precision == 8 then prefix = 'vers ' end
	--Extract circa
	if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
		for _,qualifier in pairs(statement.qualifiers.P1480) do
			if qualifier.datavalue.value.id == 'Q5727902' then
				prefix = 'circa '
				struct.precision = 8 --TODO: hacky
			end
		end
	end
	--Use before and after if precision <= century
	if statement.qualifiers ~= nil and struct.precision <= 7 then
		if statement.qualifiers.P1319 ~= nil then
			for _,qualifier in pairs(statement.qualifiers.P1319) do
				struct = parseWbTime(qualifier.datavalue.value)
				prefix = 'après '
				struct.precision = 8 --TODO: hacky
			end
		elseif statement.qualifiers.P1326 ~= nil then
			for _,qualifier in pairs(statement.qualifiers.P1326) do
				struct = parseWbTime(qualifier.datavalue.value)
				prefix = 'avant '
				struct.precision = 8 --TODO: hacky
			end
		elseif statement.qualifiers.P1317 ~= nil then
			for _,qualifier in pairs(statement.qualifiers.P1317) do
				struct = parseWbTime(qualifier.datavalue.value)
				prefix = 'floruit '
				struct.precision = 8 --TODO: hacky
			end
		end
	end
	--Create text
	if struct.precision >= 9 then
		struct.text = prefix .. getTextForYear(struct.year)
	elseif struct.precision == 8 then
		struct.text = prefix .. getTextForYear(struct.year)
	elseif struct.precision == 7 then
		struct.text = prefix .. getTextForCentury(struct.century, true)
	else
		struct.text = errorMessage('La date de ' .. field .. ' a une précision trop faible sur Wikidata')
	end
	return struct
end

function formatDates(naissance, deces)
	if naissance.text == nil and deces.text == nil then return '' end
	local text = '('
	if naissance.precision >= 9 then
		text = text .. '<time datetime=' .. naissance.year .. ' class="bday" itemprop="birthDate">' .. naissance.text .. '</time> '
	elseif naissance.text ~= nil then
		text = text .. naissance.text .. ' '
	end
	text = text .. '–'
	if deces.precision >= 9 then
		text = text .. ' <time datetime=' .. deces.year .. '  class="dday" itemprop="deathDate">' .. deces.text .. '</time>'
	elseif deces.text ~= nil then
		text = text .. ' ' .. deces.text
	end
	return text .. ')'
end

function qidForProperty(item, property)
	local statements = item:getBestStatements(property)
	if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
		return statements[1].mainsnak.datavalue.value.id
	end
	return nil
end

function searchKey(key)
	-- normally the key does not contain any diacritic but it's a common misuse
	-- of the clef = so handle at least the most usual diacritics, note than
	-- prenom can be empty
	local nom, prenom = string.match(key, '^([A-ZÉÈÀÇa-zéèàç-]*)[,]?[ ]*(.*)$')
	return prenom .. ' ' .. 'intitle:' .. nom
end

function datas.ModuleAuteur2_20161214() -- From Tpt on 2016-12-14 in ModuleAuteur2 20161214.lua
--	function main(frame) -- From Tpt on 2016-12-14 in ModuleAuteur2 20161214.lua
	--create a clean table of parameters with blank parameters removed
	item = datas.item
	local t = "\n* function main(frame) -- From Tpt on 2016-12-14 in ModuleAuteur2 20161214.lua"
	local args = {}
--	datas.prop.Label = datas.item:getLabel() -- add_err()+add_cat() Only in a dedicated namespace and if datas exist
	args.nom = datas.prop.Label or "Aristote"
	for k,v in pairs(datas.frame:getParent().args) do
		if v ~= '' then
			args[k] = v
		end
	end
	t = t .. viewer.ta("\n* 920: main(frame) args.nom", args.nom)
	local naissance = getDateFromArgs(args, 'naissance', 'Naissance')
	local deces = getDateFromArgs(args, 'deces', 'Deces')
	local sexe = nil
	local html = mw.html.create()

	--Utilise Wikidata si paramètres non renseignés
	local item = mw.wikibase.getEntity()
	if item == nil then
		html:wikitext('[[Catégorie:Pages « Auteur » sans élément sur Wikidata]]')
	else
		if args.nom == nil then
			args.nom = item:getLabel() -- or "Victor Hugo"
		else
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un nom local]]')
		end
		if args.description ~= nil then
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une description locale]]')
		elseif item.descriptions ~= nil and item.descriptions.fr ~= nil then
			args.description = item.descriptions.fr.value
			if item.descriptions.fr.language ~= 'fr' then
				args.descriptionLanguageCode = item.descriptions.fr.language
			end
		end
		if args.image == nil then
			local statements = item:getBestStatements('P18')
			if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
				args.image = statements[1].mainsnak.datavalue.value
			end
		else 
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une image locale]]')
		end
		local naissanceWikidata = getDateFromTimeStatements(item:getBestStatements('P569'), 'naissance')
		if naissance.text == nil then
			naissance = naissanceWikidata
		else
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une date locale]]')
			if naissanceWikidata.text == nil then
				html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]')
			end
		end
		local decesWikidata = getDateFromTimeStatements(item:getBestStatements('P570'), 'deces')
		if deces.text == nil then
			deces = decesWikidata
		else
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une date locale]]')
			if decesWikidata.text == nil then
				html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]')
			end
		end
		if args.pseudo == nil then
			args.pseudo = item:formatPropertyValues( 'P742' ).value
			if args.pseudo == '' then
				args.pseudo = nil
			end
		elseif args.pseudo ~= '-' then
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un pseudo local]]')
		end
		--sexe
		sexe = qidForProperty(item, 'P21')
	end

	if args.nom == nil then
		return errorMessage('Le paramètre « nom » est obligatoire et doit contenir le nom de l’auteur')
	end

	--sort key and initiale
	local firstName = ''
	local familyName = ''
	if item ~= nil then
		--first name
		local firstNameStatements = item:getBestStatements('P735')
		if firstNameStatements[1] ~= nil then
			if firstNameStatements[1].mainsnak.type == 'value' then
				local firstNameId = firstNameStatements[1].mainsnak.datavalue.value.id
				firstName = mw.wikibase.label(firstNameId) or ''
				--TODO check if the first name is not an initial
			elseif firstNameStatements[1].mainsnak.type == 'somevalue' then
				html:wikitext('[[Catégorie:Auteurs de prénom inconnu]]')
			end
		end
		--family name
		local familyNameId = qidForProperty(item, 'P734')
		if familyNameId ~= nil then
			familyName = mw.wikibase.label(familyNameId) or ''
		end
	end
	if familyName == '' then
		--We are in a simple case with first name and last name. TODO: bad hack, should be improved
		local nameParts = mw.text.split(args.nom, ' ', true)
		if #nameParts == 1 then
			familyName = nameParts[1]
		elseif #nameParts == 2 then
			firstName = nameParts[1]
			familyName = nameParts[2]
		end
	end
	if args.cle == nil then
		if familyName ~= '' then
			local moduleClassement = require 'Module:Classement'
			args.cle = moduleClassement.getSortKeyForName({args = {firstName, familyName}})
		else
			return errorMessage('Le paramètre « cle » est obligatoire et doit contenir une clé de tri pour l’auteur')
		end
	else 
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une clé locale]]')
	end

	if args.initiale == nil then
		if args.cle ~= nil then
			args.initiale = string.sub(args.cle, 1, 1)
		else
			return errorMessage('Le paramètre « initiale » est obligatoire et doit contenir l’initiale du nom de l’auteur en majuscule non accentuée')
		end
	else
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]')
	end

	local main = html:tag('div')
		:addClass('vcard')
		:attr('itemscope', '')
		:attr('itemtype', 'http://schema.org/Person')
		:css({['background-color'] = '#F1F1DE', ['overflow'] = 'auto', ['border-radius'] = '0.7em', ['box-shadow'] = '0.2em 0.3em 0.2em #B7B7B7'})

	if item ~= nil and item.id ~= nil then
		main:attr('itemid', 'http://www.wikidata.org/entity/' .. item.id)
	end
	
	--Image
	local image = args.image
	if image == nil then
		local defaultImages = {'Silver - replace this image male.svg', 'Silver - replace this image female.svg'}
		if sexe == 'Q6581097' then
			image = defaultImages[1]
		elseif sexe == 'Q6581072' then
			image = defaultImages[2]
		else
			image = defaultImages[math.random(#defaultImages)]
		end
	end
	main:tag('div')
		:css({['float'] = 'right', ['margin'] = '1em'})
		:wikitext('[[Fichier:' .. image .. '|140px|alt=' .. args.nom .. '|class=photo|itemprop=image]]')

	--First row	
	local firstRow = main:tag('div')

		--Categorie Auteur-X
		firstRow:tag('div')
			:css({['float'] = 'left', ['font-size'] = '115%', ['text-indent'] = '1em'})
			:tag('span')
				:css('color', '#aaaa66')
				:wikitext('◄')
				:done()
			:wikitext('&nbsp;[[:Catégorie:Auteurs-' .. args.initiale .. '|Auteurs&nbsp;' .. args.initiale .. ']]')

		--Title
		firstRow:tag('h1')
			:addClass('fn')
			:attr('itemprop', 'name')
			:css({['text-align'] = 'center', ['font-size'] = '160%', ['font-weight'] = 'bold', ['border-bottom'] = 'none'})
			:wikitext(args.nom)
	
	--Second row
	local secondRow = main:tag('div')

		--Interwikis
		local interwikis = secondRow:tag('div')
			:css({['float'] = 'left', ['height'] = '50%', ['font-size'] = '75%', ['text-indent'] = '2em'})
			:node(createLinkRow('<span class="plainlinks">[//fr.wikisource.org/wiki/Spécial:IndexPages?key=' .. mw.uri.encode(searchKey(args.cle)) .. ' Fac-similés]</span>', 'Wikisource'))
			if item ~= nil and item:getSitelink('frwiki') ~= nil then
				interwikis:node(createLinkRow('[[w:' .. item:getSitelink('frwiki') .. '|Biographie]]', 'Wikipedia'))
			else
				interwikis:node(createLinkRow('[[w:' .. args.nom .. '|<span style="color:#BA0000;">Biographie</span>]]', 'Wikipedia'))
			end
			if item ~= nil and item:getSitelink('frwikiquote') ~= nil then
				interwikis:node(createLinkRow('[[q:' .. item:getSitelink('frwikiquote') .. '|Citations]]', 'Wikiquote'))
			else
				interwikis:node(createLinkRow('[[q:' .. args.nom .. '|<span style="color:#BA0000;">Citations</span>]]', 'Wikiquote'))
			end

			if item ~= nil then
				local commonsCat = item:formatPropertyValues('P373').value
				if commonsCat ~= '' then
					interwikis:node(createLinkRow('[[commons:Category:' .. commonsCat .. '|Médias]]', 'Commons'))
				elseif item:getSitelink('commonswiki') ~= nil then
					interwikis:node(createLinkRow('[[commons:' .. item:getSitelink('commonswiki') .. '|Médias]]', 'Commons'))
				else
					interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
				end
			else
				interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
			end

			if item ~= nil and item.id ~= nil then
				interwikis:node(createLinkRow('[[d:' .. item.id .. '|Données&nbsp;structurées]]', 'Wikidata'))
			else
				interwikis:node(createLinkRow('<span class="plainlinks">[//www.wikidata.org/w/index.php?title=Special:NewItem&site=frwikisource&page=' .. mw.uri.encode(mw.title.getCurrentTitle().fullText) .. '&label=' .. mw.uri.encode(args.nom) .. ' Données&nbsp;structurées</span>]</span>', 'Wikidata'))
			end

		--Description
		local fullDescription = secondRow:tag('div')
			:css({['text-align'] = 'center', ['font-size'] = '110%', ['line-height'] = '110%', ['padding'] = '1em'})
		local description = fullDescription:tag('span')
			:addClass('label')
			:attr('itemprop', 'description')
			:wikitext(args.description or '')
		if args.descriptionLanguageCode ~= nil then
			description:attr('lang', item.descriptions.fr.language)
				:css('font-style', 'italic')
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur sans description française]]')
		elseif args.description == nil then
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur sans description française]]')
		end
		fullDescription
			:newline()
			:wikitext(formatDates(naissance, deces))
		if args.pseudo ~= nil and args.pseudo ~= '-' then
			fullDescription:tag('br')
			fullDescription:wikitext('Pseudonyme : \'\'')
				:tag('span')
				:attr('itemprop', 'alternateName')
				:css('font-style', 'italic')
				:wikitext(args.pseudo)
		end

	--categories
	html:wikitext('[[Catégorie:Auteurs]]' .. '[[Catégorie:Auteurs-' .. args.initiale .. ']]')
	--genre
	if args.genre ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un genre local]]')
		html:wikitext(categorization('', args.genre))
	end
	html:wikitext(categorization('', args.genre))
	--langue
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P1412')) do
			if statement.mainsnak.datavalue ~= nil then
				categoryName = 'Catégorie:Auteurs écrivant en ' .. mw.wikibase.label(statement.mainsnak.datavalue.value.id)
				html:wikitext('[[' .. categoryName .. ']]')
				if not mw.title.new( categoryName ).exists then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une catégorie de langue non créée]]')
				end
			end
		end
	end
	if args.langue ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une langue locale]]')
	end
	--nationalités
	categoryForCountry = mw.loadData('Module:Auteur2/nationalités')
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P27')) do
			if statement.mainsnak.datavalue ~= nil then
				countryId = statement.mainsnak.datavalue.value.id
				if categoryForCountry[countryId] == nil then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une nationalité sans catégorie]]')
				elseif categoryForCountry[countryId] then
					html:wikitext('[[Category:' .. categoryForCountry[countryId] .. ']]')
				end
			end
		end
	end
	if args.pays ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une nationalité locale]]')
	end
	--occupation
	categoryForOccupation = mw.loadData('Module:Auteur2/occupations')
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P106')) do
			if statement.mainsnak.datavalue ~= nil then
				occupationId = statement.mainsnak.datavalue.value.id
				if categoryForOccupation[occupationId] == nil then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une occupation sans catégorie]]')
				elseif categoryForOccupation[occupationId] then
					html:wikitext('[[Category:' .. categoryForOccupation[occupationId] .. ']]')
				end
			end
		end
	end
	if args.metier ~= nil or args["métier"] ~= nil then
		html:wikitext(categorization('', args.metier or args["métier"]))
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une occupation locale]]')
	end
	--prix
	if args.prix ~= nil then
		html:wikitext(categorization('Lauréats du', args.prix))
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un prix local]]')
	end
	if item ~= nil then
		for _, awardStatement in pairs(item:getBestStatements('P166')) do
			if awardStatement.mainsnak.datavalue ~= nil then
				distinctionItem = mw.wikibase.getEntity(awardStatement.mainsnak.datavalue.value.id)
				for _, awardeeCatStatement in pairs(distinctionItem:getBestStatements('P2517')) do
					if awardeeCatStatement.mainsnak.datavalue ~= nil then
						wikisourceCategory = mw.wikibase.sitelink(awardeeCatStatement.mainsnak.datavalue.value.id)
						if wikisourceCategory then
							html:wikitext('[[' .. wikisourceCategory .. ']]')
						end
					end
				end
			end
		end
	end

	--categorie dates
	if naissance.precision >= 9 and naissance.year > 1500 then
		html:wikitext('[[Catégorie:Naissance en ' .. naissance.year .. ']]')
	end
	if deces.precision >= 9 and deces.year > 1500 then
		html:wikitext('[[Catégorie:Décès en ' .. deces.year .. ']]')
	end
	local withoutEpoque = true
	if naissance.century ~= nil and (naissance.precision < 9 or naissance.year <= naissance.century * 100 - 20) then
		if 15 <= naissance.century then
			html:wikitext('[[Catégorie:Auteurs du ' .. getTextForCentury(naissance.century, false) .. ']]')
		elseif 6 <= naissance.century and naissance.century <= 14 then
			html:wikitext('[[Catégorie:Auteurs du Moyen Âge]]')
		else
			html:wikitext('[[Catégorie:Auteurs de l’Antiquité]]')
		end
		withoutEpoque = false
	end
	if deces.century ~= nil and (deces.precision < 9 or (deces.century - 1) * 100 + 5 <= deces.year) then
		if 15 <= deces.century then
			html:wikitext('[[Catégorie:Auteurs du ' .. getTextForCentury(deces.century, false) .. ']]')
		elseif 6 <= deces.century and deces.century <= 14 then
			html:wikitext('[[Catégorie:Auteurs du Moyen Âge]]')
		else
			html:wikitext('[[Catégorie:Auteurs de l’Antiquité]]')
		end
		withoutEpoque = false
	end
	if withoutEpoque then
		html:wikitext('[[Catégorie:Epoque inconnue]]')
	end
	if sexe == 'Q6581072' then
		html:wikitext('[[Catégorie:Autrices]]')
	end

	--droits
	if args.droits == nil then
		args.droits = '70'
	end
	droitsNumber = tonumber(args.droits)
	if args.droits == 'mpf' then
		if deces.precision >= 9 and tonumber(os.date("%Y")) <= deces.year + 95 then --TODO: guess 'mpf' from P166:Q3324507 in Wikidata?
			html:wikitext(datas.frame:expandTemplate({title = 'Auteur Mort pour la France'}))
		end
		html:wikitext('[[Catégorie:Auteurs morts pour la France]]')
	elseif args.droits == 'non' then
		--rien à faire
	elseif droitsNumber ~= nil then
		if deces.year ~= nil and tonumber(os.date("%Y")) <= deces.year + droitsNumber then --XX ans on vérifie le DP-EU
			if naissance.year == nil or 1923 - naissance.year > 20 then
				html:wikitext(datas.frame:expandTemplate({title = 'DP-EU-Auteur'}))
			end
		end
		if args.droits ~= '70' then
			html:wikitext('[[Catégorie:Droits d’auteur ' .. args.droits .. ' ans]]')
		end
	else
		return errorMessage('Le paramètre droit contient une valeur non supportés. Valeurs possibles : 70/60/50 (durée du droit d\'auteur), "mpf" (mort pour la france). Par défaut: 70')
	end
	

	--maintenance
	if args.image == nil then
		html:wikitext('[[Catégorie:Pages « Auteur » sans image]]')
	end

	if args.cle ~= nil then
		html:wikitext(datas.frame:preprocess('{{DEFAULTSORT:' .. args.cle .. '}}'))
	end
--	local t = "\n* function main(frame) -- From Tpt on 2016-12-14 in ModuleAuteur2 20161214.lua"
	t = t .. viewer.ta("\n* 1295: main(frame) end args.nom", args.nom)
	return t .. tostring(html) .. '\n__NOTOC__'
end

------------------------------------------------------------------------------------------------
--	End of compact Module:Auteur2  2016-12-14T19:18:29‎ Tpt20180122 0715.lua
------------------------------------------------------------------------------------------------

function createLinkRow(link, site)
	-- Return some html stylised formated text of link
	local html = mw.html.create('div')
	html:tag('span')
		:css({['color'] = '#232388', ['font-size'] = '140%', ['line-height'] = '150%'})
		:wikitext('[[File:' .. site .. '-logo.svg|12px|logo de ' .. site .. ']]&nbsp;&nbsp;')
	html:wikitext(link)
	return html
end

function main(frame)
	--create a clean table of parameters with blank parameters removed
	local args = {}
	for k,v in pairs(datas.frame:getParent().args) do
		if v ~= '' then args[k] = v end
	end
	local naissance = getDateFromArgs(args, 'naissance', 'Naissance')
	local deces = getDateFromArgs(args, 'deces', 'Deces')
	local sexe = nil
	local html = mw.html.create()
	--Utilise Wikidata si paramètres non renseignés
	local item = mw.wikibase.getEntity()
	if item == nil then
		html:wikitext('[[Catégorie:Pages « Auteur » sans élément sur Wikidata]]')
	else
		if args.nom == nil then args.nom = item:getLabel()
		else html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un nom local]]') end
		if args.description ~= nil then html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une description locale]]')
		elseif item.descriptions ~= nil and item.descriptions.fr ~= nil then
			args.description = item.descriptions.fr.value
			if item.descriptions.fr.language ~= 'fr' then args.descriptionLanguageCode = item.descriptions.fr.language end
		end
		if args.image == nil then
			local statements = item:getBestStatements('P18')
			if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then args.image = statements[1].mainsnak.datavalue.value end
		else html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une image locale]]') end
		local naissanceWikidata = getDateFromTimeStatements(item:getBestStatements('P569'), 'naissance')
		if naissance.text == nil then naissance = naissanceWikidata
		else
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une date locale]]')
			if naissanceWikidata.text == nil then html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]') end
		end
		local decesWikidata = getDateFromTimeStatements(item:getBestStatements('P570'), 'deces')
		if deces.text == nil then deces = decesWikidata
		else
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une date locale]]')
			if decesWikidata.text == nil then html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]') end
		end
		if args.pseudo == nil then
			args.pseudo = item:formatPropertyValues( 'P742' ).value
			if args.pseudo == '' then args.pseudo = nil end
		elseif args.pseudo ~= '-' then html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un pseudo local]]') end
		sexe = qidForProperty(item, 'P21')
	end
	if args.nom == nil then return errorMessage('Le paramètre « nom » est obligatoire et doit contenir le nom de l’auteur') end
	--sort key and initiale
	local firstName = ''
	local familyName = ''
	if item ~= nil then
		--first name
		local firstNameStatements = item:getBestStatements('P735')
		if firstNameStatements[1] ~= nil then
			if firstNameStatements[1].mainsnak.type == 'value' then
				local firstNameId = firstNameStatements[1].mainsnak.datavalue.value.id
				firstName = mw.wikibase.label(firstNameId) or ''
				--TODO check if the first name is not an initial
			elseif firstNameStatements[1].mainsnak.type == 'somevalue' then
				html:wikitext('[[Catégorie:Auteurs de prénom inconnu]]')
			end
		end
		--family name
		local familyNameId = qidForProperty(item, 'P734')
		if familyNameId ~= nil then
			familyName = mw.wikibase.label(familyNameId) or ''
		end
	end
	if familyName == '' then
		--We are in a simple case with first name and last name. TODO: bad hack, should be improved
		local nameParts = mw.text.split(args.nom, ' ', true)
		if #nameParts == 1 then
			familyName = nameParts[1]
		elseif #nameParts == 2 then
			firstName = nameParts[1]
			familyName = nameParts[2]
		end
	end
	if args.cle == nil then
		if familyName ~= '' then
			local moduleClassement = require 'Module:Classement'
			args.cle = moduleClassement.getSortKeyForName({args = {firstName, familyName}})
		else
			return errorMessage('Le paramètre « cle » est obligatoire et doit contenir une clé de tri pour l’auteur')
		end
	else 
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une clé locale]]')
	end
	if args.initiale == nil then
		if args.cle ~= nil then
			args.initiale = string.sub(args.cle, 1, 1)
		else
			return errorMessage('Le paramètre « initiale » est obligatoire et doit contenir l’initiale du nom de l’auteur en majuscule non accentuée')
		end
	else
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec des données à migrer]]')
	end
	local main = html:tag('div')
		:addClass('vcard')
		:attr('itemscope', '')
		:attr('itemtype', 'http://schema.org/Person')
		:css({['background-color'] = '#F1F1DE', ['overflow'] = 'auto', ['border-radius'] = '0.7em', ['box-shadow'] = '0.2em 0.3em 0.2em #B7B7B7'})
	if item ~= nil and item.id ~= nil then
		main:attr('itemid', 'http://www.wikidata.org/entity/' .. item.id)
	end
	--Image
	local image = args.image
	if image == nil then
		local defaultImages = {'Silver - replace this image male.svg', 'Silver - replace this image female.svg'}
		if sexe == 'Q6581097' then
			image = defaultImages[1]
		elseif sexe == 'Q6581072' then
			image = defaultImages[2]
		else
			image = defaultImages[math.random(#defaultImages)]
		end
	end
	main:tag('div')
		:css({['float'] = 'right', ['margin'] = '1em'})
		:wikitext('[[Fichier:' .. image .. '|140px|alt=' .. args.nom .. '|class=photo|itemprop=image]]')
	--First row	
	local firstRow = main:tag('div')
		--Categorie Auteur-X
		firstRow:tag('div')
			:css({['float'] = 'left', ['font-size'] = '115%', ['text-indent'] = '1em'})
			:tag('span')
				:css('color', '#aaaa66')
				:wikitext('◄')
				:done()
			:wikitext('&nbsp;[[:Catégorie:Auteurs-' .. args.initiale .. '|Auteurs&nbsp;' .. args.initiale .. ']]')

		--Title
		firstRow:tag('h1')
			:addClass('fn')
			:attr('itemprop', 'name')
			:css({['text-align'] = 'center', ['font-size'] = '160%', ['font-weight'] = 'bold', ['border-bottom'] = 'none'})
			:wikitext(args.nom)
	--Second row
	local secondRow = main:tag('div')
		--Interwikis
		local interwikis = secondRow:tag('div')
			:css({['float'] = 'left', ['height'] = '50%', ['font-size'] = '75%', ['text-indent'] = '2em'})
			:node(createLinkRow('<span class="plainlinks">[//fr.wikisource.org/wiki/Spécial:IndexPages?key=' .. mw.uri.encode(searchKey(args.cle)) .. ' Fac-similés]</span>', 'Wikisource'))
			if item ~= nil and item:getSitelink('frwiki') ~= nil then
				interwikis:node(createLinkRow('[[w:' .. item:getSitelink('frwiki') .. '|Biographie]]', 'Wikipedia'))
			else
				interwikis:node(createLinkRow('[[w:' .. args.nom .. '|<span style="color:#BA0000;">Biographie</span>]]', 'Wikipedia'))
			end
			if item ~= nil and item:getSitelink('frwikiquote') ~= nil then
				interwikis:node(createLinkRow('[[q:' .. item:getSitelink('frwikiquote') .. '|Citations]]', 'Wikiquote'))
			else
				interwikis:node(createLinkRow('[[q:' .. args.nom .. '|<span style="color:#BA0000;">Citations</span>]]', 'Wikiquote'))
			end
			if item ~= nil then
				local commonsCat = item:formatPropertyValues('P373').value
				if commonsCat ~= '' then
					interwikis:node(createLinkRow('[[commons:Category:' .. commonsCat .. '|Médias]]', 'Commons'))
				elseif item:getSitelink('commonswiki') ~= nil then
					interwikis:node(createLinkRow('[[commons:' .. item:getSitelink('commonswiki') .. '|Médias]]', 'Commons'))
				else
					interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
				end
			else
				interwikis:node(createLinkRow('[[commons:' .. args.nom .. '|<span style="color:#BA0000;">Médias</span>]]', 'Commons'))
			end
			if item ~= nil and item.id ~= nil then
				interwikis:node(createLinkRow('[[d:' .. item.id .. '|Données&nbsp;structurées]]', 'Wikidata'))
			else
				interwikis:node(createLinkRow('<span class="plainlinks">[//www.wikidata.org/w/index.php?title=Special:NewItem&site=frwikisource&page=' .. mw.uri.encode(mw.title.getCurrentTitle().fullText) .. '&label=' .. mw.uri.encode(args.nom) .. ' Données&nbsp;structurées</span>]</span>', 'Wikidata'))
			end
		--Description
		local fullDescription = secondRow:tag('div')
			:css({['text-align'] = 'center', ['font-size'] = '110%', ['line-height'] = '110%', ['padding'] = '1em'})
		local description = fullDescription:tag('span')
			:addClass('label')
			:attr('itemprop', 'description')
			:wikitext(args.description or '')
		if args.descriptionLanguageCode ~= nil then
			description:attr('lang', item.descriptions.fr.language)
				:css('font-style', 'italic')
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur sans description française]]')
		elseif args.description == nil then
			html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur sans description française]]')
		end
		fullDescription
			:newline()
			:wikitext(formatDates(naissance, deces))
		if args.pseudo ~= nil and args.pseudo ~= '-' then
			fullDescription:tag('br')
			fullDescription:wikitext('Pseudonyme : \'\'')
				:tag('span')
				:attr('itemprop', 'alternateName')
				:css('font-style', 'italic')
				:wikitext(args.pseudo)
		end
	--categories
	html:wikitext('[[Catégorie:Auteurs]]' .. '[[Catégorie:Auteurs-' .. args.initiale .. ']]')
	--genre
	if args.genre ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un genre local]]')
		html:wikitext(categorization('', args.genre))
	end
	html:wikitext(categorization('', args.genre))
	--langue
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P1412')) do
			if statement.mainsnak.datavalue ~= nil then
				categoryName = 'Catégorie:Auteurs écrivant en ' .. mw.wikibase.label(statement.mainsnak.datavalue.value.id)
				html:wikitext('[[' .. categoryName .. ']]')
				if not mw.title.new( categoryName ).exists then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une catégorie de langue non créée]]')
				end
			end
		end
	end
	if args.langue ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une langue locale]]')
	end
	--nationalités
	categoryForCountry = mw.loadData('Module:Auteur2/nationalités')
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P27')) do
			if statement.mainsnak.datavalue ~= nil then
				countryId = statement.mainsnak.datavalue.value.id
				if categoryForCountry[countryId] == nil then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une nationalité sans catégorie]]')
				elseif categoryForCountry[countryId] then
					html:wikitext('[[Category:' .. categoryForCountry[countryId] .. ']]')
				end
			end
		end
	end
	if args.pays ~= nil then
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une nationalité locale]]')
	end
	--occupation
	categoryForOccupation = mw.loadData('Module:Auteur2/occupations')
	if item ~= nil then
		for _, statement in pairs(item:getBestStatements('P106')) do
			if statement.mainsnak.datavalue ~= nil then
				occupationId = statement.mainsnak.datavalue.value.id
				if categoryForOccupation[occupationId] == nil then
					html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une occupation sans catégorie]]')
				elseif categoryForOccupation[occupationId] then
					html:wikitext('[[Category:' .. categoryForOccupation[occupationId] .. ']]')
				end
			end
		end
	end
	if args.metier ~= nil or args["métier"] ~= nil then
		html:wikitext(categorization('', args.metier or args["métier"]))
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une occupation locale]]')
	end
	--prix
	if args.prix ~= nil then
		html:wikitext(categorization('Lauréats du', args.prix))
		html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec un prix local]]')
	end
	if item ~= nil then
		for _, awardStatement in pairs(item:getBestStatements('P166')) do
			if awardStatement.mainsnak.datavalue ~= nil then
				distinctionItem = mw.wikibase.getEntity(awardStatement.mainsnak.datavalue.value.id)
				for _, awardeeCatStatement in pairs(distinctionItem:getBestStatements('P2517')) do
					if awardeeCatStatement.mainsnak.datavalue ~= nil then
						wikisourceCategory = mw.wikibase.sitelink(awardeeCatStatement.mainsnak.datavalue.value.id)
						if wikisourceCategory then
							html:wikitext('[[' .. wikisourceCategory .. ']]')
						end
					end
				end
			end
		end
	end
	--categorie dates
	if naissance.precision >= 9 and naissance.year > 1500 then
		html:wikitext('[[Catégorie:Naissance en ' .. naissance.year .. ']]')
	end
	if deces.precision >= 9 and deces.year > 1500 then
		html:wikitext('[[Catégorie:Décès en ' .. deces.year .. ']]')
	end
	local withoutEpoque = true
	if naissance.century ~= nil and (naissance.precision < 9 or naissance.year <= naissance.century * 100 - 20) then
		if 15 <= naissance.century then
			html:wikitext('[[Catégorie:Auteurs du ' .. getTextForCentury(naissance.century, false) .. ']]')
		elseif 6 <= naissance.century and naissance.century <= 14 then
			html:wikitext('[[Catégorie:Auteurs du Moyen Âge]]')
		else
			html:wikitext('[[Catégorie:Auteurs de l’Antiquité]]')
		end
		withoutEpoque = false
	end
	if deces.century ~= nil and (deces.precision < 9 or (deces.century - 1) * 100 + 5 <= deces.year) then
		if 15 <= deces.century then
			html:wikitext('[[Catégorie:Auteurs du ' .. getTextForCentury(deces.century, false) .. ']]')
		elseif 6 <= deces.century and deces.century <= 14 then
			html:wikitext('[[Catégorie:Auteurs du Moyen Âge]]')
		else
			html:wikitext('[[Catégorie:Auteurs de l’Antiquité]]')
		end
		withoutEpoque = false
	end
	if withoutEpoque then html:wikitext('[[Catégorie:Epoque inconnue]]') end
	if sexe == 'Q6581072' then html:wikitext('[[Catégorie:Autrices]]') end
	--droits
	if args.droits == nil then
		args.droits = '70'
	end
	droitsNumber = tonumber(args.droits)
	if args.droits == 'mpf' then
		if deces.precision >= 9 and tonumber(os.date("%Y")) <= deces.year + 95 then --TODO: guess 'mpf' from P166:Q3324507 in Wikidata?
			html:wikitext(datas.frame:expandTemplate({title = 'Auteur Mort pour la France'}))
		end
		html:wikitext('[[Catégorie:Auteurs morts pour la France]]')
	elseif args.droits == 'non' then
		--rien à faire
	elseif droitsNumber ~= nil then
		if deces.year ~= nil and tonumber(os.date("%Y")) <= deces.year + droitsNumber then --XX ans on vérifie le DP-EU
			if naissance.year == nil or 1923 - naissance.year > 20 then
				html:wikitext(datas.frame:expandTemplate({title = 'DP-EU-Auteur'}))
			end
		end
		if args.droits ~= '70' then html:wikitext('[[Catégorie:Droits d’auteur ' .. args.droits .. ' ans]]') end
	else
		return errorMessage('Le paramètre droit contient une valeur non supportés. Valeurs possibles : 70/60/50 (durée du droit d\'auteur), "mpf" (mort pour la france). Par défaut: 70')
	end
	--maintenance
	if args.image == nil then html:wikitext('[[Catégorie:Pages « Auteur » sans image]]') end
	if args.cle ~= nil then html:wikitext(datas.frame:preprocess('{{DEFAULTSORT:' .. args.cle .. '}}')) end
	return tostring(html) .. '\n__NOTOC__'
end

function viewer.is_in(word, text) -- The word is it in the text, even inside another word?
	local bug = "Erreur Lua dans Module:Central-s-fr à la ligne 7444 : attempt to call field 'find' (a nil value)."
	local i = string.find(text or "", word or "", 1, true)
	return (i and true)
end

function viewer.ta(txt, val, sep) -- Form an argument and its value in a documentation. The text is "nil" if the value is nil.
	if val == nil then val = "nil" end
	if sep == nil then sep = "=" end
	return " , " .. tostring(txt) .. " " .. tostring(sep) .. " <b>" .. tostring(val) .. "</b> "
end

function lua_table.level_list(tab, typ, select, field) -- Collect and count selected or all keys, in the first level of the table -- subtasks S170813lll
	--	typ = "key;val;keys;vals;sort;boolean;function;number;string;table;"
	-- Get only the first level of the table. Select only keys containing select. Select the field as key if defined.
	-- Collects and counts the selected keys, or all, in recording order
	-- Count the key of the typ type
	-- for T20170130 Begin to use
	local list, count, level, split, ok = "", 0, {}, {}, false
	local sort, keyval = typ, ""
--	if sort == "sort" then typ = "string" end -- Select values by their type.
	if (type(tab) ~= "table") then return list, count, level, split end
	for key, val in pairs(tab) do
		table.insert(level, val)
		ok = false
		if (typ == "key") then -- Count and list keys from select and field.
			sort, keyval = false, key
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "val") then -- Count and list values...
			sort, keyval = false, val
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "keys") then -- Count and sort keys...
			sort, keyval = true, key
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "vals") then -- Count and sort values...
			sort, keyval = true, val
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "sort") then -- Sort all values...
			sort, keyval = true, tab[field or 1]
			if viewer.is_in( tostring(keyval), tostring(select) ) then ok = true end -- Select a value if the val is in select.
		else -- lua_table.count_values()
			local typ2 = type(typ) -- To select a type or the type of a variable.
				if (typ2 == "boolean") or (typ == "boolean") then -- Count only these types.
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "function") or (typ == "function") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "number") or (typ == "number") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "string") or (typ == "string") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "table") or (typ == "table") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			end
		end
		if ok then
			table.insert(split, keyval) -- Collect the selected keys, or all, in recording order
			count = count + 1 -- Count the key of the typ type
			list = list .. tostring(keyval) .. ", " -- List values
		end
	end
	if (sort == "sort") or (sort == true) then table.sort( split ) end -- in alphabetic order -- , function (a, b) end
	list = table.concat(split, ", ")
	return list, count, level, split
end --	local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests(

function datas.tv(line, prop, what, val) -- track a property in datas.get_item
	local t = ""
	if prop == "P569" then
		local line = "L" .. tostring(line)
		local prop = tostring(prop)
		local what = tostring(what)
		local val = tostring(val)
		t = t .. "\n*  line=" .. line .. ": prop=" .. prop .. " what=" .. what .. " val=" .. val
	end
	return t
end -- datas.track_val = datas.tv(line, prop, what, val)

function datas.prot(prop)
	datas.prop = datas.prop or {}
	local prop = prop
	if type(prop) ~= "string"then prop = "prop" end
	local t = prop
	if type(prop) == "string" and not string.find(prop, "%s", 1, true) then t = datas.prop[prop] or prop end
	return t
end

function lua_table.level_count(tab) -- Count all objects in the table, or 0 if tab is not a table.
	local count = 0
	if (type(tab) ~= "table") then return count end
	for k,v in pairs(tab) do
		count = count + 1
	end
	return count
end -- c = lua_table.level_count(tab)

function lua_table.level_list(tab, typ, select, field) -- Collect and count selected or all keys, in the first level of the table -- subtasks S170813lll
	--	["typ"] = "key;val;keys;vals;sort;boolean;function;number;string;table;"
	-- Get only the first level of the table. Select only keys containing select. Select the field as key if defined.
	-- Collects and counts the selected keys, or all, in recording order
	-- Count the key of the typ type
	-- for T20170130 Begin to use
	local list, count, level, split, ok = "", 0, {}, {}, false
	local sort, keyval = typ, ""
--	if sort == "sort" then typ = "string" end -- Select values by their type.
	if (type(tab) ~= "table") then return list, count, level, split end
	for key, val in pairs(tab) do
		table.insert(level, val)
		ok = false
		if (typ == "key") then -- Count and list keys from select and field.
			sort, keyval = false, key
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "val") then -- Count and list values...
			sort, keyval = false, val
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "keys") then -- Count and sort keys...
			sort, keyval = true, key
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "vals") then -- Count and sort values...
			sort, keyval = true, val
			if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
		elseif (typ == "sort") then -- Sort all values...
			sort, keyval = true, tab[field or 1]
			if viewer.is_in( tostring(keyval), tostring(select) ) then ok = true end -- Select a value if the val is in select.
		else -- lua_table.count_values()
	--[[
	local list, count_done, level, split = lua_table.level_list(mw, "keys") -- , "string", "done", 3) -- S170621csc
	t = t .. "\n* list mw.* " .. list -- Library:lua_table function lua_table.level_list(
	t = t .. "\n* level_list mw " .. tostring(lua_table.level_list(mw, "keys") )
	t = t .. "\n* count_all mw " .. tostring(lua_table.count_all(mw, "keys") )
	t = t .. "\n* count_types mw " .. lua_table.rough_view(lua_table.count_types(mw, "keys") )
	t = t .. "\n* count_values mw " .. lua_table.rough_view(lua_table.count_values(mw, "keys") )
	t = t .. "\n* rough_view mw " .. lua_table.rough_view(mw, {recursiveLimit = 1,}) -- function lua_table.rough_view(table, option) opt.recursiveLimit
	--]]
			local typ2 = type(typ) -- To select a type or the type of a variable.
				if (typ2 == "boolean") or (typ == "boolean") then -- Count only these types.
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "function") or (typ == "function") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "number") or (typ == "number") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "string") or (typ == "string") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			elseif (typ2 == "table") or (typ == "table") then
				if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
			end
		end
		if ok then
			table.insert(split, keyval) -- Collect the selected keys, or all, in recording order
			count = count + 1 -- Count the key of the typ type
			list = list .. tostring(keyval) .. ", " -- List values
		end
	end
	if (sort == "sort") or (sort == true) then table.sort( split ) end -- in alphabetic order -- , function (a, b) end
	list = table.concat(split, ", ")
	return list, count, level, split
end --	local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests(

function datas.getDateFromTimeStatement(statements, field)
	local time = nil
	if type(statements) ~= "table" then statements = {} end
--	if #statements == 0 then 
--		return "2018-01-250" -- { precision = 0 }
--	end
	if #statements == 0 then
		time = "2018-01-253"
		return {
			precision = 0
		}
	end
--	local time = nil
	for _, statement in pairs(statements) do
		local newTime = datas.getDateFromTimeStatement(statement, field)
		if time == nil then
			time = newTime
		elseif time.year ~= newTime.year then --années contradictoires
			return {
				text = errorMessage('Plusieurs années de ' .. field .. ' possibles sur Wikidata. Une manière simple de résoudre se problème est de mettre la date à afficher au rang "préféré".'),
				precision = 0
			}
		end
	end
	if time == nil then
		return {
			precision = 0
		}
	end
	return time or "2018-01-275"
end

function datas.get_item(args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.
--	See: https://www.mediawiki.org/wiki/Mw.wikibase.entity.lua_bug_fix_instructions
--	See: https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua#mw.wikibase.entity:getDescription
	datas.track_val = datas.track_val or ""
	local QITEM, Title, Label, prop, lang, description, val, val_label = QITEM
				val, val_label = datas.get_prop(prop, item) -- Get the property's value and label
	t = "\n* datas.get_item(args_known, QITEM):"
	local args_known = args_known or p.args_known or {} -- optional value from p.args_known = {		}
	local langs = { -- known langs
		["content_lang"] = "fr",
		["page_lang"] = "es",
		["user_lang"] = "en",
	}
	local lang = lang or langs.user_lang or "en"
	datas.prop = datas.prop or {} -- Table to use like: datas.prop.Label or datas.prop["Label"] = "Nelson Mandela"
	datas.props = datas.prop or {} -- Table to use like: datas.prop.Label or datas.prop["Label"] = "Nelson Mandela"
	local props = datas.props --	Server mw.uri.new for path like = /wiki/Utilisateur:Rical/Nelson_Mandela
	props.Label = mw.wikibase.entity:getLabel(langs.user_lang) -- table of labels by language code
	local i = string.find(props.Label, ":", 1, true)
	if i then props.Label = string.sub(props.Label, i+1, -1) end
	--[[
	if (string.sub(id, 1, 1)
	local i = string.find(text or "", word or "", 1, true)
	local split = mw.text.split(props.Label, ':') -- table of words
	if (s) then props.Label = split[1] or props.Label end
	if (split[1] == "") then props.Label = split[2] or props.Label end
	 -- table of labels by language code. Do better later.
	--]]
	props.Title = props.Label -- table of labels by language code. Do better later.
	--
	-- Select QITEM or Title
	QITEM = QITEM or "Q535"
	--[[
	local mwuri = mw.uri.new() --	Server mw.uri.new for path like = /wiki/Utilisateur:Rical/Nelson_Mandela
	local Title, sub_parts = props.Label, mw.text.split(mwuri.path, '/') -- table of words
	for k, part in pairs(sub_parts) do Title = part end
	local Title, sub_parts = props.Label, mw.text.split(part, ':') -- table of words
	for k, part in pairs(sub_parts) do Title = part end
	Title = string.gsub(Title, "_", " ")
	--]]
	datas.QITEM = QITEM or datas.QITEM or mw.wikibase.getEntityIdForCurrentPage() or "Q8023" -- without any arg
	-- Only in this example: fr.wikisource.org/wiki/Module:...
--	datas.item = mw.wikibase.getEntity(datas.QITEM) -- add_err()+add_cat() Only in a dedicated namespace and if datas exist
	local globalSiteId = globalSiteId or "https://fr.wikisource.org/wiki/Special:Version"
	local globalSiteId = globalSiteId or mw.wikibase.entity:getSitelink( QITEM, globalSiteId )
	local globalSiteId = globalSiteId or datas.item:getSitelink( QITEM, "https://fr.wikisource.org/wiki/Special:Version" )
	t = t .. viewer.ta("\n* get_datas globalSiteId=", globalSiteId)
	mw.wikibase.sitelink( QITEM, globalSiteId ) -- Takes an entity ID and returns the title of the corresponding page title on the local Wiki.
	-- When globalSiteId is given, the page title on the specified wiki is returned, rather than the one on the local wiki.
	if not datas.item then
		datas.track_val = datas.track_val or ""
		datas.track_val = datas.track_val .. "\n* add_err()+add_cat() Only in a dedicated namespace and if datas exist" .. viewer.ta("\n* datas.QITEM", datas.QITEM)
		return props
	end
	t = t .. viewer.ta("\n* get_datas begin QITEM=", datas.QITEM) .. viewer.ta("#args_known", lua_table.level_count(args_known))
--	props.Label = datas.item:getLabel() -- add_err()+add_cat() Only in a dedicated namespace and if datas exist
	if not datas.item then
		datas.track_val = datas.track_val or ""
		datas.track_val = datas.track_val .. "\n* add_err()+add_cat() Only in a dedicated namespace and if datas exist" .. viewer.ta("\n* datas.Label", datas.Label)
		--	events.add_err("modes_too_unnamed_arguments_err", key_N, val_src .. " LLL lev=" .. tostring(arglst[1].levenshtein) )
		--	events.add_cat("versn_module_usage_error_cat")
		return props
	end
	--[[
	local mwuri = mw.uri.new() --	Server mw.uri.new for path like = /wiki/Utilisateur:Rical/Nelson_Mandela
	local Title, sub_parts = props.Label, mw.text.split(mwuri.path, '/') -- table of words
	for k, part in pairs(sub_parts) do Title = part end
	Title = string.gsub(Title, "_", " ")
	--]]
--	t = t .. viewer.ta("\n* 1289: get_datas begin Title=", props.Title) .. viewer.ta("props.Label=", props.Label) .. viewer.ta("#args_known", lua_table.level_count(args_known))
--	t = t .. viewer.ta("\n* 45: get_datas begin Title=", Title) .. viewer.ta("#args_known", lua_table.level_count(args_known))
--	Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322),
--	Nelson Mandela (Q8023), Rudyard Kipling (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772)
	props.QITEM = datas.QITEM
--	t = t .. "\n* 1294: get_datas begin val=" .. (val or "var") .. ": #args_known=" .. lua_table.level_count(args_known)
	lang = lang or langs.user_lang
	for key, args_opt in pairs(args_known) do -- from p.args_known = { }
	--[= =[
		local val, snaks = nil
		local prop = args_opt["prop"] -- Get the value of the sought property, or nil
		if type(prop) == "string" then
				if prop == 'label'		then props[prop] = wikibase.label() -- label -> P735 -> lastname
			elseif prop == 'Label'		then props[prop] = wikibase.label() -- label -> P735 -> lastname
			elseif prop == 'description'then props[prop] = wikibase.description() -- label -> P735 -> lastname
			elseif prop == 'sitelink'	then props[prop] = wikibase.sitelink() -- label -> P735 -> lastname
			else							 props[prop] = datas.get_prop(prop, item) -- Get the property's value and label
			end
	--[[
			elseif prop == 'Q16222597'	then val = "P18" -- QITEM -> image
		--	elseif prop == 'P569'		then val = datas.getDateFromTimeStatement( datas.item:getBestStatements('P569') ) or "propP569"
			elseif prop == 'P569' then -- birthday to birthyear
				local naissanceWikidata = datas.getDateFromTimeStatement(datas.entity:getBestStatements('P569'), 'naissance')
				val = naissanceWikidata
				t = t .. viewer.ta("\n* 345: get_item qualifiers prop == 'P569'=", prop) .. viewer.ta("val", val)
			elseif prop == 'P570' then -- deathday to deathyear
				local decesWikidata = datas.getDateFromTimeStatement(datas.entity:getBestStatements('P570'), 'deces')
				val = decesWikidata
				t = t .. viewer.ta("\n* 349: get_item qualifiers prop == 'P570'=", prop) .. viewer.ta("val", val)
			else
				val, val_label = datas.get_prop(prop, item) -- Get the property's value and label
	--]]
	----<--<----
	----<--<----
	--[==[
	local statements, qualifiers, snak, naissanceWikidata
	local naissanceWikidata = datas.getDateFromTimeStatement(datas.item:getBestStatements('P569'), 'naissance')
	local statements = datas.item:getBestStatements('P569') --, 'naissance')
--	local snak = datas.item['claims']['P342'][1]['qualifiers']['P342'][1]
--	local snak = datas.item['claims'][prop][1]['qualifiers'][prop][1]
	qualifiers = datas.item['claims'][prop][1]['qualifiers']
	if qualifiers then
----------------------------------------------------------------------------------	
--		for _, statement in pairs(item:getBestStatements('P1412')) do show in dats ------------
----------------------------------------------------------------------------------	
		snak = datas.item['claims'][prop][1]['qualifiers'][prop][1]
	--	val = mw.wikibase.renderSnak( snak ) -- Returns the given Snak value formatted as wikitext escaped plain text.
		val = mw.wikibase.formatValue( snak ) -- Returns the given Snak value formatted as rich wikitext.
		t = t .. viewer.ta("\n* 352: get_item qualifiers [prop][1]=", prop) .. viewer.ta("val", val)
		if not val then
			snak = datas.item['claims'][prop][1]['qualifiers'][prop][2]
			val = mw.wikibase.formatValue( snak ) -- Returns the given Snak value formatted as rich wikitext.
			t = t .. viewer.ta("\n* 356: get_item qualifiers [prop][2]=", prop) .. viewer.ta("val", val)
		end
	else 
		if datas.item['claims'][prop][2] and datas.item['claims'][prop][2]['qualifiers'] then
			qualifiers = datas.item['claims'][prop][2]['qualifiers']
			snak = qualifiers[prop][1]
		--	val = mw.wikibase.renderSnak( snak ) -- Returns the given Snak value formatted as wikitext escaped plain text.
			val = mw.wikibase.formatValue( snak ) -- Returns the given Snak value formatted as rich wikitext.
			t = t .. viewer.ta("\n* 1337: get_item qualifiers [prop][2]=", prop) .. viewer.ta("val", val)
		--	html:wikitext('[[Catégorie:Pages utilisant le modèle Auteur avec une image locale]]')
		end
	end
	--]==]
	---->-->----45:
	---->-->----
		end
		prop = (prop or "P000")
		props[prop] = val -- or "description1347"
	--	if prop == "P569" then t = t .. datas.tv(1348, "P569", "Track the property 'P569' in datas.get_item: ", val) end
		t = t .. viewer.ta("\n* 1364: get_item qualifiers end prop=", prop) .. viewer.ta("val", val)
	--]= =]
	end
	props.QITEM = props.QITEM or datas.QITEM
	t = t .. viewer.ta("\n* 1358: get_item Title=", Title) .. viewer.ta("props.Label=", props.Label)
	.. viewer.ta("props.description=", props.description) .. viewer.ta("#args_known", lua_table.level_count(args_known))
--] ]
	if not props.P569 then props.P569 = "P569" end
	if not props.P570 then props.Title = "P570" end
	props.P569 = props.P569 or "P569"
	props.P570 = props.P570 or "P570"
	props.Title = props.Title or props.Label
	t = t .. "\n* 1360: datas.get_item end 1 #props=" .. lua_table.level_count(props)
	t = t .. "\n* 1361: props.QITEM=" .. tostring(props.QITEM)
	for prop, val in pairs(props) do -- try other statements
		t = t .. "\n* 1363: get_datas:" .. viewer.ta("prop", prop) .. viewer.ta("val", val)
	end
	local AllStatements = datas.entity:getAllStatements( 'P569' ) -- Returns a table containing the serialization of P12 statements
	local AllStatements_view = lua_table.rough_view(AllStatements)
	t = t .. "\n* 1067: datas.get_item getAllStatements( 'P569' ) = " .. AllStatements_view
	datas.track_val = "\n* " .. t
	return datas.props
end -- datas.props = datas.get_item(args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.

--	from 2016-08-16 ModuleCentral 3a lua_table.tolist.lua
--	function datas.import_wikidata_item(args_known, id) -- id = QITEM or Title
function datas.get_datas(args_known, id) -- Get datas from modes.args_known and add wikibase datas for the page.
--	See: https://www.mediawiki.org/wiki/Mw.wikibase.entity.lua_bug_fix_instructions
--	wikidata structure args_known.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"])
	datas.track_val = datas.track_val or ""
	if type(args_known) ~= "table" then args_known = modes.args_known end
--	if type(id) ~= "string" then id = nil end -- .. " ) "
	local t, adr, val, proplabel = "", nil, nil, nil
	t = "\n* datas.get_datas(args_known, QITEM)  OLD :"
	local wd = {}
	local wd_mng = {} -- wikidata manager
	wd_mng.wd_base = mw.wikibase
	if not wd_mng.wd_base then -- Wikibase available ?
		wd_mng.wd_error = "wd_base"
		t = t .. viewer.ta("wd_error", wd_mng.wd_error)
		wd_mng.t = t
		modes.args_wikidata = wd
		return wd, t, wd_mng
	end
	local function pcall_getEntityObject( wd_id ) -- wikidata arbitrary access must not fail and block the page.
		local success, entity = pcall( mw.wikibase.getEntity, wd_id ) -- pcall or xpcall can run any function without blocking page.
		if success then return entity else return nil end
		-- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking)
	end
	wd_mng.id = id
	if type(id) == "string" then
		if (string.sub(id, 1, 1) == "Q") and tonumber( string.sub(id, 2) ) then wd_mng.id = id -- QITEM case
		else
			wd_mng.Title = id
			wd_mng.id = wikibase.getEntityIdForTitle( wd_mng.Title ) -- Title case
		end
	else id = nil end
	if id then -- Wikidata item available ?
		wd_mng.wd_entity = pcall_getEntityObject( id )
	elseif wd_mng.id then -- Wikidata item available ?
		wd_mng.wd_entity = pcall_getEntityObject( wd_mng.id )
	else
		wd_mng.wd_id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42"
		if wd_mng.wd_id then -- Wikidata item available ?
			wd_mng.wd_entity = mw.wikibase.getEntityObject(wd_mng.wd_id)
			wd_mng.wd_entity.id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42"
		end
	--	wd_mng.wd_entity = mw.wikibase.getEntity() -- ex getEntityObject
	end
	if wd_mng.wd_entity then -- Page Wikidata disponible ?
		if wd_mng.wd_entity.claimRanks then
			wd_mng.wd_claimRanks = wd_mng.wd_entity.claimRanks
			wd_mng.wd_RANK_TRUTH = wd_mng.wd_entity.claimRanks.RANK_TRUTH
			wd_mng.wd_RANK_PREFERRED = wd_mng.wd_entity.claimRanks.RANK_PREFERRED
			wd_mng.wd_RANK_NORMAL = wd_mng.wd_entity.claimRanks.RANK_NORMAL
			wd_mng.wd_RANK_DEPRECATED = wd_mng.wd_entity.claimRanks.RANK_DEPRECATED
			-- https://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua#mw.wikibase.entity.claimRanks
			-- Return the normal ranked claims with the property id P5
			-- entity:formatPropertyValues( 'P5', { mw.wikibase.entity.claimRanks.RANK_NORMAL } )
			-- Return all claims with id P123 (as the table passed contains all possible claim ranks)
			-- entity:formatPropertyValues( 'P123', mw.wikibase.entity.claimRanks )
			-- mw.wikibase.entity.claimRanks = RANK_TRUTH, RANK_PREFERRED, RANK_NORMAL, RANK_DEPRECATED
		end
		wd_mng.sitelink = wd_mng.wd_entity:getSitelink( )
		wd_mng.label = wd_mng.wd_entity:getLabel( ) -- Returns a string, like "Berlin" with 'de'
		wd_mng.props = wd_mng.wd_entity:getProperties() -- or {} Returns a table like: { "P123", "P1337" }
		wd_mng.props_count_all = tostring(lua_table.count_all( wd_mng.props ) )
		wd_mng.props_txt = "T " .. mw.text.listToText( wd_mng.props )
		--
		wd_mng.props_list = " "
		for i, pp in ipairs(wd_mng.props) do -- Properties list
			wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues(pp)
			if wd_mng.wd_claimRanks then
				wd_mng.formatPropertyValues_claimRanks = wd_mng.wd_entity:formatPropertyValues(pp, { wd_mng.wd_claimRanks } )
			end
			if wd_mng.wd_RANK_TRUTH then
				wd_mng.formatPropertyValues_RANK_TRUTH = wd_mng.wd_entity:formatPropertyValues(pp, { wd_mng.wd_RANK_TRUTH } )
			end
			if wd_mng.wd_RANK_PREFERRED then
				wd_mng.formatPropertyValues_RANK_PREFERRED = wd_mng.wd_entity:formatPropertyValues(pp, { wd_mng.wd_RANK_PREFERRED } )
			end
			if wd_mng.wd_RANK_TRUTH then
				wd_mng.formatPropertyValues_wd_RANK_NORMAL = wd_mng.wd_entity:formatPropertyValues(pp, { wd_mng.wd_RANK_NORMAL } )
			end
			if wd_mng.wd_RANK_TRUTH then
				wd_mng.formatPropertyValues_RANK_DEPRECATED = wd_mng.wd_entity:formatPropertyValues(pp, { wd_mng.wd_RANK_DEPRECATED } )
			end
			val = wd_mng.formatPropertyValues.value
			if type(val) == "table" then val = lua_table.level_list(val) end
			proplabel = wd_mng.formatPropertyValues.label
			wd_mng.props_list = wd_mng.props_list .. " , " .. i .. "=" .. pp .. "=" .. viewer.ta(proplabel, val)
			-- .. "/" .. viewer.ta(proplabel, wd_mng.formatPropertyNORMAL)
			if pp == "P569" then -- birthyear P569 for test DEBUG
			datas.TimeName = pp .. ".1.mainsnak" ; datas.WikidataTimeDetails = wd_mng.wd_entity.claims[pp][1].mainsnak end
			if pp == "P570" then -- deathyear P570 for test DEBUG
			datas.TimeName = pp .. ".1.mainsnak" ; datas.WikidataTimeDetails = wd_mng.wd_entity.claims[pp][1].mainsnak end
			-- https://www.wikidata.org/wiki/Wikidata:Bistro#Date de décès inconnue
			-- Dans la propriete :Il y a trois petits rectangles à gauche qui permettent de dire si il n'y a pas de valeur (donc pas mort) où si la date est inconnue, le modèle ici ne tient pas compte de ces éléments. --[[User:Pino~eowiki|Pino~eowiki]] ([[User talk:Pino~eowiki|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 16:40, 27 January 2016 (UTC)
		end
	else -- if not wd_mng.wd_entity then entity unknown for the page. entity introuvable pour la page.
		wd_mng.wd_error = "wd_entity"
		t = t .. viewer.ta("wd_error", wd_mng.wd_error)
		wd_mng.t = t
		datas.args_wikidata = wd
		return wd, t, wd_mng
	end
	if wd_mng.wd_error then -- Show an error, Signaler une erreur
		if wd_mng.wd_error == "wikidata_props" then err = viewer.form9user("tools_wikidata_error_err", "wikidata_props") end
		if wd_mng.wd_error == "wd_base" then err = viewer.form9user("tools_wikidata_wikibase_err") end
		if wd_mng.wd_error == "wd_entity" then err = viewer.form9user("tools_wikidata_getEntity_err", wd_mng.wd_entity) end
		if wd_mng.wd_error == "wd_property" then err = viewer.form9user("tools_wikidata_property_err", wd_mng.wd_property) end
		-- elem -> id
		if wd_mng.wd_error == "wd_id" then err = viewer.form9user("tools_wikidata_getEntityObject_err", wd_mng.wd_id) end
		err = events.err_add(err)
		t = t .. err
		local tools_wikidata_cat_err = events.cat_add("tools_wikidata_cat_err")
	else
		if type(args_known) ~= "table" then args_known = {} end
		for key, pp in pairs(args_known) do -- Pour tous les paramètres connus
			if pp.prop then
				if pp.prop == "label" then val = wd_mng.label
				elseif pp.prop == "sitelink" then val = wd_mng.sitelink
				elseif pp.prop == "QITEM" then val = wd_mng.wd_entity.id
				elseif pp.prop == "description" then val = wd_mng.wd_base.description( wd_mng.wd_id ) -- wikibase.description( id )
				elseif pp.prop == "claims" then val = wd_mng.wd_base.renderSnak( wd_mng.wd_entity['claims'] ) -- Returns the given Snaks formatted as wiki text.
			--	local entity = mw.wikibase.getEntityObject()
			--	local snaks = entity['claims']['P342'][1]['qualifiers']
			--	mw.wikibase.renderSnaks( snaks ) -- Returns the given Snaks formatted as wiki text.
				else
					wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp.prop ) -- "P" .. pp.prop
					-- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" }
					if wd_mng.wd_RANK_TRUTH then
						wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues(  pp, { wd_mng.wd_RANK_TRUTH } )
					end
					if wd_mng.wd_claimRanks then
						wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues(  pp, { wd_mng.wd_claimRanks } )
					end
					val = wd_mng.formatPropertyValues.value
					proplabel = wd_mng.formatPropertyValues.label
				end
				if pp.format == "year" then -- sitelink
					val = mw.ustring.sub( val, -4, -1 )
				end
				wd[key] = val
				t = t .. viewer.ta(key, val) -- .. viewer.ta(key, wd_mng.formatPropertyNORMAL)
			end
		end
	end
--	wd.lastname = wd.label
	t = t .. "\n* 1187: datas.get_datas(args_known, QITEM)  END."
	datas.track_val = "\n* " .. t
	return wd, t, wd_mng
end -- local wd, t, wd_mng = datas.get_datas(args_known, id) -- Get datas from modes.args_known and add wikibase datas for the page.

function viewer.box1(props) -- Form a box with variables to replace from a table of string values.
	local props = props or datas.props or {}
--	if type(props) ~= "table" then return "\n* viewer.box1(vals) without a table vals{}." end -- optional arguments
	local res = ""
	res = res .. "\n* <b>viewer.box1(props)</b><br/>"
	res = res .. '<div id="Author" itemscope="" itemtype="http://schema.org/Person" style="margin-right:5px; box-shadow:0.2em 0.3em 0.2em #B7B7B7; background-color:#F1F1DE; padding:0.3em; overflow:auto; line-height:80%; border-radius:0.7em; " >'
	  .. '<table cellspacing="0" cellpadding="0" style="background-color: transparent; border:none; padding:0em;">'
		.. '<tr>'
		  .. '<td valign="middle" rowspan="3" style="background-color: #F1F1DE; text-align:left; font-size:80%; ">'
			.. '<div style=" width:7em; text-align:left; line-height:220%; " >'
			.. viewer.ta("links", props.links)
			.. '</div>'
		  .. '</td>'
		  .. '<td valign="top" rowspan="1" align="center" style="min-width:40%; padding:0.5em; ">'
			.. '<span id="AuthorName" style=" font-family:Times,serif; text-align:center; max-heigth:20%; line-height:80%; font-size:180%; font-weight:bold; padding-bottom:0.5em; ">' -- "Times New Roman"
			  .. viewer.ta("Title", props.Title) .. viewer.ta("Label", props.Label)
			.. '</span>'
		  .. '</td>'
		  .. '<td valign="middle" align="center" rowspan="3" style=" border-left:{{{border|0}}}px solid #CCCCCC; ">'
			.. '<div id="AuthorImage" style=" padding:4px; ">'
			--.. (props.image or "-")
			  .. viewer.ta("image", props.image) .. viewer.ta("Label", props.P18)
			.. '</div>'
		  .. '</td>'
		.. '</tr>'
		.. '<tr>'
		  .. '<td align="center" style="width:100%; padding:0.3em; ">' -- valign="top"
			.. '<span class="label" style=" font-size:110%; max-heigth:20%; line-height:110%; text-align:center; " >'
			  .. viewer.ta("description", props.description)
			.. '</span>'
		  .. '</td>'
		.. '</tr>'
		.. '<tr>'
		  .. '<td >' -- colspan="1"
			.. '<div align="center" style=" margin:0.3em; flex-flow:row wrap; text-align:center; " >'
				.. "notices"
				.. ' <span style=" color:#BBBBBB; ">|</span> &nbsp; '
				.. '<br/><br/><span style=" text-align:center; line-height:150%; font-size:80%; ">'
				.. viewer.ta("bithyear", props.bithyear) .. viewer.ta("deathyear", props.deathyear)
				.. '</span>'
			.. '</div>'
		  .. '</td>'
		.. '</tr>'
	  .. '</table>'
	.. '</div>'
	return res
end -- res = res .. viewer.box1(props) -- Form a box with variables to replace from a table of string values.

function qidForProperty(item, property)
	local statements = item:getBestStatements(property)
	if statements[1] ~= nil and statements[1].mainsnak.datavalue ~= nil then
		return statements[1].mainsnak.datavalue.value.id
	end
	return nil
end

function datas.get_prop(prop, item) -- Get the property's value and label
	local item, val, val_label = item or datas.item
	if type(prop) == "string" then
		local prop_tab = item:getBestStatements(prop)
		local prop_tab_example = { ["value"] = "Formatted claim value", ["label"] = "Label of the Property" }
		val = prop_tab["value"]
		val_label = prop_tab["label"]
	end
	return val, val_label
	--[[
	if type(prop) == "string" then statements = item:getBestStatements(prop) end
	if statements[1] and statements[1].mainsnak.datavalue then return statements[1].mainsnak.datavalue.value.id end
	else return nil end
	mw.wikibase.entity:formatPropertyValues, but the returned values will be formatted as rich wikitext, rather than just wikitext escaped plain text.
	item:formatPropertyValues( 'P12' )
	-- Return a table like: { value = "Formatted claim value", label = "Label of the Property" }
	--]]
end -- val, val_label = datas.get_prop(prop, item) -- Get the property's value and label

function p.dats(frame)
	-- Central values for datas for dats
	datas.frame = mw.getCurrentFrame()
	datas.QITEM = mw.wikibase.getEntityIdForCurrentPage() or "Q8023" -- without any arg
	datas.entity = mw.wikibase.getEntity(datas.QITEM or "Q8023") -- for "Nelson Mandela"
	--	datas.entity:getAllStatements('P569') -- Returns a table containing the serialization of P12 statements
	datas.track_val = datas.track_val or ""
	local res, t = "", ""
	res = res .. "\n* <b>p.dats in args_known</b>"
	datas.props = {}
--	p.args_known = { -- Table of the definitions of all known arguments at module level.
	local args_known = args_known or p.args_known
	for key, args_prop in pairs(args_known) do
		local prop = args_prop.prop
		if prop then val = datas.item:getBestStatements(prop) or prop or "noprop" else val = args_prop.keyword or "keyword" end
		if prop and val then datas.props[prop] = (val) end
		res = res .. viewer.ta(tostring(prop), tostring(val))
	end -- box1
	res = res .. viewer.box1(datas.props) -- Form a box with variables to replace from a table of string values.
	-- Some arguments have a keyword identical to the registration name, except synonyms.
	--[[
	["image"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "image",		["prop"] = "P18", },
	["country"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "country",	["prop"] = "P27", },
	["birthyear"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "birthyear",	["prop"] = "P569", ["format"] = "year", },
	["deathyear"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "deathyear",	["prop"] = "P570", ["format"] = "year", },
	["lastname"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", },
	--]]
----------------------------------------------------------------------------------	
--		for _, statement in pairs(item:getBestStatements('P1412')) do show in dats ------------
----------------------------------------------------------------------------------	
	--[[
	datas.prop, t = datas.get_datas(p.args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.
	res = res .. t
	res = res .. "\n* " .. viewer.ta("datas.prop.QITEM",		datas.prop.QITEM)
	res = res .. "\n* " .. viewer.ta("datas.prop.description",	datas.prop.description)
	res = res .. "\n* " .. viewer.ta("datas.prop.label",		datas.prop.label)
	res = res .. "\n* " .. viewer.ta("datas.prop.image",		datas.prop.image)
	res = res .. "\n* " .. viewer.ta("datas.prop.P18",			datas.prop.P18)
	datas.track_val = res
	["personlang"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "personlang",	["prop"] = "P1412", },
	["QITEM"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "QITEM",		["prop"] = "Q16222597", },
	["itemid"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "QITEM",		["prop"] = "Q16222597", ["syn"] = 2, },
	["label"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "label" ,		["prop"] = "label", },
	["sitelink"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "sitelink",	["prop"] = "sitelink", },
	["description"]		= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "description",["prop"] = "description", },
	["image"]			= { ["typ"] = "dat",	["need"] = 2,	["keyword"] = "image",		["prop"] = "P18", },
	--]]
	return res
end -- res = p.dats(frame)

function p.edit(frame) -- The read mode generates the normal result for read only users.
	datas.track_val = datas.track_val or ""
	local res = ""
	res = res .. "<b>Nothing to test</b> in: [[Auteur:Rical/Victor Hugo]]"
	datas.track_val = res
	return res
end -- res = p.edit(frame)

function p.read(frame) -- The read mode generates the normal result for read only users.
	datas.track_val = datas.track_val or ""
	local res = ""
	res = res .. "\n* <b>datas.get_item(p.args_known, QITEM)</b>"
--	datas.prop = datas.get_item(args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.
	datas.props = datas.get_item(p.args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.
	res = res .. datas.track_val
	datas.track_val = res
	return res
end -- res = p.read(frame)

function p.tests(frame) -- The read mode generates the normal result for read only users.
	datas.track_val = datas.track_val or ""
	local res = ""
--	res = res .. "<b>Nothing to test</b> in: [[Auteur:Rical/Victor Hugo]]"
	res = res .. "\n* <b>datas.get_datas(p.args_known, QITEM)</b>"
	datas.prop = datas.get_datas(p.args_known, QITEM) -- Get datas from modes.args_known and add wikibase datas for the page.
	res = res .. datas.track_val
	res = res .. "\n* " .. viewer.ta("datas.prop.QITEM",		datas.prop.QITEM)
	res = res .. "\n* " .. viewer.ta("datas.prop.description",	datas.prop.description)
	res = res .. "\n* " .. viewer.ta("datas.prop.label",		datas.prop.label)
	res = res .. "\n* " .. viewer.ta("datas.prop.image",		datas.prop.image)
	res = res .. "\n* " .. viewer.ta("datas.prop.P18",			datas.prop.P18)
	datas.track_val = res
	return res
end -- res = p.tests(frame)

function Mediawiki_version() -- Form Mediawiki_version, in error color if it changes.
	local currentVersion = tostring(mw.site.currentVersion)
	return currentVersion
end -- function versn.Mediawiki_version()

function p.edit(frame) -- The read mode generates the normal result for read only users.
--	return main(frame)
	return datas.ModuleAuteur2_20161214() -- From Tpt on 2016-12-14 in ModuleAuteur2 20161214.lua
end

return p

--	Utilisateur:Rical/MediawikiVersion		-- Module to test, last change : 2018-01-12 à 20:58:47
--	Module:MediawikiVersion/Documentation	-- Module to test, last change : 2018-01-12 à 20:58:47
--	Module:MediawikiVersion					-- Module to test, last change : 2018-01-12 à 20:58:47

--	Usual pages for Translations (for easier select the test page when edit this module in other wikis)
--	Modulenn:Central-s-br/doc				{{#invoke:Central-s-br|read}}	br = Breton = Brezhoneg
--	Modul:Central-s-de/Doku					{{#invoke:Central-s-de|read}}	de = German = Deutsch
--	Module:Central-s-en/Documentation		{{#invoke:Central-s-en|read}}	en = English = English
--	Module:Central-s-es/Documentación		{{#invoke:Central-s-es|read}}	es = Spanish = español
--	Modul:Central-w-hu/doc					{{#invoke:Central-w-hu|read}}	hu = Hungarian = Magyar
--	Module:Central-mw-en/doc				{{#invoke:Central-mw-en|read}}	en = English = English
--	Mô đun:Central-w-vi/tài liệu			{{#invoke:Central-w-vi|read}}	vi = Vietnamese = Tiếng việt
--	MediaWiki:Scribunto/Central modules reference manual
--	Module:Central-s-fr/Documentation		{{#invoke:Central-s-fr|read}}	fr = French = Français proto

--	Module:Tests							-- Module for some tests, last change : 2018-01-12 à 20:58:47
--	Module:Tests/Documentation				-- For some tests

--	Before new tests pages
--	Auteur:Rical/Nelson Mandela				-- (Q8023)-for Module:Central-s-fr
--	Auteur:Rical/Victor Hugo				-- (Q535)-for Module:Central-s-fr
--	Utilisateur:Rical/Victor Hugo (Q535)	-- content Module:Author3
--	Utilisateur:Rical/Nelson Mandela (Q8023)-- content Module:Central-s-fr/Documentation
--	Utilisateur:Rical/Auteur:Nelson Mandela (Q8023)-- content Module:Central-s-fr/Documentation

--	After the last tests page at 2018-01-22T08:16:00 
--	Module:Tpt								-- (Re-use ModuleAuteur2 20161214.lua)
--	ModuleTpt/Victor Hugo					-- (Q535)-for Module:Central-s-fr
--	Module:Author3							-- (ModuleAuthor3 (image ok)run)
--	Auteur3:Aristote						-- (New tests for Module:Author3) (actuelle)
--	Auteur3:Nelson Mandela					-- (Q8023)-- content Module:Central-s-fr/Documentation
--	Module:Central-s-fr/Galilée				-- (Q307)-for Module:Central-s-fr
--