Module:Author3

From Wikipedia

Documentation for this module may be created at Module:Author3/doc

--[[ Module:Author3

-- relire ControlArgs/Author : module code in english

-- Fait : Si generDocBox est hors de Module ou Modèle alors : erreur et categorie "erreur d'utilisation"

-- relire ControlArgs/Author : module code in english

-- A faire : Titus Livius (Q2039), format de dates : P569 = date of birth = 59 BCE, P570 = date of death = 17

-- A faire : Dans wikidata Toutes les propriétés ou dans Personne j'ai trouvé langue native P103 et langues parlés P1412, à expérimenter.

== Services aux modules appelants ==
* La détection et l'utilisation de nombres décimaux et de nombres romains dans du texte.
* Le calcul des siècles et époques à partir des années, pour plusieurs régions, définies dans une table facile à compléter.

-- Fait : link •  Fac-similés, si index ? 
-- https://fr.wikisource.org/wiki/Sp%C3%A9cial:IndexPages?key=Victor+Hugo
-- https://fr.wikisource.org/wiki/Auteur:Victor_Hugo

-- A faire ? Faut-il demander à wikidata un champ "type de droit d'auteur" ?
-- voir P577. --LBE (d) 1 juin 2014
https://www.wikidata.org/wiki/Property:P275 = license = public domain in The Roman Sentinel (Q15677329)

-- A faire ? un argument pour les auteurs dont le style ne correspond pas au siècle selon la naissance.
L'information technique de la date de naissance ne correspond que statistiquement au classement subjectif d'un auteur dans un groupe désigné approximativement à postériori par un numéro de siècle. C'est cette approximation humaine qui provoque une gêne si l'on n'en prend pas conscience. Les auteurs qui ont participé aux mouvements litéraires de deux "siècles" le montrent bien.
* Comment résoudre cette ambigüité sans le modèle ? faut-il :
* utiliser un nouvel argument, dédié à ces cas :  genre, époque, mouvement littéraire
* utiliser un argument existant comme siècle, qui ne sera utilisé en même temps que l'année que dans ces cas
* utiliser la description pour exprimer ces cas, mais on n'a pas alors de classement en catégorie.

-- * Questions de migration vers Module:Auter
-- Adapter les erreurs et catégories de maintenance aux besoins.
-- Adapter la liste des notices à ws:fr.
-- Vérifier tous les tests unitaires pour oublier moins de cas.
-- initiales automatiques trop difficiles (premiere lettre du dernier mot).
-- répondre à tous les "A faire ?" ci_dessous

-- A faire : debug for stable interprojet with Tpt

-- A faire ? limiter la liste des notices d'autorites selon la langue du wiki.

-- A faire : Catégorie sans numero de siecle < 0 : Catégorie:Auteurs du e siècle av. J.-C. ,

-- A faire : generer une erreur err_roman2int sur les valeurs de nombres romains.

-- A faire : Ajouter la "Catégorie:Droits d’auteur 50 ans". Et la valeur par défaut 70 ans.
-- Quand on crée un nouvel auteur avec le formulaire automatique, la valeur par défaut pour les droits est : 50 ans (canadien) - serait-il possible de mettre par défaut 70 ans, sinon on risque des problèmes en n'ayant pas pris le temps de vérifier la nationalité de l'auteur (qui est français 99/100).
-- https://fr.wikisource.org/wiki/Discussion_utilisateur:Tpt#Param.C3.A9trage_en_cr.C3.A9ation_Auteur
-- J’ai ajouté la catégorisation dans Catégorie:Droits d’auteur 50 ans. Il faut attendre avant que tous les auteurs y apparaissent. (Ça m'a permis de voir deux erreurs que j’ai faites…) Aristoi (d) 19 mars 2014 à 18:28 (UTC)

-- a faire ? demander a wikidata un champ "type de droit d'auteur"

-- a faire ? demander a wikidata un champ "date d'une oeuvre"

-- a faire ? migrer la table args_known dans le sous module I18N, pour adapter la liste des notices à chaque wiki.

-- a faire ? "Catégorie:Domaine public en 2014"

-- a faire ? notices non coupees par un retour a la ligne. Le style est en place mais les navigateurs ne l'interprètent pas encore.

-- A faire : dans le bug "edit state" demander aussi "creation state" pour adapter ou remplacer l'automate.
-- voir https://fr.wikisource.org/wiki/Discussion_utilisateur:Tpt#Param.C3.A9trage_en_cr.C3.A9ation_Auteur
-- Quand on crée un nouvel auteur avec le formulaire automatique, la valeur par défaut pour les droits est : 50 ans (canadien) - serait-il possible de mettre par défaut 70 ans

-- A faire : debug interprojet stable avec Tpt
-- A faire : finaliser l'intégration de microformat avec Tpt

-- A faire : Dans le calcul des époques et siècles, il y a une ambiguité depuis longtemps : le libelé des siècles est "Naissance en 1876" alors que les époques sont basées sur l'âge de publication à partir de 20 ans. A la transition entre siècles et époques il y a un flou.

-- A faire : droits d'auteur, dans les box renvoyer vers l'aide.
-- A faire : droits d'auteur, ajouter l'aide DP 1923 + DP-EU + DP-US

-- A faire : HTMLscans et HTMLnotice avec fr.wikipedia international i18n
-- A faire : Modules should be in English (while docs are not) Guerrit : https://gerrit.wikimedia.org/r/95407
-- En attente : Detect the edit state to adapt help messages to user errors https://bugzilla.wikimedia.org/show_bug.cgi?id=51660

-- a faire ? mode et/ou option "notice" pour les notices choisies par les arguments ?
-- a faire ? mode et/ou option "notices" pour les notices venant de wikidata ?

-- a faire ? Selection de notices : limiter le nombre par un maxi. trier les notices dans l'ordre prefere pour un wiki. Ne demander a wikidata que les notices necessaires ?
-- a faire ? limiter le nombre de notices avec une liste de priorités entre elles, par le paramètre args_known { priority = 2... }
-- a faire ? notices multiples : traiter toutes les notices multiples. Voir Johnny Hallyday wikidata ISNI.

-- a faire ? Il serait bon d'inscrire dans l'espace de noms "Auteur:" la mention de la date estimée de fin des droits d'auteur exclusifs de ces auteurs connus (avec le pays où ces droits sont issus), afin de repérer leurs oeuvres publiées illégalement — Verdy_p (d) 18 février 2014 à 02:23 ?
-- a faire ? Signaler pour chaque oeuvre le debut probable du domaine public (et les elements sur lesquels il est basé)
-- a faire ? Calculer pour chaque oeuvre le debut probable du domaine public, dans les cas les plus courants. Et signaler sinon les limites du calcul.

-- a faire ? Utiliser les notices dans le Modèle:Document.

-- Traces de discussions pour debug ou évolutions :
-- Pour les années de naissance avant 1901, le mettre en catégories de siècles. Le Modèle:Epoque ne génère pas de catégories d’années avant 1901, voir la documentation. De mémoire, parce qu'elles sont trop dispersées et que ces catégories servent surtout à repérer chaque année les auteurs nouvellement publiables. --Rical (d) 9 novembre 2012 à 21:04 (UTC)
-- Certaines catégories sont étranges. « Auteurs par pays : », « Auteurs par pseudo », etc. Est-ce que ce serait possible de mettre à jour ce modèle pour le faire correspondre aux catégories qui existent déjà ? Marc (d) 3 avril 2013 à 10:49 (UTC)
-- Catégorie:Femmes auteurs
-- Catégorie:Auteurs par nationalité [×] Auteurs anglais‎ (142 P) Catégorie:Auteurs anglais
-- [+] Auteurs par pseudo‎ (1 C) à modifier -> Catégorie:Pseudonymes
-- Auteurs par pays : n'existe pas
-- [×] Auteurs morts pour la France‎ (15 P) Catégorie:Auteurs morts pour la France
-- [+] Auteurs par période‎ (12 C, 1 P) Catégorie:Auteurs par période

-- fait : notices multiples : traiter les notices multiples en prenant la pemiere seulement. Voir Johnny Hallyday wikidata ISNI.
-- fait : source d'argument à modifier dans interact_args = "inter"
-- fait : 4 fonctions d'interfaces : normal, notice, doc, tests
-- fait : Catégories automatiques d’années depuis les derniers 100 ans

-- doc : need="0" not necessary argument
-- need="1" necessary from argument
-- need="2" necessary from argument or module interaction

-- Interactions entre parametres et doc (exemples : titre = prenom+nom, l'initiale vient du nom)

-- doc : Ce module peut porter d'autres noms dans d'autres langues, le code etant identique.
-- doc : couleurs des origines des arguments en doc
-- doc : <code>module</code>
-- doc : Lors de la création d'une page d'auteur, établir le lien wikisource avec wikidata.
-- doc : Le modèle definissait les années incertaines par plusieurs paramètres.
-- doc : Le module reconnait l'année dans le texte libre du paramètre.
-- doc : http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual
-- doc perso : aller a une ligne de code en edit https://test2.wikipedia.org/w/index.php?title=Module:Auteur&action=edit#mw-ce-l3399
-- doc : Assistance internationale : un administrateur peut assister un wiki inconnu en selectionner une langue qu'il connait pour lire les messages et noms d'arguments. Demander une evolution pour connaitre la langue de l'utilisateur ( bug NNNN ).

-- doc : valeurs autorisées pour un argument à valeurs multiples, exemple pour la région : china/india/century/other
-- voir : arg_values = "region_values", key_values = "other/china/india/century"
-- pour region et droits d'auteur, dans p.args_known p.args_source et i18n.erreur_de_valeur et module avec erreur
]]

--	Module dependencies. Dependencias del módulo. Dépendances du module.
local MathRoman = require "Module:MathRoman"
local CA = require "Module:ControlArgs"
local Interprojet = require "Module:Interprojet"

local annotations = {}
annotations["lastname"] = "fn"
annotations["firstname"] = "n"
annotations["description"] = "label"
annotations["birthyear"] = "bday"
annotations["deathyear"] = "dday"

local microformat = function(data)
	if data ~= " cette instruction desactive microformat pour debug. " then return "" end
	local text = {}
	local style = "display:none; speak:none;"
	for n,v in pairs(data) do
		local class = annotations[n]
		local datum = mw.text.tag({name="span", contents=v, params={id=n,class=class}})
		table.insert(text, datum)
	end
	return mw.text.tag({name="div", contents=table.concat(text), params={id="ws-data", class="vcard ws-noexport", style=style}})
end

------------------------------------------------------------
-- Interface from the module to the template
-- Interface du module pour le modèle
------------------------------------------------------------

local p = {}
local AT = p

-- CA.nowyear = tonumber(os.date("%Y") ) -- local now_date = os.date("%Y-%m-%d %H:%M:%S")

CA.constants = CA.constants or {}
-- Categorize the year of death for 100 years
-- Clasificar el año que murió hace 100 años
-- Catégoriser l'année de décès depuis 100 ans
CA.constants.categorise_death_for_n_years = 100 -- normal = 100
-- Start writing an author after birth
-- Comience a escribir un autor después de su nacimiento
-- Début d'écriture d'un auteur après la naissance
CA.constants.author_writing_after_birth = 20
-- Finished writing a writer before his death
-- Terminó escribiendo un escritor antes de su muerte
-- Fin d'écriture d'un auteur avant son décès
CA.constants.author_writing_before_death = 5
-- Limit of normal life
-- Límite de la vida normal
-- Limite de durée de vie normale
CA.constants.lifetime_limit = 120
-- Limit of normal time writing of an author
-- Límite de tiempo normal de escribir de un autor
-- Limite normale de durée d'écriture d'un auteur
CA.constants.author_writing_time_limit = CA.constants.lifetime_limit - CA.constants.author_writing_after_birth - CA.constants.author_writing_before_death

-- Translation in i18n tables. Tables de traductions i18n.
p.i18n_args = { }
p.i18n_args.en = { -- English translations of arguments, categories and messages :
	[1]							= "1",
	["1"]						= "1",
	label						= 'label',
	sitelink					= 'sitelink',
	mode						= "mode",
	lastname					= 'lastname',
	initiale					= 'initiale',
	familyname					= 'familyname',
	firstname					= 'firstname',
	pseudonym					= 'pseudonym',
	title						= 'title',
	galliname					= 'galliname',
	sex							= 'sex',
	sortkey						= 'sortkey',
	image						= 'image',
	birthyear					= 'birthyear',
	birth						= 'birth',
	birthcentury				= 'birthcentury',
	birthuncertain				= 'birthuncertain',
	region						= 'region', -- argument with verified multiple values
	region_values				= 'other/china/india/century',
	args_values_err				= "Abnormal value of the argument '''%1 = %2''' (%3)",
	epoch						= 'epoch',
	deathyear					= 'deathyear',
	death						= 'death',
	deathcentury				= 'deathcentury',
	deathuncertain				= 'deathuncertain',
	description					= 'description',
	occupation					= 'occupation',
	genre						= 'genre',
	language					= 'language',
	languages					= 'languages',
	nationality					= 'nationality',
	prize						= 'prize',
	wikipedia					= 'wikipedia',
	wikiquote					= 'wikiquote',
	commons						= 'commons',
	notices						= 'notices',
	indexpages					= 'indexpages', -- IndexPages
	rights						= 'rights', -- argument with verified multiple values
	rights_values				= '70/50/mpf/none',
	rights_values_cat_70		= "Author in public domain in USA",
	rights_values_box_70		= "DP-EU-Auteur",
	rights_values_cat_50		= "Author in public domain in Canada",
	rights_values_box_50		= "-",
	rights_values_cat_mpf		= "Author death for France",
	rights_values_box_mpf		= "-",
	rights_values_cat_none		= "-",
	rights_values_box_none		= "-",
	commonscat					= 'commonscat',
	namespace					= 'space',
	category					= 'Category',
	catspace					= 'catspace',

	-- oldargs selon wikisource Modèle:Auteur/Documentation le 05/01/2014
	birth_text					= 'birthText',
	death_text					= 'deathText',
	birth_type					= 'birthType',
	death_type					= 'deathType',
	birth_link					= 'birthLink',
	death_link					= 'deathLink',
	birth_link2					= 'birthLink2',
	death_link2					= 'deathLink2',

	-- Scans and Notices
	author_scans_text			= 'Scans and authorities',
	author_Notices				= 'Notices',
	ARC							= 'ARC',
	ARCgeo						= 'ARCgeo',
	ARCid						= 'ARCid',
	ARCitem						= 'ARCitem',
	ARCorg						= 'ARCorg',
	ARCsub						= 'ARCsub',
	ARCHIVE						= 'ARCHIVE',
	BNF							= 'BNF',
	BNFbook						= 'BNFbook',
	DNB							= 'DNB',
	GKD							= 'GKD',
	GKD_V1						= 'GKD_V1',
	GND							= 'GND',
	IA							= 'IA',
	IBL							= 'IBL',
	IBLid						= 'IBLid',
	IBLbook						= 'IBLbook',
	IMDb						= 'IMDb',
	ISBN						= 'ISBN',
	ISFDB						= 'ISFDB',
	ISFDBid						= 'ISFDBid',
	ISFDBpub					= 'ISFDBpub',
	ISFDBtitle					= 'ISFDBtitle',
	ISNI						= 'ISNI',
	LCCN						= 'LCCN',
	LCCNid						= 'LCCNid',
	LT							= 'LT',
	NDL							= 'NDL',
	NKC							= 'NKC',
	NLA							= 'NLA',
	OCLC						= 'OCLC',
	OL							= 'OL',
	OLbook						= 'OLbook',
	PND							= 'PND',
	SELIBR						= 'SELIBR',
	SUDOC						= 'SUDOC',
	SWD							= 'SWD',
	ULAN						= 'ULAN',
	VIAF						= 'VIAF',
	WORLDCAT					= 'WORLDCAT',
	WORLDCATbook				= 'WORLDCATbook',
	WORLDCATch					= 'WORLDCATch',
	WORLDCATid					= 'WORLDCATid',
	authorities_selector		= "VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat,6,NLA,PND,GKD,ARC",

	-- Categories and Various messages
	--	wanted_error				= "EN wanted error",
	authors_authors				= "Authors",
	authors_initiale_txt		= "Authors&nbsp;%1",
	authors_initiale_cat		= "Authors-%1",
	entityid_txt				= "Structured Data",
	authors_birthyear			= 'Born in %1',
	authors_deathyear			= 'Death in %1',
	authors_birth_century		= "Born in %1..",
	authors_death_century		= "Death in %1..",
	list_limit_levelmaxi		= "Structure limit levelmaxi=%1",
	list_limit_maxn				= "Structure limit maxn=%1",
	limit_cat_birth_death		= 'Limit the years of categories "Births in" and "Death in".',
	cat_group_languages			= "Authors writing in %1",
	cat_epoch_china_antiquity	= "Author of Chinese antiquity",
	cat_epoch_china_springs		= "Author of Springs and Autumns",
	cat_epoch_china_empires		= "Author of Chinese empires",
--	cat_epoch_indian_indus		= "Author of Indus civilisation",
--	cat_epoch_indian_muslim		= "Author of Indo-Muslim period",
	cat_epoch_indian_antiquity	= "Author of Indian antiquity",
	cat_epoch_indian_classic	= "Author of classic Indian period",
	cat_epoch_indian_middle_age	= "Author of classic Indian Middle Age",
	cat_epoch_antiquity			= "Author of antiquity",
	cat_epoch_middle_age		= "Author of Middle Ages",
	cat_epoch_century_CE		= "Born in the %1th century",
	cat_epoch_century_BCE		= "Born in the %1th century B.C.",
	-- BCE = Before Common Era = «BC». AEC = Antes de la Era Común = «a. C.». AEC = Avant l'ère commune = «av. J.-C.»
	century_CE					= "%1 th century",
	century_BCE					= "%1 th century B.C.",
	year_BCE					= "%1 B.C.",

	-- Error messages and categories
	-- These messages should also include those of module(s) called.
	err_one_number_argument		= "Error: In parameter '''%1''', enter a single number between -5000 and now.",
	err_delete_docbox			= "This documentation/support must be removed before recording. Remove all modes to return to normal mode.",
	err_assist_user_param		= "User support for checking the settings:",
	err_module_error			= "Module error",
	msg_automatic_argument		= "Verify the automatic argument '''%1'''.",
	msg_unknown_auto_arg		= "Internal Error: Unknown automatic argument : %1 = '''%2'''.",
	msg_auto_val_warning		= "Verify the automatic argument: %1 = '''%2'''.",
	msg_auto_val_unknown		= "Internal Error: Unknown automatic argument: %1 = '''%2'''.",
	err_no_known_arguments		= "Module without known arguments table.",
	--
	err_vague_year				= "Uncertain year.",
	err_death_before_birth		= "Error: death '''%1''' is before birth '''%2'''.",
	err_death_before_birth_cat	= "Author death is before birth.",
	err_life_too_long			= "Life is too long from %1 to %2.",
	err_life_too_long_cat		= "Life of author is too long",

	date_to_part_format			= " dd yyyy mmmm",
	date_to_part_call_err		= "Internal Error: Abnormal calling arguments in date '''%1''', '''%2'''.",
	date_to_part_call_cat		= "Module with internal error",
	date_to_part_err_not_found	= "Internal Error: No part found in date '''%1''', '''%2'''.",

	err_vague_epoch				= "Uncertain times.",
	err_unknown_epoch_cat		= "Unknown epoch",
	err_year_in_roman_number	= "Ambiguity: the year '''%1''' is in roman numerals. Do you want define a century ?",
	err_roman2int				= "Error in roman number in argument %1 = '''%2''' ; %3 %4. ",
	err_notices_properties		= "Internal Error: An authority record is undefined : %1.",
	err_notices_properties_cat	= "Internal Error: One or more authority record is undefined.",

	docbox_namespace_valid		= "Help Mod-ule Project Template",
	docbox_namespace_stop		= "Aut-eur Ma-in Page",
	docbox_namespace_error		= "Auteur Main Page",
	docbox_namespace_error_cat	= "Module with usage error",
	docbox_namespace_error_err	= "The documentation panel is forbidden in space '''%1:'''. Return to normal mode by removing all modes.",

	-- These messages are used to Cargs = ControlAgrs module and are copied here.
	c							= 'c',
	debug						= "debug",
	options						= 'options',
	err_error_list_header		= "User support about parameters:",
	err_unknown_argument		= "Error: parameter '''%1''' is unknown in this template. Check the name or flag this gap.",
	err_nearest_argument		= "Error: the known argument '''%1''' is it the one you need ?",
	err_value_re_defined		= "Error: the value of the argument '''%1''' is already defined. Choose only one argument and value.",
	err_need_value				= "Error: This argument is required but absent : '''%1'''. Should define it.",
	err_none_value				= "Error: No argument has been defined.",
	err_too_unnamed_arguments	= "Error: Too many unnamed arguments ( '''%1''' ).",
	err_internal_notice_wsid	= "Internal Error: Notify the developer that the internal argument '''%1''' is unknown in the records.",
	err_notice_link				= "Error: bad notice for '''%1'''.",
	err_notice_link_cat			= "Module with bad notice",
	list_limit_levelmaxi		= "List limit levelmaxi=%1",
	list_limit_max_n			= "List limit max_n=%1",
	err_module_miss_i18n_cat	= "Module missing i18n translation",
} -- p.i18n_args.en

p.i18n_args.es = { -- Traducciones al español de los argumentos, categorías y mensajes:
	[1]							= "1",
	["1"]						= "1",
	label						= 'label',
	sitelink					= 'sitelink',
	mode						= "modo",
	lastname					= 'nombre',
	initiale					= 'initiale',
	familyname					= 'primernombre',
	firstname					= 'apellido',
	pseudonym					= 'apodo',
	title						= 'título',
	galliname					= 'apellidoGalli',
	sex							= 'sexo',
	sortkey						= 'clave', -- especie 
	image						= 'imagen',
	birthyear					= 'año de nacimiento',
	birth						= 'nacimiento',
	birthcentury				= 'siglo de nacimiento',
	birthuncertain				= 'nacimiento incierto',
	region						= 'región',
	region_values				= 'otros/china/india/siglo',
	args_values_err				= "Valor anormal del argumento '''%1 = %2''' (%3)",
	epoch						= 'epoch',
	deathyear					= 'año de la muerte',
	death						= 'muerte',
	deathcentury				= 'siglo de la muerte',
	deathuncertain				= 'muerte incierto',
	description					= 'descripción',
	occupation					= 'profesión',
	genre						= 'tipo',
	language					= 'lengua',
	languages					= 'lenguas',
	nationality					= 'país',
	prize						= 'premio',
	wikipedia					= 'wikipedia',
	wikiquote					= 'wikiquote',
	commons						= 'commons',
	notices						= 'registros',
	indexpages					= 'indexpages', -- IndexPages
	rights						= 'derechos',
	rights_values				= '70/50/mpf/nada',
	rights_values_cat_70		= "Autores en el dominio público en los Estados Unidos",
	rights_values_box_70		= "DP-EU-Auteur",
	rights_values_cat_50		= "Autores en el dominio público en Canadá",
	rights_values_box_50		= "-",
	rights_values_cat_mpf		= "Autores que murieron por Francia",
	rights_values_box_mpf		= "-",
	rights_values_cat_none		= "-",
	rights_values_box_none		= "-",
	commonscat					= 'commonscat',
	namespace					= 'espacio',
	category					= 'Categoría',
	catspace					= 'catespacio',

	-- oldargs selon wikisource Modèle:Auteur/Documentation le 05/01/2014
	birth_text					= 'textNacido',
	death_text					= 'textMuerto',
	birth_type					= 'nacimientoTipo',
	death_type					= 'muertoTipo',
	birth_link					= 'enlaceNacimiento',
	death_link					= 'enlaceMuerto',
	birth_link2					= 'enlace2Nacimiento',
	death_link2					= 'enlace2Muerto',

	-- Scans and Notices
	author_scans_text			= 'Escanea y autoridades',
	author_Notices				= 'Avisos',
	ARC							= 'ARC',
	ARCgeo						= 'ARCgeo',
	ARCid						= 'ARCid',
	ARCitem						= 'ARCitem',
	ARCorg						= 'ARCorg',
	ARCsub						= 'ARCsub',
	ARCHIVE						= 'ARCHIVE',
	BNF							= 'BNF',
	BNFbook						= 'BNFbook',
	DNB							= 'DNB',
	GKD							= 'GKD',
	GKD_V1						= 'GKD_V1',
	GND							= 'GND',
	IA							= 'IA',
	IBL							= 'IBL',
	IBLid						= 'IBLid',
	IBLbook						= 'IBLbook',
	IMDb						= 'IMDb',
	ISBN						= 'ISBN',
	ISFDB						= 'ISFDB',
	ISFDBid						= 'ISFDBid',
	ISFDBpub					= 'ISFDBpub',
	ISFDBtitle					= 'ISFDBtitle',
	ISNI						= 'ISNI',
	LCCN						= 'LCCN',
	LCCNid						= 'LCCNid',
	LT							= 'LT',
	NDL							= 'NDL',
	NKC							= 'NKC',
	NLA							= 'NLA',
	OCLC						= 'OCLC',
	OL							= 'OL',
	OLbook						= 'OLbook',
	PND							= 'PND',
	SELIBR						= 'SELIBR',
	SUDOC						= 'SUDOC',
	SWD							= 'SWD',
	ULAN						= 'ULAN',
	VIAF						= 'VIAF',
	WORLDCAT					= 'WORLDCAT',
	WORLDCATbook				= 'WORLDCATbook',
	WORLDCATch					= 'WORLDCATch',
	WORLDCATid					= 'WORLDCATid',
	authorities_selector		= "VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat,6,NLA,PND,GKD,ARC",

	-- Categorías y Varios mensajes
	-- Estos mensajes deben incluir también los de módulo(s) llamado.
	--	error_deseada				= 'ES error deseada',
	authors_authors				= "Autores",
	authors_initiale_txt		= "Autores&nbsp;%1",
	authors_initiale_cat		= "Autores-%1",
	entityid_txt				= "Estructurado Datos",
	authors_birthyear			= 'Nacido en el año %1',
	authors_deathyear			= 'Muerte en %1',
	authors_birth_century		= "Nacido en el año %1..",
	authors_death_century		= "Muerte en %1..",
	list_limit_levelmaxi		= "Limite de la estructura levelmaxi=%1",
	list_limit_maxn				= "Limite de la estructura maxn=%1",
	limit_cat_birth_death		= 'Limite los años de las categorías "Nacimientos en" y "Muerte en".',
	cat_group_languages			= "Autores que escriben en %1",
	cat_epoch_china_antiquity	= "Autor de la antigüedad china",
	cat_epoch_china_springs		= "Autor de Primaveras y Otoños",
	cat_epoch_china_empires		= "Autor de los Imperios chinos",
--	cat_epoch_indian_indus		= "Autor de la civilización del Indo",
--	cat_epoch_indian_muslim		= "Autor de el período indo-musulmán",
	cat_epoch_indian_antiquity	= "Autor de la antigüedad india",
	cat_epoch_indian_classic	= "Autor del período clásico de la India",
	cat_epoch_indian_middle_age	= "Autor de la Edad Media de la India",
	cat_epoch_antiquity			= "Autor de la antigüedad",
	cat_epoch_middle_age		= "Autor de la Edad Media",
	cat_epoch_century_CE		= "Nacido en el siglo del día 1%",
	cat_epoch_century_BCE		= "Nacido en el siglo a. C. día 1%",
	-- BCE = Before Common Era = «BC». AEC = Antes de la Era Común = «a. C.». AEC = Avant l'ère commune = «av. J.-C.»
	century_CE					= "%1 siglo",
	century_BCE					= "%1 siglo a. C.",
	year_BCE					= "%1 a. C.",

	-- Los mensajes de error y categorías
	-- Estos mensajes deben incluir también los de módulo(s) llamado.
	err_one_number_argument		= "Error: En el parámetro '''%1''', ingrese un número único entre -5000 y ahora.",
	err_delete_docbox			= "Esta documentación/apoyo debe ser removido antes de grabar. Retire todos los modos para volver al modo normal.",
	err_assist_user_param		= "Apoyo a los usuarios para comprobar los ajustes:",
	err_module_error			= "Module error",
	msg_automatic_argument		= "Verificar el argumento automático '''%1'''.",
	msg_unknown_auto_arg		= "Error interno: Argumento desconocido automático : %1 = '''%2'''.",
	msg_auto_val_warning		= "Verifique el argumento automático: %1 = '''%2'''.",
	msg_auto_val_unknown		= "Error interno: Argumento desconocido automático: %1 = '''%2'''.",
	err_no_known_arguments		= "Módulo sin argumentos tabla conocida.",
	--
	err_vague_year				= "Año incierto.",
	err_death_before_birth		= "Error: muerte '''%1''' antes del nacimiento '''%2'''.",
	err_death_before_birth_cat	= "Autor muerte antes del nacimiento.",
	err_life_too_long			= "La vida es demasiado largo de %1 a %2.",
	err_life_too_long_cat		= "Vida del autor es demasiado largo",

	date_to_part_format			= " dd mmmm yyyy",
	date_to_part_call_err		= "Error interno: Argumentos de llamadas anormales en la fecha '''%1''', '''%2'''.",
	date_to_part_call_cat		= "Módulo con error interno",
	date_to_part_err_not_found	= "Error interno: No parte encontrado en la fecha '''%1''', '''%2'''.",

	err_vague_epoch				= "Épocas inciertas.",
	err_unknown_epoch_cat		= "Desconocido período",
	err_year_in_roman_number	= "Ambigüedad: el año '''%1''' es en números romanos ¿Qué quieres definir un siglo?",
	err_roman2int				= "Error en el número romano en el argumento %1 = '''%2''' ; %3 %4. ",
	err_notices_properties		= "Error interno: Un registro de autoridad no está definido: %1.",
	err_notices_properties_cat	= "Error interno: Uno o más registro de autoridad no está definido.",

	docbox_namespace_valid		= "Help Mod-ule Project Template",
	docbox_namespace_stop		= "Aut-eur Ma-in Page",
	docbox_namespace_error		= "Auteur Main Page",
	docbox_namespace_error_cat	= "Módulo con error del uso",
	docbox_namespace_error_err	= "El panel del documentación está prohibido en el espacio '''%1:'''. Vuelva al modo normal mediante la eliminación de todos los modos.",

	-- Estos mensajes se utilizan para módulo Cargs = ControlAgrs, y se copian aquí.
	c							= 'c',
	debug						= "debug",
	options						= 'options',
	err_error_list_header		= "Asistencia en los parámetros del modelo en:",
	err_unknown_argument		= "Error: El parámetro '''%1''' es desconocido en este modelo. Compruebe el nombre o marca esta brecha.",
	err_nearest_argument		= "Error: la '''%1''' argumento conocido es el que necesita?",
	err_value_re_defined		= "Error: el valor del argumento '''%1''' ya se ha definido. Elige uno sólo argumento y valor.",
	err_need_value				= "Error: Este argumento es necesario pero ausente : '''%1'''. Debe definir.",
	err_none_value				= "Error: Ningún argumento ha sido definido.",
	err_too_unnamed_arguments	= "Error: Demasiados argumentos sin nombre ( '''%1''' ).",
	err_internal_notice_wsid	= "Error interno: Notificar al promotor que el argumento interno '''%1''' es desconocida en los registros.",
	err_notice_link				= "Error: mala nota por '''%1'''.",
	err_notice_link_cat			= "Módulo con mala nota",
	list_limit_levelmaxi		= "Límite de la lista levelmaxi=%1",
	list_limit_max_n			= "Límite de la lista max_n=%1",
	err_module_miss_i18n_cat	= "Módulo faltante traducción i18n",
} -- p.i18n_args.es

p.i18n_args.fr = { -- Traductions en francais des arguments, catégories et messages :
	-- to debug for arg 1, arg 2 :
	[1]							= "1",
	["1"]						= "1",
	label						= 'label',
	sitelink					= 'sitelink',
	mode						= "mode",
	lastname					= 'nom',
	initiale					= 'initiale',
	familyname					= 'nomfamille',
	firstname					= 'prénom',
	pseudonym					= 'pseudo',
	title						= 'titre',
	galliname					= 'prénomGalli',
	sex							= 'sexe',
	sortkey						= 'cle',
	image						= 'image',
	birthyear					= 'anneeNaissance',
	birth						= 'naissance',
	birthcentury				= 'siecleNaissance',
	birthuncertain				= 'incertitudeNaissance',
	region						= 'région',
	region_values				= "autre/chine/inde/siècle",
	args_values_err				= "Valeur anormale de l'argument '''%1 = %2''' (%3)",
	epoch						= 'époque',
	deathyear					= 'anneeDeces',
	death						= 'deces',
	deathcentury				= 'siecleDeces',
	deathuncertain				= 'incertitudeDeces',
	description					= 'description',
	occupation					= 'metier',
	genre						= 'genre',
	language					= 'langue',
	languages					= 'langues',
	nationality					= 'pays',
	prize						= 'prix',
	wikipedia					= 'wikipedia',
	wikiquote					= 'wikiquote',
	commons						= 'commons',
	notices						= 'notices',
	indexpages					= 'indexpages', -- IndexPages
	rights						= 'droits',
	rights_values				= '70/50/mpf/non',
	rights_values_cat_70		= "Auteurs dans le domaine public aux États-Unis",
	rights_values_box_70		= "DP-EU-Auteur",
	rights_values_cat_50		= "Auteurs dans le domaine public au Canada",
	rights_values_box_50		= "-",
	rights_values_cat_mpf		= "Auteurs morts pour la France",
	rights_values_box_mpf		= "-",
	rights_values_cat_none		= "-",
	rights_values_box_none		= "-",
	commonscat					= 'commonscat',
	namespace					= 'espace',
	category					= 'Category',
	catspace					= 'catspace',

	-- oldargs par selon wikisource Modèle:Auteur/Documentation le 05/01/2014
	birth_text					= 'texteNaissance',
	death_text					= 'texteDeces',
	birth_type					= 'typeNaissance',
	death_type					= 'typeDeces',
	birth_link					= 'lienNaissance',
	death_link					= 'lienDeces',
	birth_link2					= 'liaisonNaissance',
	death_link2					= 'liaisonDeces',

	-- Scans et Notices
	author_scans_text			= 'Scans et notices',
	author_Notices				= 'Notices', -- search BNF
	ARC							= 'ARC',
	ARCgeo						= 'ARCgeo',
	ARCid						= 'ARCid',
	ARCitem						= 'ARCitem',
	ARCorg						= 'ARCorg',
	ARCsub						= 'ARCsub',
	ARCHIVE						= 'ARCHIVE',
	BNF							= 'BNF',
	BNFbook						= 'BNFbook',
	DNB							= 'DNB',
	GKD							= 'GKD',
	GKD_V1						= 'GKD_V1',
	GND							= 'GND',
	IA							= 'IA',
	IBL							= 'IBL',
	IBLid						= 'IBLid',
	IBLbook						= 'IBLbook',
	IMDb						= 'IMDb',
	ISBN						= 'ISBN',
	ISFDB						= 'ISFDB',
	ISFDBid						= 'ISFDBid',
	ISFDBpub					= 'ISFDBpub',
	ISFDBtitle					= 'ISFDBtitle',
	ISNI						= 'ISNI',
	LCCN						= 'LCCN',
	LCCNid						= 'LCCNid',
	LT							= 'LT',
	NDL							= 'NDL',
	NKC							= 'NKC',
	NLA							= 'NLA',
	OCLC						= 'OCLC',
	OL							= 'OL',
	OLbook						= 'OLbook',
	PND							= 'PND',
	SELIBR						= 'SELIBR',
	SUDOC						= 'SUDOC',
	SWD							= 'SWD',
	ULAN						= 'ULAN',
	VIAF						= 'VIAF',
	WORLDCAT					= 'WORLDCAT',
	WORLDCATbook				= 'WORLDCATbook',
	WORLDCATch					= 'WORLDCATch',
	WORLDCATid					= 'WORLDCATid',
	authorities_selector		= "VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat,6,NLA,PND,GKD,ARC",
	-- Hsarrazin = VIAF, BNF, SUDOC + LCCN (référence internationale) + ISNI et Worldcat, plus autres
--	authorities_selector		= "VIAF,BNF,SUDOC", -- ,3,LCCN,ISNI,Worldcat", -- for tests only

	-- Catégories et Messages divers
	-- Ces messages doivent aussi intégrer ceux du (ou des) module(s) appelé(s).
	--	erreur_voulue				= 'FR erreur voulue',
	authors_authors				= "Auteurs",
	authors_initiale_txt		= "Auteurs&nbsp;%1",
	authors_initiale_cat		= "Auteurs-%1",
	entityid_txt				= "Données structurées",
	authors_birthyear			= 'Naissance en %1',
	authors_deathyear			= 'Décès en %1',
	authors_birth_century		= "Naissance en %1..",
	authors_death_century		= "Décès en %1..",
	list_limit_levelmaxi		= "Limite de la structure levelmaxi=%1",
	list_limit_maxn				= "Limite de la structure maxn=%1",
	limit_cat_birth_death		= 'Limite les années des catégories "Naissance en" et "Décès en".',
	cat_group_languages			= "Auteurs écrivant en %1",
	cat_epoch_china_antiquity	= "Auteurs de l'antiquité chinoise",
	cat_epoch_china_springs		= "Auteurs des Printemps et Automnes",
	cat_epoch_china_empires		= "Auteurs des Empires chinois",
--	cat_epoch_indian_indus		= "Auteurs de la civilisation de l'Indus",
--	cat_epoch_indian_muslim		= "Auteurs de la période indo-musulmane",
	cat_epoch_indian_antiquity	= "Auteurs de l'antiquité indienne",
	cat_epoch_indian_classic	= "Auteurs de période classique indienne",
	cat_epoch_indian_middle_age	= "Auteurs du moyen-âge indien",
	cat_epoch_antiquity			= "Auteurs de l’Antiquité",
	cat_epoch_middle_age		= "Auteurs du Moyen Âge",
	cat_epoch_century_CE		= "Auteurs du %1e siècle‎",
	cat_epoch_century_BCE		= "Auteurs du %1e siècle av. J.-C.",
	-- BCE = Before Common Era = «BC». AEC = Antes de la Era Común = «a. C.». AEC = Avant l'ère commune = «av. J.-C.»
	century_CE					= "%1 ème siècle",
	century_BCE					= "%1 ème siècle av. J.-C.",
	year_BCE					= "%1 av. J.-C.",

	-- Messages d'erreurs et catégories
	-- Ces messages doivent aussi intégrer ceux du (ou des) module(s) appelé(s).
	err_one_number_argument		= "Erreur : Dans le paramètre '''%1''', entrer un seul nombre entre -5000 et maintenant.",
	err_delete_docbox			= "Cette documentation/assistance doit être supprimée avant d'enregistrer. Supprimez tous les modes pour revenir en mode normal.",
	err_assist_user_param		= "Assistance à l'utilisateur pour la vérification des paramètres :",
	err_module_error			= "Module avec erreur",
	msg_automatic_argument		= "Vérifiez l'argument automatique '''%1'''.",
	msg_unknown_auto_arg		= "Erreur interne : Argument automatique inconnu : %1 = '''%2'''.",
	msg_auto_val_warning		= "Vérifiez l'argument automatique : %1 = '''%2'''.",
	msg_auto_val_unknown		= "Erreur interne: Argument automatique inconnu : %1 = '''%2'''.",
	err_no_known_arguments		= "Module sans table d'arguments connus.",
	--
	err_vague_year				= "Année incertaine.",
	err_death_before_birth		= "Erreur : le décès '''%1''' est avant la naissance '''%2'''.",
	err_death_before_birth_cat	= "Erreur : le décès est avant la naissance.",
	err_life_too_long			= "Durée de vie trop longue de %1 à %2.",
	err_life_too_long_cat		= "Durée de vie de l'auteur trop longue",
	err_module_miss_i18n_cat	= "Module avec erreur interne",

	date_to_part_format			= " dd mmmm yyyy",
	date_to_part_call_err		= "Erreur interne : argument d'appel anormal dans la date '''%1''', '''%2'''.",
	date_to_part_call_cat		= "Module avec erreur interne",
	date_to_part_err_not_found	= "Erreur interne : Partie non trouvée dans la date '''%1''', '''%2'''.",

	err_vague_epoch				= "Époque incertaine.",
	err_unknown_epoch_cat		= "Époque inconnue",
	err_year_in_roman_number	= "Ambigüité : l'année '''%1''' est en nombres romains. Voulez-vous définir un siècle ?",
	err_roman2int				= "Erreur de nombre romain dans l'argument %1 = '''%2''' ; %3 %4. ",
	err_notices_properties		= "Erreur interne: Une notice d'autorité n'est pas définie : %1.",
	err_notices_properties_cat	= "Module avec erreur interne.",

	docbox_namespace_valid		= "Help Mod-ule Project Template",
	docbox_namespace_stop		= "Aut-eur Ma-in Page",
	docbox_namespace_error		= "Auteur Main Page",
	docbox_namespace_error_cat	= "Module avec erreur d'utilisation",
	docbox_namespace_error_err	= "Le panneau de documentation est interdit dans l'espace '''%1:'''. Revenez en mode normal en supprimant tous les modes.",

	-- Ces messages servent au module CA = ControlAgrs, et sont copiés ici.
	c							= 'c',
	debug						= "debug",
	options						= 'options',
	err_error_list_header		= "Assistance sur les paramètres de ce modèle :",
	err_unknown_argument		= "Erreur : Le paramètre '''%1''' est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.",
	err_nearest_argument		= "Erreur: L'argument connu '''%1''' est-il celui que vous voulez ?",
	err_value_re_defined		= "Erreur : La valeur de l'argument '''%1''' est déjà définie. Choisir un seul argument et une seule valeur.",
	err_need_value				= "Erreur : Cet argument est nécessaire mais absent : '''%1'''. Il faut le définir.",
	err_none_value				= "Erreur : Aucun argument n'a été défini.",
	err_too_unnamed_arguments	= "Erreur : Trop de paramètres non nommés ( '''%1''' ).",
	err_internal_notice_wsid	= "Erreur interne : Signalez au developpeur que l'argument interne '''%1''' est inconnu dans les notices.",
	err_notice_link				= "Erreur : mauvaise notice pour '''%1'''.",
	err_notice_link_cat			= "Module avec erreur interne",
	list_limit_levelmaxi		= "Limite de liste levelmaxi=%1",
	list_limit_max_n			= "Limite de liste max_n=%1",
	err_module_miss_i18n_cat	= "Module manquant de traduction i18n",
} -- p.i18n_args.fr

------------------------------------------------------------
-- i18n end
------------------------------------------------------------

------------------------------------------------------------
-- MArgms object table start
------------------------------------------------------------
-- Special arguments to modify the fonctions and outputs of this module.
-- Argumentos spéciaux vierta modificadoras le fonctionnement et les salidas de módulo ce.
-- Arguments spéciaux pour modifier le fonctionnement et les sorties de ce module.

p.args_known_default = {

	[1] =			{typ = "dat", need = 0, list = 1, syn = 1,
		keyword = "mode"},

	mode =			{typ = "prg", need = 0, list = 1,
		keyword = "mode"},

	c =				{typ = "opt", need = 0, list = 1,
		keyword = "c", },

	debug =			{typ = "opt", need = 0, list = 1,
		keyword = "debug", },

	options =		{typ = "opt", need = 0, list = 1,
		keyword = "options", },

	-- All arguments have a keyword parameter identical to the registration name, except synonyms.
	-- Todos los argumentos tienen un parámetro keyword idéntica a la denominación registrada, a menos sinónimos.
	-- Tous les arguments ont un paramètre keyword identique au nom d'enregistrement, sauf les synonymes.

	label =		{typ = "dat", need = 0, list = 2,
		keyword = "label", prop = "label" },

	sitelink =		{typ = "dat", need = 0, list = 2,
		keyword = "sitelink" , prop = "sitelink"},

	lastname =		{typ = "dat", need = 0, list = 2,
		keyword = "lastname", prop = "label", },

	initiale =		{typ = "prg", need = 2, list = 2,
		keyword = "initiale", },

	familyname =	{typ = "dat", need = 0, list = 9,
		keyword = "familyname", },

	firstname =		{typ = "dat", need = 0, list = 2,
		keyword = "firstname", },

	pseudonym =		{typ = "ctr", need = 0, list = 9,
		keyword = "pseudonym", },

	title =			{typ = "dat", need = 2, list = 9,
		keyword = "title", },

	galliname =		{typ = "dat", need = 0, list = 9,
		keyword = "galliname", },

	sex =			{typ = "dat", need = 0, list = 9,
		keyword = "sex", },

	sortkey =		{typ = "dat", need = 2, list = 9,
		keyword = "sortkey", },

	image =			{typ = "dat", need = 0, list = 2,
		keyword = "image", prop = "18", },

	birthyear =		{typ = "dat", need = 0, list = 2,
		keyword = "birthyear", }, -- prop = "569", format = "year"},

	birth =			{typ = "dat", need = 0, list = 1,
		keyword = "birth", prop = "569"}, -- syn = 1,

	birthcentury =	{typ = "dat", need = 0, list = 2,
		keyword = "birthcentury", },

	birthuncertain ={typ = "dat", need = 0, list = 3,
		keyword = "birthuncertain", },

	region =		{typ = "dat", need = 0, list = 2,
		keyword = "region", arg_values = "region_values", key_values = "other/china/india/century" },

	epoch =			{typ = "dat", need = 0, list = 2,
		keyword = "epoch" },

	deathyear =		{typ = "dat", need = 0, list = 2,
		keyword = "deathyear", }, -- prop = "570", format = "year"},

	death =			{typ = "dat", need = 0, list = 1,
		keyword = "death", prop = "570"}, -- syn = 1,

	deathcentury =	{typ = "dat", need = 0, list = 2,
		keyword = "deathcentury", },

	deathuncertain ={typ = "dat", need = 0, list = 3,
		keyword = "deathuncertain", },

	description =	{typ = "dat", need = 0, list = 1,
		keyword = "description", },

	occupation =	{typ = "dat", need = 0, list = 3,
		keyword = "occupation", prop = "106", },

	genre =			{typ = "dat", need = 0, list = 3,
		keyword = "genre", },

	language =		{typ = "dat", need = 0, list = 3,
		keyword = "language", prop = "103", },

	languages =		{typ = "dat", need = 0, list = 3,
		keyword = "languages", prop = "1412", },

	nationality =	{typ = "dat", need = 0, list = 3,
		keyword = "nationality", prop = "27", }, -- country of citizenship

	prize =			{typ = "dat", need = 0, list = 4,
		keyword = "prize", },

	wikipedia =		{typ = "dat", need = 0, list = 4,
		keyword = "wikipedia", },

	wikiquote =		{typ = "dat", need = 0, list = 4,
		keyword = "wikiquote", },

	commons =		{typ = "dat", need = 0, list = 4,
		keyword = "commons", },

	notices =		{typ = "dat", need = 0, list = 4,
		keyword = "notices", },

	indexpages =	{typ = "dat", need = 0, list = 4,
		keyword = "indexpages", }, -- IndexPages
		
	entityid =		{typ = "dat", need = 0, list = 4,
		keyword = "entityid" , prop = "entityid"},

	rights =		{typ = "dat", need = 0, list = 1,
		keyword = "rights", arg_values = "region_values", key_values = "70/50/mpf/none" },

	commonscat =	{typ = "ctr", need = 0, list = 3,
		keyword = "commonscat", },

	namespace =		{typ = "ctr", need = 0, list = 4,
		keyword = "namespace", },

	category =		{typ = "ctr", need = 0, list = 3,
		keyword = "category", },

	-- Obsolete old arguments from wikisource Modèle:Auteur/Documentation le 05/01/2014
	-- obsoleto viejos argumentos de wikisource Modèle:Auteur/Documentation le 05/01/2014
	-- Obsolète anciens arguments selon wikisource Modèle:Auteur/Documentation le 05/01/2014

	birth_text =	{typ = "oldargs", need = 0, list = 9,
		keyword = "birth_text", },

	death_text =	{typ = "oldargs", need = 0, list = 9,
		keyword = "death_text", },

	birth_type =	{typ = "oldargs", need = 0, list = 9,
		keyword = "birth_type", },

	death_type =	{typ = "oldargs", need = 0, list = 9,
		keyword = "death_type", },

	birth_link =	{typ = "oldargs", need = 0, list = 9,
		keyword = "birth_link", },

	death_link =	{typ = "oldargs", need = 0, list = 9,
		keyword = "death_link", },

	birth_link2 =	{typ = "oldargs", need = 0, list = 9,
		keyword = "birth_link2", },

	death_link2 =	{typ = "oldargs", need = 0, list = 9,
		keyword = "death_link2", },

	-- arguments managed only by program, not read from template
	catspace =		{typ = "prg", need = 0, list = 9,
		keyword = "catspace", },

	limit_cat_birth_death = {val = "100", typ = "prg", need = 0, list = 9,
		keyword = "catspace", },

	------------------------------------------------------------
	-- Table de notices de notoriétés pour auteurs livres et autres
	------------------------------------------------------------
	-- The arguments for authority records are treated separately
	-- Les arguments pour les notices d'autorités sont traités à part

	ARC =			{typ = "not", need = 0, list = 3,
		keyword = "ARC", base_base = "ARC", base_id = "ARC", not_type = "Author",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExternalPersonIdSearch?id=REF_1", },

	ARCgeo =		{typ = "not", need = 0, list = 3,
		keyword = "ARC", base_base = "ARC", base_id = "ARCgeo", not_type = "Geo",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExecuteRelatedGeographicalSearch?id=REF_1", },

	ARCid =			{typ = "not", need = 0, list = 3,
		keyword = "ARCid", base_base = "ARC", base_id = "ARCid", not_type = "Author",
		base_test = "R457-J-44", -- ARCid = "R457-J-44"
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExternalPersonIdSearch?id=REF_1", },

	ARCitem =		{typ = "not", need = 0, list = 3,
		keyword = "ARCitem", base_base = "ARC", base_id = "ARCitem", not_type = "Book",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExternalIdSearch?id=REF_1", },

	ARCorg =		{typ = "not", need = 0, list = 3,
		keyword = "ARCorg", base_base = "ARC", base_id = "ARCorg", not_type = "Org",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExecuteRelatedOrganizationSearch?id=REF_1", },

	ARCsub =		{typ = "not", need = 0, list = 3,
		keyword = "ARCsub", base_base = "ARC", base_id = "ARCsub", not_type = "Subject",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://arcweb.archives.gov/arc/action/ExecuteRelatedTopicalSubjectsSearch?id=REF_1", },

	ARCHIVE =		{typ = "not", need = 0, list = 3,
		keyword = "ARCHIVE", base_base = "ARC", base_id = "ARCHIVE", not_type = "Author",
		base_test = "1234",
		base_name = "National Archives and Records Administration",
		not_link = "http://www.archive.org/details/REF_1", },

	BNF =			{typ = "not", need = 0, list = 3,
		keyword = "BNF", prop = "268", base_base = "BNF", base_id = "BNF", not_type = "Author",
		base_test = "119067514", -- BNF = 11888266 = Alain Fournier
		base_name = "Bibliothèque nationale de France",
		not_link = "http://catalogue.bnf.fr/ark:/12148/cbREF_1", },

	CANTIC =			{typ = "not", need = 0, list = 3,
		keyword = "CANTIC", prop = "1273", base_base = "CANTIC", base_id = "CANTIC", not_type = "Author",
		base_test = "12972/259446", -- pape Víctor III, 1027-1087
		base_name = "CANTIC", -- Catálogo de autoridades de nombres y títulos de Cataluña
		not_link = "http://cantic.bnc.cat/registres/marc/20692/1/REF_1", },
		-- http://cantic.bnc.cat/registres/fitxa/20692/1/12972/259446

	DNB =			{typ = "not", need = 0, list = 3,
		keyword = "DNB", base_base = "DNB", base_id = "DNB", not_type = "Author",
		base_test = "3684200072", -- , DNB = "3684200072"
		base_name = "Bibliothèque nationale allemande", -- Deutsche National Bibliothek
		not_link = "http://d-nb.info/gnd/REF_1", },

	GKD =			{typ = "not", need = 0, list = 3,
		keyword = "GKD", base_base = "GKD", base_id = "GKD", not_type = "Author",
		base_test = "71yhjey852", -- , GKD = "71yhjey852"
		base_name = "Bibliothèque nationale allemande",
		not_link = "http://d-nb.info/gnd/REF_1", },

	GKD_V1 =		{typ = "not", need = 0, list = 3,
		keyword = "GKD_V1", base_base = "GKD", base_id = "GKD-V1", not_type = "Author",
		base_test = "71yhjey852",
		base_name = "Bibliothèque nationale allemande",
		not_link = "http://d-nb.info/gnd/REF_1", },

	GND =			{typ = "not", need = 0, list = 3,
		keyword = "GND", prop = "227", base_base = "GND", base_id = "GND", not_type = "Author",
		base_test = "118730541",
		base_name = "GND",
		not_link = "http://www.GND.org/REF_1", },

	IA =			{typ = "not", need = 0, list = 3,
		keyword = "IA", base_base = "IA", base_id = "IA", not_type = "Author",
		base_test = "1234",
		base_name = "Internet Archive",
		not_link = "http://www.archive.org/REF_1", },

	IBL =			{typ = "not", need = 0, list = 3,
		keyword = "IBL", base_base = "IBL", base_id = "IBL", not_type = "Author",
		base_test = "1234",
		base_name = "Internet Book List", -- Pas de page fr, en redirige vers Base de données bibliographiques
		not_link = "http://www.iblist.com/authorREF_1.html", },

	IBLbook =		{typ = "not", need = 0, list = 3,
		keyword = "IBLbook", base_base = "IBL", base_id = "IBLbook", not_type = "Book",
		base_test = "1234",
		base_name = "Internet Book List", -- Pas de page fr, en redirige vers Base de données bibliographiques
		not_link = "http://www.iblist.com/bookREF_1.html", },

	IBLid =			{typ = "not", need = 0, list = 3,
		keyword = "IBLid", base_base = "IBL", base_id = "IBLid", not_type = "Author",
		base_test = "37581257954", -- , IBLid = "37581257954"
		base_name = "Internet Book List", -- Pas de page fr, en redirige vers Base de données bibliographiques
		not_link = "http://www.iblist.com/authorREF_1.html", },

	IMDb =			{typ = "not", need = 0, list = 3,
		keyword = "IMDb", base_base = "IMDb", base_id = "IMDb", not_type = "Author",
		base_test = "0002776", -- Johnny Hallyday
		base_name = "Internet Movie Data base",
		not_link = "http://www.imdb.com/name/nmREF_1/", },

	ISBN =			{typ = "not", need = 0, list = 3,
		keyword = "ISBN", base_base = "ISBN", base_id = "ISBN", not_type = "Book",
		base_test = "2-7073-0549-9", -- L'apartheid, de Nelson Mandela
		base_name = "International Standard Book Number", },

	ISFDB =			{typ = "not", need = 0, list = 3,
		keyword = "ISFDB", base_base = "ISFDB", base_id = "ISFDB", not_type = "Author",
		base_test = "1234",
		base_name = "Internet Speculative Fiction Database",
		not_link = "http://www.isfdb.org/cgi-bin/ea.cgi?REF_1", },

	ISFDBid =		{typ = "not", need = 0, list = 3,
		keyword = "ISFDBid", base_base = "ISFDB", base_id = "ISFDBid", not_type = "Author",
		base_test = "1234",
		base_name = "Internet Speculative Fiction Database",
		not_link = "http://www.isfdb.org/cgi-bin/ea.cgi?REF_1", },

	ISFDBpub =		{typ = "not", need = 0, list = 3,
		keyword = "ISFDBpub", base_base = "ISFDB", base_id = "ISFDBpub", not_type = "Book",
		base_test = "1234",
		base_name = "Internet Speculative Fiction Database",
		not_link = "http://www.isfdb.org/cgi-bin/pl.cgi?REF_1", },

	ISFDBtitle =	{typ = "not", need = 0, list = 3,
		keyword = "ISFDBtitle", base_base = "ISFDB", base_id = "ISFDBtitle", not_type = "Book",
		base_test = "1234",
		base_name = "Internet Speculative Fiction Database",
		not_link = "http://www.isfdb.org/cgi-bin/title.cgi?REF_1", },

	ISNI =			{typ = "not", need = 0, list = 3,
		keyword = "ISNI", prop = "213", base_base = "ISNI", base_id = "ISNI", not_type = "Author",
		base_test = "0000 0001 2144 7715",
		base_name = "International Standard Name Identifier",
		not_link = "http://isni.oclc.nl/DB=1.2/SET=10/TTL=1/CMD?ACT=SRCHA&IKT=8006&SRT=&TRM=REF_1", },

	LCCN =			{typ = "not", need = 0, list = 3,
		keyword = "LCCN", prop = "244", base_base = "LCCN", base_id = "LCCN", not_type = "Author",
		base_test = "n82212654", -- LCCN = n82212654 = Johnny Hallyday
		base_name = "Numéro de contrôle de la Bibliothèque du Congrès",
		not_link = "http://id.loc.gov/authorities/names/REF_1" },
	--[[
	LCCNid =			{typ = "not", need = 0, list = 3,
		keyword = "LCCNid", prop = "244", base_base = "LCCN", base_id = "LCCNid", not_type = "Author",
		base_test = "n/50/23101", -- LCCN = n/50/23101 = Alain Fournier
		base_name = "Numéro de contrôle de la Bibliothèque du Congrès",
		not_link = "http://id.loc.gov/authorities/names/REF_1REF_2REF_3" },
	-->|LCCN=http://id.loc.gov/authorities/names/{{ParmPart|1|{{{code|{{{2|}}} }}} }}{{ParmPart|2|{{{code|{{{2|}}} }}} }}{{padleft:{{ParmPart|3|{{{code|{{{2|}}} }}} }}|6|0}}.html<!--
	-->|LCCNid=http://id.loc.gov/authorities/names/{{ParmPart|1|{{{code|{{{2|}}} }}} }}{{ParmPart|2|{{{code|{{{2|}}} }}} }}{{padleft:{{ParmPart|3|{{{code|{{{2|}}} }}} }}|6|0}}.html<!--
	-->|LCCNbook=http://lccn.loc.gov/{{{code|{{{2|}}} }}}<!--
	--]]
	LT =			{typ = "not", need = 0, list = 3,
		keyword = "LT", base_base = "LT", base_id = "LT", not_type = "Author",
		-- prop = ?
		base_test = "1234",
		base_name = "Library Thing",
		not_link = "http://www.librarything.com/work/REF_1" },

	NDL =			{typ = "not", need = 0, list = 3,
		keyword = "NDL", prop = "349", },

	NKC =			{typ = "not", need = 0, list = 3,
		keyword = "NKC", prop = "691", },

	NLA =			{typ = "not", need = 0, list = 3,
		keyword = "NLA", base_base = "NLA", base_id = "NLA", not_type = "Author",
		base_test = "35096649", -- NLA = 35096649 = Alain Fournier
		base_name = "Online Computer Library Center",
		not_link ="http://www.worldcat.org/oclc/REF_1", },

	OCLC =			{typ = "not", need = 0, list = 3,
		keyword = "OCLC", base_base = "OCLC", base_id = "OCLC", not_type = "Author",
		base_test = "1234",
		base_name = "Online Computer Library Center",
		not_link ="http://www.worldcat.org/oclc/REF_1", },

	OL =			{typ = "not", need = 0, list = 3,
		keyword = "OL", base_base = "OL", base_id = "OL", not_type = "Author",
		base_test = "1234",
		base_name = "Open Library",
		not_link ="http://www.worldcat.org/oclc/REF_1", },

	OLbook =			{typ = "not", need = 0, list = 3,
		keyword = "OLbook", base_base = "OL", base_id = "OLbook", not_type = "Book",
		base_test = "2707305499", -- L'apartheid, de Nelson Mandela
		base_name = "Open Library",
		not_link ="http://openlibrary.org/search?wtitle=&wauthor=&wtopic=&wisbn=REF_1&wpublisher=&wdescription=&ftokens=&_save=Chercher", },

	PND =			{typ = "not", need = 0, list = 3,
		keyword = "PND", base_base = "PND", base_id = "PND", not_type = "Author",
		base_test = "11850133X", -- PND = 11850133X = Alain Fournier
		base_name = "Personennamendatei",
		not_link ="http://d-nb.info/gnd/REF_1", },

	SELIBR =		{typ = "not", need = 0, list = 3,
		keyword = "SELIBR", base_base = "SELIBR", base_id = "SELIBR", not_type = "Author",
		base_test = "74042",
		base_name = "Bibliothèque royale (Suède)", -- "National Library of Sweden" "Personennamendatei",
		not_link ="http://libris.kb.se/auth/REF_1", },

	SUDOC =			{typ = "not", need = 0, list = 3,
		keyword = "SUDOC", base_base = "SUDOC", base_id = "SUDOC", not_type = "Author",
		base_test = "1234",
		base_name = "Système universitaire de documentation",
		not_link ="http://www.idref.fr/REF_1", },

	SWD =			{typ = "not", need = 0, list = 3,
		keyword = "SWD", base_base = "SWD", base_id = "SWD", not_type = "Author",
		base_test = "1234", -- debug text : de : Subject Headings Authority File, base allemande nom anglais
		base_name = "Schlagwortnormdatei",
		not_link ="http://d-nb.info/gnd/REF_1", },

	ULAN =			{typ = "not", need = 0, list = 3,
		keyword = "ULAN", base_base = "ULAN", base_id = "ULAN", not_type = "Author",
		base_test = "500198443",
		base_name = "Union List of Artist Names",
		not_link ="http://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid=REF_1", },

	VIAF =			{typ = "not", need = 0, list = 3,
		keyword = "VIAF", prop = "214", base_base = "VIAF", base_id = "VIAF", not_type = "Author",
		base_test = "34452139", -- VIAF = 34452139 = Alain Fournier -- VIAF = 7396281 = Arthur Rimbaud
		base_name = "Fichier d'autorité international virtuel",
		not_link ="http://viaf.org/viaf/REF_1", },

	WORLDCAT =		{typ = "not", need = 0, list = 3,
		keyword = "WORLDCAT", base_base = "WORLDCAT", base_id = "WORLDCAT", not_type = "",
		base_test = "35096649",
		base_name = "WorldCat", -- = http://www.worldcat.org/identities/lccn-n50-23101
		not_link ="http://www.worldcat.org/search?qt=worldcat_org_all&q=REF_1+REF_2", },

	WORLDCATbook =		{typ = "not", need = 0, list = 3,
		keyword = "WORLDCATbook", base_base = "WORLDCAT", base_id = "WORLDCATbook", not_type = "Book",
		base_test = "2707305499", -- L'apartheid, de Nelson Mandela
		base_name = "WorldCat",
		not_link ="http://worldcat.org/search?q=REF_1&qt=owc_search", },

	WORLDCATch =	{typ = "not", need = 0, list = 3,
		keyword = "WORLDCATch", base_base = "WORLDCAT",base_id = "WORLDCATch", not_type = "",
		base_test = "35096649", -- http://www.worldcat.org/search?q=Alain-Fournier&qt=owc_search
		base_name = "WorldCat",
		not_link ="http://www.worldcat.org/search?q=REF_2-REF_1&qt=owc_search", },

	WORLDCATid =	{typ = "not", need = 0, list = 3,
		keyword = "WORLDCATid", base_base = "WORLDCAT", base_id = "WORLDCATid", not_type = "Author",
		base_test = "lccn-n50-23101", -- = http://www.worldcat.org/identities/lccn-n50-23101
		base_name = "WorldCat",
		not_link ="http://www.worldcat.org/identities/REF_1", },

} -- p.args_known_default

------------------------------------------------------------
-- Manage options. Administrar opciones. Gérer les options.
------------------------------------------------------------

-- MArgms local catView = "" -- = ":" to display a category to document it rather than truly categorize

--	Options de maîtrise du fonctionnement de ce module
CA.invoke_options = " " -- options normales venant du modèle, normal options from template
--	options= en es fr params docview doc-min docmax docdef doc-apres docline
--	local CA.mode_options = " " -- pas d'options de debug du module par edit
CA.mode_options = " " -- " unitest debug erron params docview no-box no-cat doc-min doc-max doc-notice doc-def docline not-ices tra-ck " -- options de debug du module par edit

------------------------------------------------------------
-- Petites fonctions utilitaires. Miscellaneous functions
------------------------------------------------------------

local function isDef(x) -- x is defined. x est défini
	return (type(x) == "string") and (x ~= "") and (x ~= " ") and (x ~= "nil")
end -- function isDef(x)

function wordstotable(txt, opt) -- convertit un texte en table de mots
	local t = ""
	local tab = { }
	function inserer(ti)
		if ti ~= "" then table.insert(tab, ti.."") end -- table.insert(tab, t.."")
	end
	local xyz = string.gsub( txt, "(%S*%-*%S*)", inserer ) -- "(%w*%-*%'*%w*)", "(%S*%-*%S*)"
	for key, val in pairs(tab) do -- Pour tous les mots
		t = t .. " ( " .. tostring(key) .. " = " .. tostring(val) .. " ) "
	end
	t = "\n* wordstotable txt = " .. tostring(xyz) .. " " .. t
	return tab, t, opt
end -- function p.wordstotable(txt, opt)

------------------------------------------------------------
-- Données de wikidata par mw.wikibase
------------------------------------------------------------
-- http://test2.wikipedia.org/w/index.php?title=Bertha_von_Suttner&action=edit
-- {{authority control|TYP=p|GND=118620126|LCCN=n/50/66831|NDL=01229737|VIAF=95160848}}
-- http://test2.wikipedia.org/wiki/Module:Wikibase

-- mw.wikibase.getEntity() --	 gets entity data of the Wikidata item connected with the current page. See the section Entity table and data structure for an example of the structure returned.
-- mw.wikibase.label( id ) --	 takes an item ID and returns the label in the language of the local wiki.
-- mw.wikibase.sitelink( id ) --	takes an item ID and returns the title of the corresponding page on the local wiki.
-- http://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua
-- p.entity = mw.wikibase.getEntity()
-- p.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"])
-- p.id = ""
-- father == "Lord Byron"
-- http://www.wikidata.org/wiki/Wikidata:Project_chat#Getting_a_subset_of_claims_for_an_entity
-- The props=claims API query retrieves ALL the claims stored for an entity.
------------------------------------------------------------

------------------------------------------------------------
-- Manage and generate autority notices and scans
-- Gérer et générer les notices d'autorité et les scans
------------------------------------------------------------

function p.subst_string(input, find, replace)
	local L = string.len(find)
	local res = ""
	--	if (type(L) ~= "number") or (L == 0) then return "" end
	if L == 0 then return "" end
	local i = string.find(input, find)
	if i and (i > 0) then
		res = string.sub(input, 1, i-1) .. replace .. string.sub(input, i+L, -1)
	else return input end
	return res
end -- function p.subst_string(input, find, replace)

function p.split_by_char(input, split)
	if type(input) ~= "string" then return end
	if type(split) ~= "string" then return end
	local i, j, k, char, str, tbl = 0, 0, 0, "", "", {}
	local len = string.len(input)
	for i = 1, len do -- pour tous les caracteres de input
		char = string.sub(input, i, i)
		if char == split then -- a chaque coupure, stocker une partie en table
			k = k+1
			table.insert(tbl, str) -- tostring(k).."-"..
			j = 0
			str = ""
		else
			j = j+1
			str = str .. char
		end
	end
	k = k+1
	table.insert(tbl, str) -- tostring(k).."-"..
	return tbl
end -- function p.split_by_char(input, split)

function p.split_by_char_test()
	local t = "\n* Test '''split_by_char''' : "
	local test = { "debut", "un/deux", "1/23/4567", "abc//def", "/start/next/stop/", "fin", }
	local max = table.maxn(test)
	for N, str in ipairs( test) do
		tbl = p.split_by_char(str, "/")
		t = t .. CA.ta(str, table.concat(tbl, " , "))
	end -- tostring(N).."*"..refN
	return t
end -- function p.split_by_char_test()

function p.str_subst(txt, find, repl) -- in txt, replace find by repl
	-- Replace string.gsub( because :
	-- Erreur Lua dans Module:Author invalid capture index, in wt = string.gsub(wt, "REF_1", tostring(v1) )
	txt = tostring(txt)
	local i = string.find(txt, find)
	if i and (i > 1) then
		txt = string.sub(txt, 1, i-1) .. tostring(repl) .. string.sub(txt, i + string.len(find), -1)
	end
	return txt
end -- function p.str_subst(txt, find, repl)

function p.str_REF(wt_ref, v1, v2, v3)
	-- replace REF_1 to REF_3 by v1 to v3 in the translation of wt_ref, else in wt_ref
	wt_ref = tostring(wt_ref)
	local wt = ""
	if CA.wiki_translations and CA.wiki_translations[wt_ref]
		then wt = CA.wiki_translations[wt_ref] -- Utiliser wt_ref comme la reference d'un texte à traduire.
		else wt = wt_ref end -- Avant init de CA.wiki_translations utiliser wt_ref comme le texte lui-même
	if type(wt) ~= "string" then wt = wt_ref end -- Sinon utiliser wt_ref comme le texte lui-même.
	if v1 then wt = p.str_subst(wt, "REF_1", tostring(v1) ) end
	if v2 then wt = p.str_subst(wt, "REF_2", tostring(v2) ) end
	if v3 then wt = p.str_subst(wt, "REF_3", tostring(v3) ) end
	return wt
end -- function p.str_REF(wt_ref, v1, v2, v3)

-- Select authorities depending on the user language
function p.authorities_select(authorities_selector, args_wikidata_import, args_known)
--	CA.args_wikidata, CA.args_wikidata_selected, t = p.authorities_select()
	-- The authorities notices selector come from the call, else from the "notices" template argument, else from the user language or from the wiki language authorities_selector.
	local args_final_notices = nil
	if type(CA.args_final) == "table" then args_final_notices = CA.args_final.notices end
	authorities_selector = authorities_selector or args_final_notices or CA.user_translations.authorities_selector or CA.wiki_translations.authorities_selector -- or "VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat,6,NLA,PND,GKD,ARC"
	if type(args_wikidata_import) ~= "table" then args_wikidata_import = CA.args_wikidata_import end
	if type(args_known) ~= "table" then args_known = CA.args_known end
	t = t or "\n* authorities_select : "
	local selected = {}
	local args_cleaned = {}
	local k, Nsel, N, maxi, pos = 0, 0, 1, 999, nil
	local selectors = mw.text.split(authorities_selector, ",", true)
	for i, authority in ipairs(selectors) do
		if Nsel >= maxi then break end
		N = tonumber(authority)
		if authority == "+" then -- select all noticies from wikidata
		--[[	if type(args_known) == "table" and type(args_wikidata_import) == "table" then
				for key, args_kwn in pairs(args_known) do
					if args_kwn and (args_kwn["typ"] == "not") then
						Nsel = Nsel + 1
						selected[key] = tostring(args_wikidata_import[key])
					end
				end
			end --]]
			
			if type(args_known) == "table" and type(args_wikidata_import) == "table" then
				for key, val in pairs(args_wikidata_import) do
					if args_known[key] and (args_known[key]["typ"] == "not") then
						Nsel = Nsel + 1
						selected[key] = val
					end
				end
			end
		elseif N and string.sub(authority, 1, 1) == "+" then -- select +N more notices in nexts notices
			maxi = Nsel + N
		elseif N then -- select N maximum total notices with next notices
			maxi = N
		else
			pos = string.find(authorities_selector, authority, 1, true)
			if pos then
				Nsel = Nsel + 1
				selected[authority] = tostring(args_wikidata_import[authority])
			end
		end
		t = t .. CA.tam(authority, selected[authority])
	end
	-- In args_wikidata, suppress not selected noticies, supprimer les notices non selectionnées
	if type(args_known) == "table" and type(args_wikidata_import) == "table" then
		args_cleaned = mw.clone(args_wikidata_import)
		for key, args_kwn in pairs(args_known) do
			if args_kwn and (args_kwn["typ"] == "not") then
				if not selected[key] then args_cleaned[key] = nil end
			end
		end
	end
--	CA.args_wikidata = args_cleaned
--	CA.args_wikidata_selected = selected
	return args_cleaned, selected, t
--	CA.args_wikidata, CA.args_wikidata_selected, t = p.authorities_select()
end -- function p.authorities_select(authorities_selector, args_wikidata, args_known)

function p.authorities_select_test1(t, authorities_selector, args_wikidata_import)
	local twi, ts, cln = " ", " ", " "
	for key, val in pairs(args_wikidata_import) do
		twi = twi .. " '''" .. key .. "''', "
	end
	local args_cleaned, args_selected = p.authorities_select(authorities_selector, args_wikidata_import)
	for key, val in pairs(args_selected) do
		ts = ts .. " '''" .. key .. "''', "
	end
	for key, val in pairs(args_cleaned) do
		cln = cln .. " '''" .. key .. "''', "
	end
	t = (t or "") .. CA.Tr() .. CA.Td(authorities_selector) .. CA.Td(twi) .. CA.Td(ts) .. CA.Td(cln)
	return t
end -- function p.authorities_select_test1(t, authorities_selector, args_wikidata)

function p.authorities_select_test(t)
	local select = "3,VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat"
	--     sur fr, sont indispensables : VIAF, BNF, SUDOC + LCCN (référence internationale) + ISNI et Worldcat... les autres, seulement en cas de manque dans les autorités "de base"... Clin d'œil
	t = (t or "") .. "\n* '''authorities_select''' exemple : " .. CA.ta( "sélecteur", select )
	t = t .. "\n* Sélectionner seulement les 3 premières autorités du sélecteur, parmi celles venant de wikidata. "
	t = t .. "\n* Autre exemple : " .. CA.ta( "sélecteur", "+" )
	t = t .. "\n* Sélectionner toutes les notices de wikidata. "
	t = t .. "\n* Autre exemple : " .. CA.ta( "sélecteur", "BNF,Worldcat,+2,VIAF,3,GKD,LCCN" )
	t = t .. "\n* Sélectionner les premières, puis 2 de plus parmi les suivantes, puis au maximum 3. "
	t = t .. CA.Th() .. CA.Tc("Sélecteur") .. CA.Tc("Wikidata initial") .. CA.Tc("Sélection") .. CA.Tc("Wikidata sélectionné")
	t = p.authorities_select_test1( t, select, { NLA="7", NLA="7", GKD="7", GKD="7", label="7", sitelink="7"} )
	t = p.authorities_select_test1( t, select, { VIAF="7", BNF="7", SUDOC="7", LCCN="7", lastname="7", label="7"} )
	t = p.authorities_select_test1( t, select, { VIAF="7", NLA="7", GKD="7", BNF="7", sitelink="7", initiale="7"} )
	t = p.authorities_select_test1( t, select, { SUDOC="7", BNF="7", GKD="7", GKD="7", lastname="7", initiale="7"} )
	t = p.authorities_select_test1( t, select, { VIAF="7", xyz="7", GKD="7", VIAF="7", initiale="7", sitelink="7"} )
	t = p.authorities_select_test1( t, "+", { VIAF="7", xyz="7", GKD="7", VIAF="7", initiale="7", sitelink="7"} )
	t = p.authorities_select_test1( t, "VIAF,BNF,+2,SUDOC,LCCN,ISNI,Worldcat", { VIAF="7", Worldcat="7", GKD="7", LCCN="7", ISNI="7", BNF="7"} )
	t = p.authorities_select_test1( t, "LCCN,+,ISNI", { VIAF="7", xyz="7", GKD="7", LCCN="7", ISNI="7", BNF="7"} )
	t = t .. CA.Te()
	return t
end -- function p.authorities_select_test( res, args_final)

function p.HTMLnotice(ref, noticeN) -- Générer le wikitexte d'une notice
	-- exemple : notice("cb11888266r", noticeN)
	--	ARCitem = {base_base = "ARC", base_id = "ARCitem",	_space = "", base_test = "1234", not_type = "Book", ...
	if type(noticeN) ~= "table" then return "" end
	local base_id = noticeN.base_id
	local base_link = noticeN.not_link
	if type(base_id) ~= "string" then return "" end
	if type(noticeN.not_link) ~= "string" then return "" end
	if type(ref) ~= "string" or ref == "" then return "" end -- relire : declarer une erreur err_notice_missing_ref
	-- ne garder que le première reference si references multiples (voir Johnny Hallyday)
	-- Keep only the fisrt reference in case of multiple references (see Johnny Hallyday)
	local i = string.find( ref, ",")
	if i and (i > 1) then ref = string.sub(ref, 1, i-1) end
	-- = mw.text.trim( s, charset ) -- charset = "%t%r%n%f ". %s: represents all characters with General Category "Separator", plus tab, linefeed, carriage return, vertical tab, and form feed.
	local ref_link = mw.uri.encode(ref, "PATH") -- espace = space = %20
	local autority_alt_text = base_id .. " : " .. ref
	local wikipedia_name = noticeN.base_name
	local wikipedia_name_link = mw.uri.encode(wikipedia_name, "PATH") -- espace == %20
	local wikipedia_base_link = 'http://fr.wikipedia.org/wiki/' .. wikipedia_name_link
	local authority_icon_link = noticeN.not_link
	-- REF_1 = reference en un seul identifiant comme "cb11888266r"
	-- REF_1/REF_2 = reference en 2 parties comme "...worldcat_org_all&q=REF_1+REF_2"
	-- REF_1/REF_2/REF_3 = reference en 3 parties comme "http://id.loc.gov/.../REF_1REF_2REF_3"
	local v = mw.text.split(ref_link, "/", true) -- nobug
	-- LCCNid : allonger à 6 chiffres, avec des 0 à gauche, la partie 3 de "n/50/23101", soit 023101.
	--	v[3] = string.sub( "000001234" .. tostring(v[3]), -8, -1 ) --	-6, -1 )
	local authority_icon_link = p.str_REF(authority_icon_link, v[1], v[2], v[3])
	--
	local img = 'Farm-Fresh draw calligraphic.png'
	if noticeN.not_type == "Book" then img = 'Nuvola_apps_bookcase_2.svg' end
	-- exemple : wt = '<span style="margin-left:10px;" > &nbsp; * &nbsp; [' .. wikipedia_base_link .. ' ' .. base_id .. '] : [[File:' .. img .. '|22px|link=' .. authority_icon_link .. '|' .. autority_alt_text .. ']]</span>'
	-- <form> non -	  <ins> calé à gauche - use the <object> tag to embed another webpage into your HTML document.
	-- <wbr> (Word Break Opportunity) -- text-wrap: normal|none|unrestricted|suppress;

	--	local wt = '<span style="text-wrap:none;" ><span style="margin-left:10px;" >*</span><span style="margin-left:10px;" >[' .. wikipedia_base_link .. ' ' .. base_id .. ']</span><span style="margin-left:10px;" >[[File:' .. img .. '|22px|link=' .. authority_icon_link .. '|' .. autority_alt_text .. ']]</span>&nbsp;</span>'

	local wt = '<span style="margin-left:10px;" >*</span><span style="margin-left:10px;" >[' .. wikipedia_base_link .. ' ' .. base_id .. ']</span>[[File:' .. img .. '|22px|link=' .. authority_icon_link .. '|' .. autority_alt_text .. ']]&nbsp; '

	-- :</span>
	return wt
end -- function p.HTMLnotice(ref, noticeN)

--[[ example of autority notice definition
BNF =			{typ = "not", need = 0, list = 3,
	keyword = "BNF", prop = "268", base_base = "BNF", base_id = "BNF", not_type = "Author",
	base_test = "119067514", -- BNF = 11888266 = Alain Fournier
	base_name = "Bibliothèque nationale de France",
	not_link = "http://catalogue.bnf.fr/ark:/12148/cbREF_1", },

ISBN =			{typ = "not", need = 0, list = 3,
	keyword = "ISBN", base_base = "ISBN", base_id = "ISBN", not_type = "Book",
	base_test = "2-7073-0549-9", -- L'apartheid, de Nelson Mandela
	base_name = "International Standard Book Number", },
]]

-- Générer des notices d'autorités indépendantes sur une personne, un livre ou autre.
function p.gener_notices(args_known, args_wikidata_selected)
	-- Generate notices ARCid DNB GKD IBLid ...
	if type(args_known) ~= "table" then args_known = CA.args_known end
	if type(args_wikidata_selected) ~= "table" then args_wikidata_selected = CA.args_wikidata_selected end
	local wt, ref_trim, ref_split = "", "", nil
	--	wt = wt .. '<span style="margin-left:10px;" >*</span><span style="margin-left:10px;" >[http://fr.wikipedia.org/wiki/Bibliothèque%20nationale%20de%20France BNF test]</span> [[File:Farm-Fresh draw calligraphic.png|22px|link=http://catalogue.bnf.fr/ark:/12148/cb119067514|BNF test 119067514]] &nbsp;'
	for key, ref in pairs(args_wikidata_selected) do -- Pour tous les paramètres connus
		key = tostring(key)
		if args_known[key] and (args_known[key]["typ"] == "not") then
			local ref_split = mw.text.split(ref, ",", true) -- nobug
			for i, ref_i in ipairs(ref_split) do
				ref_trim = mw.text.trim(ref_i)
				if ref_trim and ref_trim ~= "" then wt = wt .. p.HTMLnotice(ref_trim, args_known[key]) end
			end
		end
	end
	return wt
end -- function p.gener_notices(args_known, args_wikidata_selected)

-- Tester toutes les notices d'autorités indépendantes sur une personne, un livre ou autre.
-- Generate all know notices ARCid DNB GKD IBLid ...
function p.HTMLnotice_test( res, args_known)
	if type(args_known) ~= "string" then args_known = CA.args_known end
	res = res or "\n\n* Test all know authority notices : "
	local i, ntc = 1, ""
	for key, noticeN in pairs(args_known) do -- Pour toutes les notices connus
		res = res .. p.HTMLnotice(noticeN.base_test, noticeN)
	end
	return res
end -- function p.HTMLnotice_test( res, args_known)

function p.toUTF8(t)
	-- convertir un simple texte en UTF8 pour URL
	-- base_name = "Bibliothèque d'autorité (Suède)"
	-- wikipedia_name = "Biblioth%%C3%%A8que%%20d%%27autorit%%C3%%A9%%20%%28Su%%C3%%A8de%%29"
	-- The default type, "QUERY", encodes spaces using '+' for use in query strings; "PATH" encodes spaces as %20; and "WIKI" encodes spaces as '_'.
	--
	if type(t) ~= "string" then return "" end
	--t = mw.uri.encode( t, "QUERY" )
	t = string.gsub(t, "%s", "%%20") -- espace == %20
	t = string.gsub(t, "'", "%%27") -- , == %27
	t = string.gsub(t, ",", "%%2C") -- , == %2C
	t = string.gsub(t, ":", "%%3A") -- : = %3A
	t = string.gsub(t, "%(", "%%%%28")
	t = string.gsub(t, "%)", "%%%%29")
	t = string.gsub(t, "é", "%%C3%%A9")
	t = string.gsub(t, "è", "%%C3%%A8")
	return t
end -- function p.toUTF8(t)

function p.scanNames(wt, site, args_final)
	-- wt = scanNames("http://gallic ... &q=-ws-name-+-ws-firstname-", md_data) -- replace names for scans
	-- anti errors
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local lastname = args_final.lastname or ""
	local firstname = args_final.firstname or ""
	local galliname = args_final.galliname or ""
	--	if galliname == "" then galliname = firstname end
	--	wt = mw.uri.encode(wt, "WIKI" ) -- The default type, "QUERY", encodes spaces using '+' for use in query strings; "PATH" encodes spaces as %20; and "WIKI" encodes spaces as '_'.
	-- replace names for scans
	wt = tostring(wt)
	firstname = mw.uri.encode(firstname, "QUERY" )
	wt = tostring(string.gsub(wt, "wsfirstname", firstname) ) -- "ws_firstname", firstname
	lastname = mw.uri.encode(lastname, "QUERY" )
	wt = tostring(string.gsub(wt, "wslastname", lastname) )
	galliname = mw.uri.encode(galliname, "QUERY" )
	wt = tostring(string.gsub(wt, "wsfirstgall", galliname) )
	-- wt = p.toUTF8(wt)
	--	wt = mw.uri.encode(wt, "QUERY" ) -- The default type, "QUERY", encodes spaces using '+' for use in query strings; "PATH" encodes spaces as %20; and "WIKI" encodes spaces as '_'.
	-- str2 = str.gsub(/\s/,'')
	wt = "\n*[" .. wt .. " " .. site .. "] - - " -- .. '<br/>[' .. wt
	return wt
end -- function p.scanNames(wt, site, args_final)

function p.HTMLscans(args_final)
	-- à faire : i18n['fr']author_scans_text				= 'Scans fr : ', author_scans_text
	-- wt = scanNames("http://gallic ... &q=-ws-name-+-ws-firstname-") -- replace names for scans
	-- anti errors
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	-- Generate scans to display
	local firstname, lastname, galliname = "x", "x", "x"
	local t = "" -- "HTMLscans "
	if type(args_final.firstname) == "string"
	--	then firstname = mw.uri.encode(args_final.firstname, "QUERY" )
		then firstname = string.gsub(args_final.firstname, "%s", "+")
		else firstname = "" end
	if type(args_final.lastname) == "string"
	--	then lastname = mw.uri.encode(args_final.lastname, "QUERY" )
		then lastname = string.gsub(args_final.lastname, "%s", "+")
	--		lastname = "Noël+Renée"
		else lastname = "" end
	if type(args_final.galliname) == "string"
	--	then galliname = mw.uri.encode(args_final.galliname, "QUERY" )
		then galliname = string.gsub(args_final.galliname, "%s", "+")
		else galliname = "" end
	local scans = "" -- CA.ta("firstname", firstname) .. CA.ta("lastname", lastname) .. CA.ta("galliname", galliname)
	local SCAN_gallica = "http://gallica.bnf.fr/Search?ArianeWireIndex=index&p=1&lang=FR&q=" .. lastname .. "+" .. firstname
	t = t .. " <span> &nbsp; [" .. SCAN_gallica .. " Gallica] </span>"
	local SCAN_europeana = "http://www.europeana.eu/portal/search.html?query=who:" .. firstname .. ",+" .. lastname .. "&rows=12"
	t = t .. " <span> &nbsp; [" .. SCAN_europeana .. " Europeana] </span>"
	local SCAN_google = "https://www.google.fr/search?q=inauthor%3A%22" .. firstname .. "+" .. lastname .. "%22&ie=utf-8&oe=utf-8&aq=t"
	t = t .. " <span> &nbsp; [" .. SCAN_google .. " Google] </span>"
	local scan_notices = p.gener_notices(CA.args_known, CA.args_final)
--	local start = CA.trans('author_scans_text') .. ' : &nbsp; '
	local scans = '<div class="vcard" style=" background-color:#F1F1DE; border:0px solid #CCCCCC; "><span> ' .. scan_notices .. t .. " " .. ' </span></div>'
	--	scans = scans .. p.HTMLnotice_test( "\n\n* Test de '''gener_notices''' : " )
	AT.scans = scans .. CA.Th('style="bottom:0px; margin:1px; "') .. CA.Tr() .. CA.Td(scan_notices) .. CA.Td(t) .. CA.Te()
	return scans --	 .. "\n\n* Test de '''gener_notices''' : "
end -- function p.HTMLscans(args_final)

------------------------------------------------------------
-- Gérer les catégories. Manage categories. Administrar categorías.
------------------------------------------------------------

function p.gener_categories(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end
	if args_final.initiale then
		CA.cat_add("authors_initiale_cat", args_final.initiale)
	end
	if args_final.commonscat then CA.cat_add(catspace, "Commons category") end
	CA.catGroup("%1", args_final.genre) -- |genre=Romanciers/Poètes/Auteurs de théatre
	CA.catGroup("cat_group_languages", args_final.language) -- |langue=français/japonais de naissance
	CA.catGroup("cat_group_languages", args_final.languages) -- |langue=français/japonais autres langues
--	CA.catGroup("%1", args_final.language) -- |langue=français/japonais de naissance
--	CA.catGroup("%1", args_final.languages) -- |langue=français/japonais autres langues
	CA.catGroup("%1", args_final.occupation) -- |metier=Académiciens/Personnalités politiques
	CA.catGroup("Auteurs %1", args_final.nationality) -- |pays=français/italiens/chinois
	CA.catGroup("%1", args_final.prize) -- |prix=Nobel de littérature/Pulitzer/Renaudot
	return
end -- function p.gener_categories(args_final)

------------------------------------------------------------
-- Gérer et générer les droits d'auteurs, annotations, microformat, defaultsort
------------------------------------------------------------

function p.author_rights(args_final)
	-- wkt, ee = p.author_rights(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end
	local rights = args_final.rights
	local birthyear = tonumber(args_final.birthyear)
	local deathyear = tonumber(args_final.deathyear)
	local tst = ""
	local wkt = ""
	local cat = nil
	local err = ""
	local box = nil
	--
	-- Compute the rights type for this author
	if rights == "mpf" then -- 'Auteur Mort pour la France'
		if deathyear then
			if CA.nowyear <= deathyear + 95 then
				cat = "rights_values_cat_mpf" -- Catégorie:Auteurs morts pour la France
				box = "rights_values_box_mpf" -- Modèle:Auteurs morts pour la France
			end
		end
	elseif rights == "50" then -- standard 70 year rights along the time
		if deathyear then
			if CA.nowyear <= deathyear + 50 then
				cat = "rights_values_cat_50" -- Catégorie:Auteurs dans le domaine public au Canada
				box = "rights_values_box_50" -- Modèle:DP-CN-Auteur
			end
		end
	elseif rights == "70" then -- Auteurs dans le domaine public aux États-Unis
		if deathyear then
			if CA.nowyear <= deathyear + 70 then
				cat = "rights_values_cat_70" -- Catégorie:Auteurs dans le domaine public aux États-Unis
				box = "rights_values_box_70" -- Modèle:DP-EU-Auteur
			end
		end
	else -- aucune information sur les Droits d'auteur
		cat = nil
		box = nil
	end
	-- Générer sans erreur la catégorie et le modèle de droits d'auteur
	-- Generate without error the category and the template
	wkt = ""
	if cat == "-" then cat = nil end
	if cat and not CA.option("nocat") then -- pour normal et pour test
		cat = CA.cat_add(cat)
	end
	if box and box == "-" then box = nil end
	if box and not CA.option("nobox") then -- pour normal et pour test
		-- Verifier si le modèle existe, pour éviter l'erreur de script
		-- Verify if the template exists, for no script error
		box = CA.str_vars(box)
		local template = mw.title.new( box, "template" )
		if template.exists then
			wkt = wkt .. mw.getCurrentFrame():expandTemplate{ title = box }
		end
	end
	tst = "\n* author_rights "
	tst = tst .. CA.ta("birthyear", birthyear) .. CA.ta("deathyear", deathyear)
	tst = tst .. CA.ta("rights", rights) .. CA.ta("box", box)
	tst = tst .. CA.ta("options", options)
	tst = tst .. CA.ta("err", err) .. CA.tam("cat", cat)
	--
	args_final.tst = tst
	args_final.wkt = wkt
	args_final.cats = args_final.cats or ""
	args_final.cats = args_final.cats .. (cat or "")
	args_final.errs = args_final.errs or ""
	args_final.errs = args_final.errs .. (err or "")
	return wkt, args_final
end -- function p.author_rights(args_final)

local defaultsort = function(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end
	if args_final.sortkey then
		return mw.getCurrentFrame():preprocess("{{DEFAULTSORT:" .. args_final.sortkey .. "}}")
	end
	return ""
end

------------------------------------------------------------
-- Gérer et générer l'entête de page d'un auteur
-- Voir aussi les styles dans Mediawiki:commons.css, Utilisateur:Xyz/commons.css
------------------------------------------------------------

-- Extract one number from a text, digital or roman
-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.a_number( ee, base_in)
	--	ee = p.a_number( ee, "digit") -- example
	local err, cat = "", ""
	local wkt, tst = "", ""
	ee.nbr_out = nil
	ee.nbr_txt = ""
	ee.nbr_in = ee.nbr_in or ""
	--
	-- La base du nombre (digit ou roman) est définie par ee.base_in puis par ee.base ici.
	-- Ensuite elle sera forcée par des valeurs d'années décimales trop grandes pour être des siècles.
	-- Ensuite elle sera forcée par des chiffres romains de siècle.
	-- voir aussi err_year_in_roman_number
	--
	-- Normalize abnormal values. Normaliser des valeurs anormales
	if base_in then ee.base_in = base_in end
	if ee.base_in then ee.base = ee.base_in end
	if ee.base ~= "roman" then ee.base = "digit" end -- default values. valeur par défaut
	local val, error_roman, argmt, argmX = nil, "", "", ""
	local an_tab = {} -- table of found numbers
-- A faire : Titus Livius (Q2039), format de dates : P569 = date of birth = 59 BCE, P570 = date of death = 17
	-- Search all roman numbers. Chercher tous les nombres romains.
	ee.digit_select = "[^MDCLXVIJ]"
	local numbers = string.gsub( " "..ee.nbr_in.." ", ee.digit_select, " " )
	local lst = wordstotable( numbers ) -- convertit un texte en table de mots
	for key, word in pairs(lst) do -- search eventual numbers
		val = nil
		if word then
			-- L'argument peut contenir un nombre décimal, un nombre romain ou les deux.
			-- On lit les deux pour traiter tous les cas plus tard.
			val, error_roman = MathRoman.roman2int(word, "	")
			if val == 0 then val = nil end
			if (val ~= nil) then
				ee.roman_txt = word -- il y a au moins un nombre roman parmi les mots
				table.insert( an_tab, val )
				ee.nbr_out = val
				ee.base = "roman"
				ee.numbers = numbers
				ee.nbr_txt = ee.roman_txt -- ee.nbr_txt ..
				ee.vague_txt = string.gsub( ee.nbr_in, ee.nbr_txt or "", "" )
				ee.vague_txt = string.gsub( ee.vague_txt, "[^%l%<%=%>]", "" )
				ee.vague_roman = isDef(ee.vague_txt)
				ee.error_roman = error_roman
				if ee.error_roman then
					CA.err_add("err_roman2int", ee.roman_txt, ee.nbr_out, ee.error_roman)
				end
			end
		end
	end
	-- Search all digital numbers. Chercher tous les nombres décimaux
	ee.digit_select = "[^%d]" -- "[^%d]"
	local numbers = string.gsub( " "..ee.nbr_in.." ", ee.digit_select, " " )
	local lst = wordstotable( numbers ) -- convertit un texte en table de mots " "..ee.nbr_in.." "
	for key, word in pairs(lst) do -- search eventual numbers
		val = nil
		if word then
			-- L'argument peut contenir un nombre décimal, un nombre romain ou les deux.
			-- On lit les deux pour traiter tous les cas plus tard.
			val = tonumber( word )
			if (val ~= nil) then
				ee.digit_txt = word -- il y a au moins un nombre décimal parmi les mots
				table.insert( an_tab, val )
				ee.nbr_out = val
				ee.base = "digit"
				ee.numbers = numbers
				ee.nbr_txt = ee.digit_txt
				-- Dans le texte d'entrée, sans le nombre trouvé, garder seulement les lettres et "<=>".
				-- In the input text, without the found number, keep only letters and "<=>"
				ee.vague_txt = string.gsub( ee.nbr_in, ee.nbr_txt or "", "" )
				ee.vague_txt = string.gsub( ee.vague_txt, "[^%l%<%=%>]", "" )
				ee.vague_digit = isDef(ee.vague_txt)
			end
		end
	end
	--
	ee.tabN = table.maxn( an_tab )
	if ee.tabN == 1 then -- verify the number is alone
		-- Si on a un nombre et un seul, on peut utiliser sa valeur
		-- Et on connait sa base par digit_txt ou roman_txt
		ee.nbr_out = an_tab[1]
	else -- erreur s'il n'y a pas de nombre ou s'il y en a plusieurs
		--	cat = cat .. CA.err_add("err_one_number_argument", tostring( ee[argname] ) )
		ee.nbr_out = nil
		ee.nbr_txt = nil
	end
	if ee.nbr_out then -- adjust for negative numbers, including romans
		local negatif = string.find( ee.nbr_in, "-" .. ee.nbr_txt )
		if negatif then
			ee.nbr_out = - ee.nbr_out
	--			ee.nbr_txt = ""
	--			if ee.digit_txt then ee.nbr_txt = ee.digit_txt end
			-- Pour les catégories CE, BCE ou Av. JC
	--			if ee.roman_txt then ee.nbr_txt = ee.nbr_txt .. ee.roman_txt end
		end
	end
	-- Chercher du texte significatif en plus du nombre
	-- Search for significant text in addition to the number
	tst =  "\n* a_number " -- tostring(tst) .. "\n* a_number "
	tst = tst .. CA.ta("nbr_in", ee.nbr_in) .. CA.ta("base_in", ee.base_in) .. CA.ta("base", ee.base)
	tst = tst .. CA.ta("nbr_out", ee.nbr_out) .. CA.ta("uncertain_txt", ee.vague_txt)
	--	tst = tst .. CA.ta("numbers", ee.numbers) -- .. CA.ta("argmX", argmX)
	tst = tst .. CA.ta("tabN", ee.tabN) .. CA.ta("nbr_txt", ee.nbr_txt)
	--	tst = tst .. CA.ta("digit_txt", ee.digit_txt) .. CA.ta("roman_txt", ee.roman_txt)
	--	tst = tst .. CA.ta("err", err) .. CA.ta("cat", cat)
	cat = cat or ""
	err = err or ""
	ee.cats = ee.cats or ""
	ee.errs = ee.errs or ""
	ee.wkt = wkt or ""
	ee.tst = tst or ""
	ee.cats = ee.cats .. cat
	ee.errs = ee.errs .. err
	return ee, ee.wkt
end -- function p.a_number( ee, base_in)

function p.roman_number_test1( t, word)
	local val, errx = MathRoman.roman2int(word, "  ")
--	t = t .. "\n* " .. CA.ta("nombre romain", word) .. CA.ta("valeur", val) .. CA.ta("erreur", errx)
	t = (t or "") .. CA.Tr() .. CA.Td(word) .. CA.Td(val) .. CA.Td(errx)
	return t
end -- function p.roman_number_test1( t, word)

--	vueRomains : XIJ=12 MCXI=1111 MCDXLIV=1444 MDCLXVI=1666 MCMXCIX=1999 MMCCXXII=2222 MMMMCMXCIX=4999 ERREURS=0 erreur caractere S en 7. XIA=11 erreur caractere A en 3. XJI=12 erreur caractere J avant la fin. IXC=89 erreur caracteres croissants. VLD=445 erreur caracteres croissants. MMMMM=5000 erreur > 4999. MMMMMYJXC=5089 erreur > 4999. erreur caractere Y en 6. erreur caractere J avant la fin.

function p.roman_number_test( t, args_known)
	-- Unitary tests of MathRoman.roman2int
	local t = tostring(t)
	t = t .. "\n:* '''roman_number_test'''."
	t = t .. CA.Th() .. CA.Tc("nombre romain") .. CA.Tc("valeur") .. CA.Tc("erreur")
	t = p.roman_number_test1( t, "0")
	t = p.roman_number_test1( t, "MCXI")
	t = p.roman_number_test1( t, "XIJ")
	t = p.roman_number_test1( t, "XJI")
	t = p.roman_number_test1( t, "XIA")
	t = p.roman_number_test1( t, "VLD")
	t = p.roman_number_test1( t, "IXC")
	t = p.roman_number_test1( t, "MMMMCMXCIX")
	t = p.roman_number_test1( t, "MMMMM")
	t = p.roman_number_test1( t, "MMMMMYJXC")
	t = t .. CA.Te()
	return t
end -- function p.roman_number_test( t, args_known)

-- Convert a digital or roman number to a year or century
-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.year_century( ee )
	ee.cats = ee.cats or ""
	ee.errs = ee.errs or ""
	local err, cat = "", ""
	ee.nowyear = CA.nowyear
	-- Type of arguments
	if ee.birthcentury then ee.argname = "birthcentury" end
	if ee.birthyear	   then ee.argname = "birthyear" end -- keep year rather than century
	if ee.deathcentury then ee.argname = "deathcentury" end
	if ee.deathyear	   then ee.argname = "deathyear" end -- keep year rather than century
	if ee.birthyear or ee.birthcentury then ee.event = "birth" end
	if ee.deathyear or ee.deathcentury then ee.event = "death" end
	-- Pour un évènement, on utilise l'argument année plus précis, sinon le siècle.
	if ee.event == "birth" then
		ee.nbr_in = ee.birthyear or ee.birthcentury -- keep year rather than century
	elseif ee.event == "death" then
		ee.nbr_in = ee.deathyear or ee.deathcentury -- keep year rather than century
	else -- Pour un évènement indéterminé, on utilise plutôt le décès pour les droits d'auteur, sinon la naissance.
		ee.nbr_in = ee.deathyear or ee.birthyear or ee.deathcentury or ee.birthcentury
	end
	local ee = p.a_number( ee, "digit")
	-- The number is a priori a year.
	-- Le nombre est à priori une année.
	ee.century = nil
	ee.year = ee.nbr_out
	-- A roman number defines a century, and cancel the year.
	-- Un nombre romain définit un siecle, et annule l'année.
	--	if ee.base_in == "roman" then
	if ee.base == "roman" then
		ee.century = ee.nbr_out
		ee.year = nil
	end
	-- A number coming from a century argument defines a century.
	-- Un nombre qui vient d'un argument de siècle définit un siecle.
	if ee.argname == "birthcentury" or ee.argname == "deathcentury" then
		ee.century = ee.nbr_out
		ee.year = nil
	end
	-- A number too big or too small to be a century is a year.
	-- Un nombre trop grand ou trop petit pour être un siècle est une année.
	-- L'Antiquité européenne commence au IVe millénaire BCE
	-- La civilisation de l'Indus (5000 BCE – 1900 BCE).
	-- In 2013, keep a margin of one unit (year or century).
	-- En 2013, garder une marge d'une unité (année ou siècle).
	if ee.nbr_out then
		if ee.nbr_out < -75 or 25 < ee.nbr_out then
			ee.century = nil
			ee.year = ee.nbr_out
		end
	end
	--
	-- Consequences for a year :
	-- Conséquences pour une année :
	if ee.year then
		ee.vague_year = ee.vague_digit or ee.vague_roman
		if ee.event == "birth" then
			-- Auteur par défaut à partir de 20 ans
			ee.event_author = ee.year + CA.constants.author_writing_after_birth
		elseif ee.event == "death" then
			-- Auteur par défaut jusqu'à 5 ans avant le décès
			ee.event_author = ee.year - CA.constants.author_writing_before_death
		else
			ee.event_author = ee.year
		end
		-- year. anno. année.
		ee.event_yr = ee.event_author
	--	if ee.epoch_arg then ee.event_yr = ee.epoch_arg end -- epoch_arg enforce epoch
		-- Assurer la continuité des années autour de 1 pour tous les calculs
		if ee.event_yr and ee.event_yr < 1 then ee.event_yr = ee.event_yr + 1 end
		-- Century from event year. Siglo de anno de evenement. Siècle selon l'annee de l'evenement.
		ee.event_century_abs = math.floor( math.abs(ee.event_author - 1 ) / 100 ) + 1
		if ee.event_author < 1 then
			ee.event_century = - ee.event_century_abs -- event negative century
			ee.event_century_roman = "-" .. MathRoman.int2roman(ee.event_century_abs)
		else
			ee.event_century = ee.event_century_abs -- event century
			ee.event_century_roman = MathRoman.int2roman(ee.event_century_abs)
		end
	elseif ee.century then -- Without year, do not shift event. Sans annee, ne pas decaler l'evenement.
		ee.vague_cent = ee.vague_digit or ee.vague_roman
		-- Event century. Siglo de evenement. Siècle d'evenement.
		ee.event_century_abs = math.abs(ee.century)
		if ee.century < 1 then
			ee.event_century = - ee.event_century_abs -- event negative century
			ee.event_century_roman = "-" .. MathRoman.int2roman( ee.event_century_abs )
		else -- ee.century_roman ?
			ee.event_century = ee.event_century_abs -- event positive century
			ee.event_century_roman = MathRoman.int2roman( ee.event_century_abs )
		end
	end
	--
	tst = "\n* year_century " -- tostring(tst) ..
	tst = tst .. CA.tam("event", ee.event) .. CA.tam("nbr_in", ee.nbr_in)
	tst = tst .. CA.tam("base", ee.base) -- .. CA.tam("base_in", ee.base_in)
	tst = tst .. CA.tam("year", ee.year) .. CA.tam("event_author", ee.event_author)
	tst = tst .. CA.tam("event_yr", ee.event_yr) .. CA.tam("century", ee.century)
	tst = tst .. CA.tam("event_ct", ee.event_ct) .. CA.tam("century_roman", ee.century_roman)
	tst = tst .. CA.tam("err", CA.error_color(err)) .. CA.tam("cat", cat)
	ee.wkt = tst
	ee.cats = ee.cats .. cat
	ee.errs = ee.errs .. err
	return ee, ee.wkt
end -- function p.year_century( ee )

-- Computes the epoch from a year or a century, and the region
-- Calcule l'époque pour une année ou un siècle, et pour une région
-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.century_epoch( ee)
	--	ee, tst = p.century_epoch( ee)
--	local err, cat = "", ""
	local epq, epoq, epoque = "", "", ""
	local wkt = wkt or ""
	local cats = cats or ""
	local tst = tst or ""
	local errs = errs or ""
	local ee = p.year_century( ee, "digit") -- wkt, cats, xxx, errs,
	--
	-- En Asie, l'Antiquité se termine à peu près vers l'an -200, avec la Dynastie Qin qui inaugure la période impériale en Chine et le début de la dynastie Chola en Inde.
	-- En Chine, la période des Printemps et Automnes s'étend de 770 à 453 BCE
	-- En Chine, la période des Royaumes combattants s'étend de 453 à 221 av. J.-C
	-- En Chine, la période de l'empire s'étend de 220 BCE à 1911.
	-- En Chine, la république commence en 1912.
	--
	-- En Inde, Des origines à l'Empire moghol (dynasties musulmanes venues de Perse et d'Afghanistan), dominant jusqu'au milieu du XVIIIe siècle. La période coloniale britannique (1750-1947), l'Empire britannique des Indes comprenant alors le Bangladesh et le Pakistan actuels, Depuis l'indépendance de l'Inde (1947-).
	-- En Inde, la civilisation de l'Indus (5000 BCE – 1900 BCE).
	-- En Inde, l'Antiquité finit vers l'an -200, suivie de la dynastie Chola.
	-- En Inde, la Civilisation védique en ... ?
	-- En Inde, Antiquité et Moyen Âge indien aux IVe et Ve siècles.
	-- En Inde, époque moderne depuis La colonie britannique (1750-1947).
	--
	-- l'Antiquité européenne commence au IVe millénaire BCE
	--
	-- A faire : valeurs autorisées pour un argument
	--	region_values			= "other/china/india/century",
	--	region_values			= "autre/chine/inde/siècle",
	--	args_values_err			= "Abnormal value of the argument %1",
	--	args_values_err			= "Valor anormal del argumento %1",
	--	args_values_err			= "Valeur anormale de l'argument %1",
	--	if ee.region and not string.find("other/china/india/century", ee.region) then
	--		ee.region = "fr"
	--		args_values_err = CA.str_vars("args_values_err", tostring(ee.region) )
	--		CA.err_add("Valeur anormale de l'argument %1" .. args_values_err)
	--	CA.cat_add( epoque, epoque, ee.c )
	--	end

	if (ee.region ~= "china") and (ee.region ~= "india") and (ee.region ~= "century") then
		ee.region = "other"
	end
	local liste_epoques = {
		{ reg = "china",	start = -9999, stop =	-771, cat = "cat_epoch_china_antiquity", val = "", },
		{ reg = "china",	start =	 -770, stop =	-221, cat = "cat_epoch_china_springs", val = "", },
		{ reg = "china",	start =	 -220, stop =	1911, cat = "cat_epoch_china_empires", val = "", },
		{ reg = "china",	start =	 1912, stop =	9999, cat = "cat_epoch_century_CE", val = ee.event_century_roman, },
		--[[
		{ reg = "india",	start = -9999, stop =  -1901, cat = "cat_epoch_indian_indus", val = "", },
		{ reg = "india",	start = -1900, stop =	 500, cat = "cat_epoch_indian_antiquity", val = "", },
		{ reg = "india",	start =	  501, stop =	1750, cat = "cat_epoch_indian_muslim", val = "", },
		{ reg = "india",	start =	 1751, stop =	9999, cat = "cat_epoch_century_CE", val = ee.event_century_roman, },
		--]]
		{ reg = "india",	start = -9999, stop =    300, cat = "cat_epoch_indian_antiquity", val = "", },
		{ reg = "india",	start =   301, stop =	1000, cat = "cat_epoch_indian_classic", val = "", },
		{ reg = "india",	start =	 1001, stop =	1600, cat = "cat_epoch_indian_middle_age", val = "", },
		{ reg = "india",	start =	 1601, stop =	9999, cat = "cat_epoch_century_CE", val = ee.event_century_roman, },
--	cat_epoch_indian_indus	l’antiquité indienne cat_epoch_indian_antiquity 300 301 période classique indienne cat_epoch_indian_classic 1000 1001 moyen-âge indien 1600 1601 période moderne à nos jours cat_epoch_century_CE cat_epoch_indian_muslim
		--
		{ reg = "century",	start = -9999, stop =	  -1, cat = "cat_epoch_century_BCE", val = ee.event_century_roman, },
		{ reg = "century",	start =	 1,	   stop =	9999, cat = "cat_epoch_century_CE", val = ee.event_century_roman, },
		--
		{ reg = "other",	start = -9999, stop =	 500, cat = "cat_epoch_antiquity", val = "", },
		{ reg = "other",	start =	  501, stop =	1400, cat = "cat_epoch_middle_age", val = "", },
		{ reg = "other",	start =	 1401, stop =	9999, cat = "cat_epoch_century_CE", val = ee.event_century_roman, },
	}
	-- BCE = Before Common Era = «BC». AEC = Antes de la Era Común = «a. C.». AEC = Avant l'ère commune = «av. J.-C.»
	local error_id = nil
	--
	for i, epq in pairs(liste_epoques) do -- Parmi toutes les époques définies
		if ee.region and ( epq.reg == ee.region) then
			if ee.event_author then
				if ( epq.start <= ee.event_author) and (ee.event_author <= epq.stop ) then
					cats = cats .. CA.cat_add(epq.cat, epq.val or "" )
				end
			elseif ee.event_century_roman then
				ee.event_ct100 = ee.event_century * 100 - 50
				if ( epq.start <= ee.event_ct100) and (ee.event_ct100 <= epq.stop ) then
					cats = cats .. CA.cat_add(epq.cat, epq.val or "" )
					if ee.vague and not ee.year and ee.century and ( epq.cat == "cat_epoch_century_CE" or epq.cat == "cat_epoch_century_BCE" ) then
						if ee.event == "birth" then
							-- Catégorie:Naissance en 18.. incertain
							cats = cats .. CA.cat_add("authors_birth_century", ee.century )
						elseif ee.event == "death" then
							-- Catégorie:Décès en 18.. incertain
							cats = cats .. CA.cat_add("authors_death_century", ee.century )
						end
					--	cats = cats .. CA.cat_add( epoque, epoque, ee.c )
					end
				end
			end
		end
	end
	-- Un seul nombre accepté
	if ee.tabN > 1 then -- verify the number is alone
		local arg_nm = CA.wiki_translations[ee.argname] -- p.args_final
		arg_nm = CA.error_color(arg_nm)
		errs = errs .. CA.err_add("err_one_number_argument", arg_nm )
	end
	-- Ambigüité des années en nombres romains
	if ee.year and ee.base and (ee.base == "roman") then
		errs = errs .. CA.err_add("err_year_in_roman_number", ee.nbr_in )
	end
	-- Year to compute the epoch, for an event or an author
	if ee.birthyear and tonumber(ee.year) then
		ee.epoch_year = tonumber(ee.year) + CA.constants.author_writing_after_birth
	end
	if ee.deathyear and tonumber(ee.year) then
		ee.epoch_year = tonumber(ee.year) - CA.constants.author_writing_before_death
	end
	ee.event_century_roman = ee.event_century_roman
	if ee.event == "birth" then ee.birth_century_roman = ee.event_century_roman end
	if ee.event == "death" then ee.death_century_roman = ee.event_century_roman end
	if ee.year and ee.year < 1 then -- Naissance en ...
		ee.year_out = CA.str_vars( "year_BCE", - ee.year )
	end
	--
	local tst = "\n* century_epoch "
	tst = tst .. CA.tam("event", ee.event) .. CA.tam("nbr_in", ee.nbr_in)
	tst = tst .. CA.tam("year", ee.year) .. CA.tam("event_author", ee.event_author)
	tst = tst .. CA.tam("century", ee.century) .. CA.tam("event_century_roman", ee.event_century_roman)
	tst = tst .. CA.tam("region", ee.region)
	tst = tst .. CA.tam("errs", CA.error_color(errs)) .. CA.tam("cat", cat)
	ee.wkt = tst
	ee.errs = ee.errs .. errs
	ee.cats = ee.cats .. cats
	return ee, tst
end -- function p.century_epoch( ee)

--[[
* ancien Modèle:Auteur :
Générer un nom d'époque à partir d'un numéro de siècle ou d'année, comme "du XVe siècle", ou "de l'Antiquité".
* Lier ce nom au texte précédent.
* S'adapter à des valeurs numériques ou non.
* Un auteur est dit du 20e siècle, de 1901 à 2000, s’il a écrit pendant ce siècle de 20 ans après sa naissance à 5 ans avant son décès.
* Cette règle automatique peut donc classer un auteur dans deux siècles ou deux époques à la fois.
* Le Ve siècle BCE s'étend de -500 à -401. Il n'existe pas d'an 0 ni de siècle 0 dans le calendrier grégorien ni dans le calendrier julien.
Les époques sont :
* à partir du siècle 15 (en l'an 1401 et suivants) : "du XVe siècle" et suivants
* des siècles 6 à 14 inclus (de l'an 501 à l'an 1400 inclus) : "du Moyen Âge"
* pour le siècle 5 et avant (avant l'an 501) : "de l'Antiquité"
* pour le siècle -9 et avant (avant l'an -800) : "de l'Antiquité chinoise"
* pour les années -771 et avant : "de l'Antiquité chinoise
* On ne catégorise les années de naissances et de décès que dans les 100 dernières années.
--]]

-- Générer les textes de categories et d'erreurs des annees et siecles.
-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.events_epochs(args_final, mode, c, verif)
--	local err, cat = "", ""
	local wkt = wkt or ""
	local cats = cats or ""
	local tst = tst or ""
	local errs = errs or ""
	if type(args_final) ~= "table" then args_final = CA.args_final end
	--
	local ee_birth = { c = ":", region = args_final.region, region_values = args_final.region_values, birthyear = args_final.birthyear, birthcentury = args_final.birthcentury, argname = "birthyear", event = "birth", errs = "", cats = "" }
	local ee_birth = p.century_epoch( ee_birth)
	if not args_final.epoch then cats = cats .. ee_birth.cats end
	-- cats = cats .. ee_birth.cats
	--
	local ee_death = { c = ":", region = args_final.region, region_values = args_final.region_values, deathyear = args_final.deathyear, deathcentury = args_final.deathcentury, argname = "deathyear", event = "death", errs = "", cats = "" }
	local ee_death = p.century_epoch( ee_death)
	if not args_final.epoch then cats = cats .. ee_death.cats end
	-- cats = cats .. ee_death.cats
	--
	-- Categorize the year of death for 100 years
	-- Clasificar el año que murió hace 100 años
	-- Catégoriser l'année de décès depuis 100 ans
	local year_limit = CA.nowyear - CA.constants.categorise_death_for_n_years
	if ee_birth.year and (year_limit  < ee_birth.year) then -- Naissance en ...
		cats = cats .. CA.cat_add( "authors_birthyear", ee_birth.year )
	end
	if ee_death.year and (year_limit  < ee_death.year) then -- Décès en ...
		cats = cats .. CA.cat_add( "authors_deathyear", ee_death.year )
	end
	--[[
	if ee_birth.year and ee_birth.year < 1 then -- Naissance en ...
		ee_birth.year_out = CA.str_vars( "year_BCE", - ee_birth.year )
	end
	if ee_death.year and ee_death.year < 1 then -- Décès en ...
		ee_death.year_out = CA.str_vars( "year_BCE", - ee_death.year )
	end --]]
	--
	-- Années ou siècles vagues incertains
	local epq = nil
	if		ee_birth.vague_year or ee_death.vague_year	then epq = "err_vague_year"
	elseif	ee_birth.vague_cent or ee_death.vague_cent	then epq = "err_vague_epoch"
	end
	if epq then
		cats = cats .. CA.cat_add( epq )
	end
	--
	-- Verify bith < death
	-- Comprobar nacer <muerte
	-- Vérifier naissance < Décès
	ee_birth.event_yr = tonumber(ee_birth.year) -- annees
	ee_death.event_yr = tonumber(ee_death.year)
	ee_birth.event_ct = tonumber(ee_birth.century) -- siecles
	if ee_birth.event_ct then ee_birth.event_ct = ee_birth.event_ct*100 end
	ee_death.event_ct = tonumber(ee_death.century)
	if ee_death.event_ct then ee_death.event_ct = ee_death.event_ct*100 end
	if ee_birth.event_yr and ee_birth.event_yr < 0 then ee_birth.event_yr = ee_birth.event_yr + 1 end
	if ee_death.event_yr and ee_death.event_yr < 0 then ee_death.event_yr = ee_death.event_yr + 1 end
	if ee_birth.event_ct and ee_birth.event_ct < 0 then ee_birth.event_ct = ee_birth.event_ct + 100 end
	if ee_death.event_ct and ee_death.event_ct < 0 then ee_death.event_ct = ee_death.event_ct + 100 end
	--	birth_yr = birth_yr or birth_ct
	--	death_yr = death_yr or death_ct
	--
	local birthdeath = true -- Vérifier naissance < Décès
	local lifetime = true -- Durée de vie anormale > 120 ans
	local lifetime_txt = "" -- Durée de vie anormale > 120 ans
	if ee_birth.event_yr and ee_death.event_yr then
		-- annee -> annee
		if ( (ee_birth.event_yr + CA.constants.lifetime_limit) < ee_death.event_yr ) then
			lifetime = false
			lifetime_txt = CA.str_vars("err_life_too_long", ee_birth.event_yr, ee_death.event_yr)
		end
		if ee_birth.event_yr > ee_death.event_yr then birthdeath = false end
	elseif ee_birth.event_ct and ee_death.event_yr then
		-- siecle -> annee
		if (ee_birth.event_ct + CA.constants.lifetime_limit) < ee_death.event_yr then
			lifetime = false
			lifetime_txt = CA.str_vars("err_life_too_long", ee_birth.event_ct, ee_death.event_yr)
		end
		if (ee_birth.event_ct - 100) > ee_death.event_yr then birthdeath = false end
	elseif ee_birth.event_yr and ee_death.event_ct then
		-- annee -> siecle
		if (ee_birth.event_yr + CA.constants.lifetime_limit) < (ee_death.event_ct - 100) then
			lifetime = false
			lifetime_txt = CA.str_vars("err_life_too_long", ee_birth.event_yr, (ee_death.event_ct - 100) )
		end
		if ee_birth.event_yr > (ee_death.event_ct) then birthdeath = false end
	elseif ee_birth.event_ct and ee_death.event_ct then
		-- siecle -> siecle
		if (ee_birth.event_ct + CA.constants.lifetime_limit) < ee_death.event_ct then
			lifetime = false
			lifetime_txt = CA.str_vars("err_life_too_long", ee_birth.event_ct, ee_death.event_ct)
		end
		if ee_birth.event_ct > ee_death.event_ct then birthdeath = false end
	end
	if not lifetime then
		-- err_life_too_long = "Durée de vie trop longue de %1 à %2.",
		errs = errs .. lifetime_txt -- CA.str_vars("err_life_too_long", ee_birth.year, ee_death.year)
		cats = cats .. CA.cat_add("err_life_too_long_cat")
		error_id = "err-year"..tostring(ee_birth.year)..">"..tostring(ee_death.year)
	end
	if not birthdeath then -- si naissance apres Décès pour year ou century
		--	err_death_before_birth	= "Error: death '''%1''' is before birth '''%2'''.",
		--	err_death_before_birth_cat= "Author death is before birth",
		errs = errs .. CA.str_vars("err_death_before_birth", ee_death.year, ee_birth.year)
		cats = cats .. CA.cat_add("err_death_before_birth_cat")
		error_id = "err-year"..tostring(ee_birth.year)..">"..tostring(ee_death.year)
	end
	if not (ee_birth.event_yr or ee_death.event_yr or ee_birth.event_ct or ee_death.event_ct) then
		-- no year no century. ni années ni siècles.
		-- Category:Unknown epoch. Catégorie:Epoque inconnue.
		cats = cats .. CA.cat_add("err_unknown_epoch_cat")
	end
	--
	-- birthcentury birthuncertain deathyear death deathcentury
	-- A faire : Catégorie:Siècle incertain
	--	return res, cat, err, t -- p.annees_epoques(args_final, mode, c, verif)
	--	res = res .. tostring(t) ; errors = errors .. err
	--
	errs = errs .. ee_birth.errs .. ee_death.errs
	tst = "\n* events_epochs "
	-- tst = tst .. CA.tam("event", ee_birth.event) .. CA.ta("nbr_in", ee_birth.nbr_in)
	if ee_birth.year then
		tst = tst .. CA.tam("birth.nbr_in", ee_birth.nbr_in)
		tst = tst .. CA.tam("birth.year", ee_birth.year)
		tst = tst .. CA.tam("birth.author", ee_birth.event_author)
	elseif ee_birth.century then
		tst = tst .. CA.tam("birth.nbr_in", ee_birth.nbr_in)
		tst = tst .. CA.tam("birth.century", ee_birth.century)
	end
	-- tst = tst .. "<br/>" .. CA.ta("event", ee_death.event) .. CA.ta("nbr_in", ee_death.nbr_in)
	if ee_death.year then
		tst = tst .. CA.tam("death.nbr_in", ee_death.nbr_in)
		tst = tst .. CA.tam("death.author", ee_death.year_author)
		tst = tst .. CA.tam("death.year", ee_death.year)
	elseif ee_death.century then
		tst = tst .. CA.tam("death.nbr_in", ee_death.nbr_in)
		tst = tst .. CA.tam("death.century", ee_death.century)
	end
	tst = tst .. CA.tam("region", ee_death.region)
	-- tst = tst .. CA.ta("birth_yr", birth_yr) .. CA.ta("death_yr", death_yr)
	-- tst = tst .. wkt
	tst = tst .. CA.tam("err", CA.error_color(err)) -- .. CA.ta("cats", cats)
	--
	-- Remplacer les siècles sans texte par X ème siècle
	local birth_txt, death_txt = "", ""
	if ee_birth.century and not ee_birth.year and not ee_birth.vague
		then birth_txt = ee_birth.event_century_roman
		else birth_txt = ee_birth.nbr_in end
	if ee_death.century and not ee_death.year and not ee_death.vague
		then death_txt = ee_death.event_century_roman
		else death_txt = ee_death.nbr_in end
	--
	birth_txt = ee_birth.vague_year or ee_birth.vague_cent or ""
	death_txt = ee_death.vague_year or ee_death.vague_cent or ""
	wkt = "<br/>(" .. ee_birth.nbr_in .. " - " .. ee_death.nbr_in .. ") " .. cats
	local events_text = "( " .. (ee_birth.year_out or ee_birth.nbr_in) .. " - " .. (ee_death.year_out or ee_death.nbr_in) .. " )"
	wkt = "<br/>" .. events_text .. " " .. cats
	--
	if ee_birth.error_roman then -- roman number error in ee_birth
		errs = errs .. CA.err_add("err_roman2int", ee_birth.roman_txt, ee_birth.nbr_out, ee_birth.error_roman, CA.user_translations.birth) -- "/birth"
	end
	if ee_death.error_roman then -- roman number error in ee_death
		errs = errs .. CA.err_add("err_roman2int", ee_death.roman_txt, ee_death.nbr_out, ee_death.error_roman, CA.user_translations.death) --  "/death")
	end
	--
	local ee = {}
	ee.birth_in = ee_birth.nbr_in
	ee.death_in = ee_death.nbr_in
	ee.events_text = events_text
	ee.wkt = wkt
	ee.tst = tst
	ee.errs = errs
	ee.cats = cats
	return ee -- wkt, cats, tst, errs, ee
end -- function p.events_epochs(args_final, mode, c, verif)

-- Generate the main box. Generar el cuadro principal. Générer la boîte principale.
function p.author_box(args_final)
	-- Generate the main box, in HTML
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local title = args_final.title
	local caption = args_final.caption
	local image = args_final.image
	local initiale = args_final.initiale
	local description = args_final.description
	local birthyear = args_final.birthyear
	local deathyear = args_final.deathyear
	local wikipedia = args_final.wikipedia
	local wikiquote = args_final.wikiquote
	local entityid = args_final.entityid
	local commons = args_final.commons
	local indexpages = args_final.indexpages
	local interwikis = {}
	local wt = ''
	--
	local ee = p.events_epochs(args_final, mode, c, verif)
	wt = wt .. ee.cats
	if type(description) ~= "string" then description = "" end
	description = description .. " " .. ee.events_text
	-- Generate image part of the table
	if type(image) == "string" then
		image = ''
		.. '<td valign="middle" align="center" rowspan="2" style=" border-left:{{{border|0}}}px solid #CCCCCC; ">'
			.. '<div id="AuthorImage" style=" padding:4px; ">'
				.. '[[File:' .. image .. '|frameless|170x170px||class=photo]]'
			.. '</div>'
		.. '</td>'
	else
		image = ""
	end
	-- Generate interwikis links
	local links = ""
	local cat_initiale = ''
	if type(initiale) == "string" then
		local authors_initiale_cat = CA.str_vars("authors_initiale_cat", initiale)
		local authors_initiale_txt = CA.str_vars("authors_initiale_txt", initiale)
		cat_initiale = "[[:" .. mw.site.namespaces.Category.name .. ":" .. authors_initiale_cat ..	 "|" .. authors_initiale_txt .. "]] "
		links = links .. '<span style="color:#aaaa66; line-height:90%; ">◀</span> ' .. cat_initiale .. ''
		-- Encode the character ◀=(U+25C0) '<<' (U+25C4)
	end
	if type(indexpages) == "string" then
		indexpages = string.gsub(indexpages, "%s", "+") -- space -> "+"
		indexpages = 'Special:IndexPages?key=' .. indexpages -- Victor+Hugo
		--	https://fr.wikisource.org/wiki/Sp%C3%A9cial:IndexPages?key=Tite-Live
		local mwtitle = mw.title.getCurrentTitle()
		local url = tostring(mwtitle:canonicalUrl( mwtitle.prefixedText ))
		local i = string.find(url, "/wiki/")
		if i and (i > 1) then
			CA.editstate = false
			links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[' .. string.sub(url, 1, i+6) .. indexpages .. ' Fac-similés] vue ' -- ..CA.ta("editstate", CA.editstate)
		end
		local i = string.find(url, "/w/")
		if i and (i > 1) then
			CA.editstate = true
			links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[' .. string.sub(url, 1, i-1) .. '/wiki/' .. indexpages .. ' Fac-similés] edit ' -- .. CA.ta("editstate", CA.editstate)
		end
		-- links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[//fr.wikisource.org/wiki/' .. indexpages .. ' Fac-similés] /2/ '
	end
	if type(wikipedia) == "string" then
		links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[[w:' .. CA.wiki_lang .. ':' .. wikipedia .. '|Biographie]]'
	end
	if type(wikiquote) == "string" then
		links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[[q:' .. CA.wiki_lang .. ':' .. wikiquote .. '|Citations]]'
	end
	if type(commons) == "string" then
		links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[[commons:' .. commons .. '|Médias]]'
	end
	if type(entityid) == "string" then -- https://www.wikidata.org/wiki/Q8023 for Nelson_Mandela
		local entityid_txt = CA.str_vars("entityid_txt")
		links = links .. '<br/><span style="color:#232388; ">• &nbsp;</span>[[d:' .. entityid .. '|' .. entityid_txt .. ']]'
	end
	-- FIXME: The french display is in HTML direct to better adapt the size and the look to plural environments.
	-- Generate scans to display
	local scans = p.HTMLscans(args_final)
	-- Generate the main box. width=99.9%; 
	wt = wt .. '<div id="Author" class="vcard" style="margin-right:5px; box-shadow:0.2em 0.2em 0.2em #EFEFEF; background-color:#F1F1DE; padding:0.3em; overflow-x:hidden; ">'
	  .. '<table cellspacing="0" cellpadding="0" style="background-color: transparent; border:0px solid #CCCCCC; padding:0em;">'
		.. '<tr>'
		  .. '<td valign="middle" rowspan="2" style="padding: 0em 0.6em; min-width:20%; background-color: #F1F1DE; text-align:left; font-size:80%; ">'
			.. '<div style="text-align:left; padding-top:0.5em; >'
			.. links
			.. '</div>'
		  .. '</td>'
		  .. '<td valign="top" align="center" style=" min-width:150px; border-left:0px solid #CCCCCC; padding:0.5em; ">'
			.. '<h1 id="AuthorName" style=" text-align:center; line-height:90%; font-size:160%; font-weight:bold; padding-top:0.1em; border-bottom: none; ">'
			  .. title 
			.. '</h1>'
		  .. '</td>'
		  .. image
		.. '</tr>'
		.. '<tr>'
		  .. '<td valign="top" align="center" style="width:100%; border-left:0px solid #CCCCCC; padding:1em; ">'
			.. '<span class="label" style=" font-size:110%; line-height:80%; text-align:center; " >'
			  .. description
			.. '</span>'
		  .. '</td>'
		.. '</tr>'
		.. '<tr>'
		  .. '<td valign="top" align="center" colspan="3" style="width:100%; border-top:0px solid #CCCCCC; ">'
			.. '<span class="label" style=" font-size:110%; line-height:80%; text-align:center; " >'
--			  .. scans
			.. '</span>'
		  .. '</td>'
		.. '</tr>'
	  .. '</table>'
	.. '</div>'
	wt = wt .. '<div style="bottom:0px; margin:1px; ">' .. AT.scans .. '</div>'
	return wt
end -- function p.author_box(args_final)

-- Interact arguments in international args_final
function p.interact_args_final(args_import)
	-- args_final = p.interact_args_final(args_import)
	if type(args_import) ~= "table" then args_import = CA.args_import end
	local args_final = mw.clone(args_import)
	local a = args_import
	local i = {} -- interact
	t = t .. "\n* begin :" .. CA.ta("initiale", a.initiale) .. CA.ta("firstname", a.firstname) .. CA.ta("lastname", a.lastname) .. CA.ta("title", a.title)
	--
	-- update sources of untouch arguments
	local k = " wd.src = "
	for key, argm in pairs(CA.args_known) do
		if CA.args_wikidata_import[key] then
		-- and args_final[key] and (CA.args_wikidata_import[key] == args_final[key])
			argm.src = "wd"
			k = k .. key .. ":" .. argm.src .. ", "
		end
	end
--	i.description = (a.description or " descr: ") .. k
	--
	local title = nil
--	if not a.title then -- If title is undefined, enforce it.
		if a.lastname and a.firstname then
			title = a.firstname .. " " .. a.lastname
		end
--		i.title = a.label or title or a.sitelink or a.lastname or CA.module_name
--		title = a.title or i.title
--	end
	if not a.title then -- If title is undefined, enforce it.
--		if a.lastname and a.firstname then
--			title = a.firstname .. " " .. a.lastname
--		end
		i.title = a.label or title or a.sitelink or a.lastname or CA.module_name
	end
	title = a.title or i.title
	--
	-- if absent, default link to other wikis
	if not a.wikipedia then i.wikipedia = i.title end
	if not a.wikiquote then i.wikiquote = i.title end
	if not a.commons then i.commons = i.title end
	if not a.indexpages then i.indexpages = i.title end
	--
	if a.sortkey and not a.initiale then
		-- If initiale is undefined, enforce it with the first word of sortkey.
		i.initiale = string.sub( a.sortkey, 1, 1 ) -- select the first letter
		i.initiale = string.upper( i.initiale or "" )
	end
	--
	if title and not a.initiale and not i.initiale then
		-- If initiale is undefined, enforce it with the last word of title.
		local tab = mw.text.split(title, '%s') -- table of words
		local max = table.maxn( tab )
		i.initiale = tab[max] -- select the last word
		i.initiale = string.sub( i.initiale, 1, 1 ) -- select the first letter
		i.initiale = string.upper( i.initiale or "" )
	end
	--
	if not a.sortkey then
		-- If sortkey is undefined, enforce it and inform the user.
		i.sortkey = a.sortkey or a.lastname or a.title
	end
	--
	if a.birth and not a.birthyear then
		local yyyy, err = CA.date_to_part(a.birth, "yyyy") -- , CA.str_vars("date_to_part_format")
		if yyyy then
			i.birthyear = yyyy
		else
			CA.err_add(err, CA.str_vars("birthyear"), "yyyy")
			CA.cat_add("date_to_part_call_cat")
		end
	end
	--
	if a.death and not a.deathyear then
		local yyyy, err = CA.date_to_part(a.death, "yyyy") -- , CA.str_vars("date_to_part_format")
		if yyyy then
			i.deathyear = yyyy
		else
			CA.err_add(err, CA.str_vars("deathyear"), "yyyy")
			CA.cat_add("date_to_part_call_cat")
		end
	end
	--
	if not a.notices then
		i.notices = CA.user_translations.authorities_selector or CA.wiki_translations.authorities_selector or "VIAF,BNF,SUDOC,LCCN,ISNI,Worldcat,6,NLA,PND,GKD,ARC"
		CA.args_wikidata, CA.args_wikidata_selected = p.authorities_select(i.notices, a)
	--	function p.authorities_select(authorities_selector, args_wikidata, args_known)
	end
	--
	-- if absent, synonym of basic arguments, syn = 1
--	if not a.birth then i.birth = (i.birthyear or a.birthyear) end
--	if not a.death then i.death = (i.deathyear or a.deathyear) end
--	if not a.birthyear then i.birthyear = (i.birth or a.birth) end
--	if not a.deathyear then i.deathyear = (i.death or a.death) end
--	i.birth = (i.birthyear or a.birthyear)
--	i.death = (i.deathyear or a.deathyear)
	--
	-- memorize interactions in CA.args_final and show errors or messages
	local n = 0
	for key, val in pairs(i) do
		local args_kwn = CA.args_known[key]
		if args_kwn then
			args_kwn.trk = (args_kwn.trk or "").."i"
			args_final[key] = val -- .. args_kwn.trk -- = i[key]
			args_kwn.src = nil -- automatic_argument value come from internal computing
			n = n + 1
			if (args_kwn.need == 2) and not a[key] then --
				-- need=2 necessary from argument or module interaction
				CA.msg_add("msg_auto_val_warning", CA.user_translations[key], val)
			--	CA.msg_add("msg_automatic_argument", CA.user_translations[key], val)
			end
		else
			CA.err_add("msg_auto_val_unknown", CA.wiki_translations[key], val)
		--	CA.err_add("msg_unknown_auto_arg", CA.wiki_translations[key], val)
		end
	end
--	if CA.args_known.title then CA.args_known.title.trk = (CA.args_known.title.trk or "").."i="..n end
	t = t .. "\n*: end :" .. CA.ta("initiale", a.initiale) .. CA.ta("firstname", a.firstname) .. CA.ta("lastname", a.lastname) .. CA.ta("title", a.title)
	CA.args_final = args_final
	return args_final, t
end -- function p.interact_args_final(args_final)

-- Identify the obsolete arguments from old template.
-- Repérer les arguments obsolètes de l'ancien modèle.
-- Identificar los argumentos obsoletos de viejos modelos.
function p.gener_oldargs(args_final)
	-- Si un ancien argument spécial est utilisé, mettre la page dans la catégorie prévue
	-- pour repérer toutes les pages concernées
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local res = ""
	local ifcat = false
	--	birth_text =	{typ = "oldargs", need = 0, list = 9, keyword = "birth_text", },
	for key, argm in pairs(CA.args_known) do -- Parmi toutes les époques définies
		if (argm.typ == "oldargs") and (argm.val ~= nil) then
			ifcat = true
		end
	end
	return res
	--	if ifcat then res = res .. CA.cat_add("Arguments obsolètes") end
	--	if not ifcat then res = res .. CA.cat_add("Arguments normaux") end
	-- 27/01/2014 19:14 Norm=0 Obso=0 somme=0 + 6495 = 6495 Auteurs
	-- 27/01/2014 21:12 Norm=2887 Obso=0 somme=2887 + 3608 = 6495 Auteurs
	-- 09/02/2014 22:50 Norm=3489 Obso=0 somme=3489 + 3006 = 6495 Auteurs
end -- function p.gener_oldargs(args_final)

function p.century_epoch_test1( t, event, region, birthyear, birthcentury, deathyear, deathcentury)
	local ee = { c = ":", nowyear = CA.nowyear, event = event, region = region, birthyear = birthyear, birthcentury = birthcentury, deathyear = deathyear, deathcentury = deathcentury }
	ee = AT.century_epoch( ee )
	if not ee.nbr_out then ee.nbr_out = "..." end
--	t = t .. "\n* century_epoch : " .. CA.ta("event", ee.event) .. " -> " .. CA.ta("region", ee.region) .. " -> " .. CA.tam("birthyear", ee.birthyear) .. CA.tam("birthcentury", ee.birthcentury) .. CA.tam("deathyear", ee.deathyear) .. CA.tam("deathcentury", ee.deathcentury) .. " -> " .. CA.ta("year", ee.year) .. CA.ta("nbr_out", ee.nbr_out) .. "<br/>:" .. CA.ta("epoch_year", ee.epoch_year) .. ", " .. ee.cats .. ", " .. CA.error_color(ee.errs)
	
	t = t .. CA.Tr() .. CA.Td(ee.event) .. CA.Td(ee.region) .. CA.Td(ee.birthyear) .. CA.Td(ee.birthcentury) .. CA.Td(ee.deathyear) .. CA.Td(ee.deathcentury)
	t = t .. CA.Td(ee.year) .. CA.Td(ee.nbr_out) .. CA.Td(ee.epoch_year)
	t = t .. CA.Td( (ee.cats or " ") .. " " .. (ee.errs or " ") )
	return t
end -- function p.century_epoch_test1( t, event, region, birthyear, birthcentury, deathyear, deathcentury)

function p.century_epoch_test( res, args_final)
	-- Unitary tests of p.a_number
	CA.catView = ":"
	local t = tostring(res)
	local headers = CA.Tc("event") .. CA.Tc("region") .. CA.Tc("birth year") .. CA.Tc("birth century") .. CA.Tc("death year") .. CA.Tc("death century") .. CA.Tc("year") .. CA.Tc("nbr out") .. CA.Tc("epoch year")
	--
	t = t .. "\n.\n:* '''China''' ( antiquity -770 springs -220 empires 1912 century ) (Authors write from 20 years.) "
	t = t .. CA.Th() .. headers .. CA.Td( "Catégories et erreurs " )
	t = t .. CA.Tr() .. headers .. CA.Td( " '''China''' ( antiquity -770 springs -220 empires 1912 century ) (Authors write from 20 years.) " )
	--
	t = p.century_epoch_test1( t, "birth", "china", "-792", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-791", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-790", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-789", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-788", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-241", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-240", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-239", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "-238", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "1891", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "1892", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "1980", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", "1981", nil, nil, nil)
	--[[
	t = t .. "\n.\n:* '''India''' ( indus -1900 antiquity 500 muslim 1750 century ) (Authors write from 20 years.) "
	t = p.century_epoch_test1( t, "birth", "india", "-1921", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "-1920", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "480", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "481", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1730", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1731", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1780", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1781", nil, nil, nil)
	--]]
	--
--	t = t .. "\n.\n:* '''India''' ( antiquity 300 301 classic 1000 1001 middle_age 1600 1601 modern ) (Authors write from 20 years.) "
	t = t .. CA.Tr() .. headers .. CA.Td("  '''India''' ( antiquity 300 301 classic 1000 1001 middle_age 1600 1601 modern ) (Authors write from 20 years.) ")
	t = p.century_epoch_test1( t, "birth", "india", "180", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "280", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "281", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "980", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "981", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1580", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1581", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1680", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "india", "1681", nil, nil, nil)
	--
--	t = t .. "\n.\n:* '''Other''' ( antiquity 500 middle_age 1400 century ) (Authors write from 20 years.) "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Other''' ( antiquity 500 middle_age 1400 century ) (Authors write from 20 years.) ")
	t = p.century_epoch_test1( t, "birth", "other", "-1000", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "480", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "481", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1380", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1381", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1480", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1481", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1580", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1581", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1880", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1881", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1980", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "1981", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "2080", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "2081", nil, nil, nil)
	t = p.century_epoch_test1( t, "death", "other", nil, nil, "2005", nil)
	t = p.century_epoch_test1( t, "death", "other", nil, nil, "2006", nil)
	--
--	t = t .. "\n.\n:* '''Century to epoch''' China ( antiquity -770 springs -220 empires 1912 century ). "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Century to epoch''' China ( antiquity -770 springs -220 empires 1912 century ). ")
	t = p.century_epoch_test1( t, "birth", "china", nil, "-9", nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", nil, "-8", nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", nil, "-7", nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", nil, "-3", nil, nil)
	t = p.century_epoch_test1( t, "birth", "china", nil, "-2", nil, nil)
	--
--	t = t .. "\n.\n:* '''Century to epoch''' Other ( antiquity 500 middle_age 1400 century ). "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Century to epoch''' Other ( antiquity 500 middle_age 1400 century ). ")
	t = p.century_epoch_test1( t, "birth", "other", nil, "4", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "5", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "6", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "13", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "14", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "15", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "16", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "19", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "20", nil, nil)
	--
--	t = t .. "\n.\n:* '''Region century''' always force centuries (Authors write from 20 years.) "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Region century''' always force centuries (Authors write from 20 years.) ")
	t = p.century_epoch_test1( t, "birth", "century", "-221", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "-220", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "-21", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "-20", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "-19", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "180", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "181", nil, nil, nil)
	--
--	t = t .. "\n.\n:* '''Year or century ?''' roman centuries from -75 to +25, else years. "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Year or century ?''' roman centuries from -75 to +25, else years. ")
	t = p.century_epoch_test1( t, "birth", "century", nil, "-CXI", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, nil, nil, "-CXI")
	t = p.century_epoch_test1( t, "birth", "century", "-CXI", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, nil, "-CXI", nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, "-LXXVI", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, "-LXXV", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, "XXV", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, "XXVI", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", "CXI", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, nil, "CXI", nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, "CXI", nil, nil)
	t = p.century_epoch_test1( t, "birth", "century", nil, nil, nil, "CXI")
	--
--	t = t .. "\n.\n:* '''Uncertain''' "
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Uncertain''' ")
	t = p.century_epoch_test1( t, "birth", "other", "vers -1357", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "vers MCXI", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "vers 1357 ou MCCCLIX", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "deux dates de naissance", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", "avant le X siècle", nil, nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, "avant le X siècle", nil, nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, nil, "avant le X siècle", nil)
	t = p.century_epoch_test1( t, "birth", "other", nil, nil, nil, "avant le X siècle")
	t = t .. CA.Te()
	--
	return t
end -- function p.century_epoch_test( res, args_final)

function p.events_epochs_test1( t, region, birthyear, birthcentury, deathyear, deathcentury)
	local args_final = { c = ":", nowyear = CA.nowyear, region = region, birthyear = birthyear, deathyear = deathyear }
	CA.catView = ":"
	local ee = AT.events_epochs(args_final, mode, ":", verif)
--		t = t .. "\n* events_epochs : " .. CA.ta("region", args_final.region)
--		t = t .. "<br/>:(" .. (ee.birth_in or "") .. " — " .. (ee.death_in or "") .. ") " .. ", " .. ee.cats .. ", " .. CA.error_color(ee.errs)
	t = t .. CA.Tr() .. CA.Td(region) .. CA.Td(ee.birth_in) .. CA.Td(ee.death_in) .. CA.Td( (ee.events_text or " ") .. ", " .. (ee.cats or " ") .. ", " .. (ee.errs or " ") )
--	t = t .. CA.Td("mi vie") .. CA.Td("force époque") .. CA.Td("siècle unique") .. CA.Td("catégories et erreurs <b>AVANT modification</b>")
	return t
end -- function p.events_epochs_test1( t, region, birthyear, birthcentury, deathyear, deathcentury)

-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.events_epochs_test(res, args_final)
	-- Unitary tests of p.a_number
	local t = tostring(res or "")
	CA.catView = ":"
	local nowyear = tonumber(os.date("%Y") ) -- local now_date = os.date("%Y-%m-%d %H:%M:%S")
--	t = t .. "\n* '''Epoque unique pour divers auteurs :'''"
--	t = t .. CA.Th() .. CA.Td("nom") .. CA.Td("région") .. CA.Td("né") .. CA.Td("mort")
--	t = t .. CA.Td("mi vie") .. CA.Td("force époque") .. CA.Td("siècle unique") .. CA.Td("catégories et erreurs <b>AVANT modification</b>")
	local headers = CA.Tc("region") .. CA.Tc("naissance") .. CA.Tc("décès")
	--
	t = t .. CA.Th() .. headers .. CA.Tc(" catégories et erreurs ")
	t = t .. CA.Tr() .. headers .. CA.Tc(" '''Durée de vie normale'''")
	t = p.events_epochs_test1( t, "other", "-519", nil, "-400", nil)
	t = p.events_epochs_test1( t, "other", "-33", nil, "33", nil)
	t = p.events_epochs_test1( t, "other", "82", nil, nil, "3")
	t = p.events_epochs_test1( t, "other", nil, "3", "419", nil)
	t = p.events_epochs_test1( t, "other", "400", nil, "519", nil)
	--
	t = t .. CA.Tr() .. headers .. CA.Td(" '''Exemples d'époques en Inde''' ")
	t = p.events_epochs_test1( t, "india", "-1958", nil, "-1834", nil)
	t = p.events_epochs_test1( t, "india", "1700", nil, "1777", nil)
	--
	t = t .. CA.Tr() .. headers .. CA.Tc(" '''Durée de vie anormale''' ")
	t = p.events_epochs_test1( t, "india", "-1758", nil, "-1834", nil)
	t = p.events_epochs_test1( t, "india", "1700", nil, "1677", nil)
	--
	t = t .. CA.Tr() .. headers .. CA.Tc(" '''Durée de vie > 120 ans de la naissance au décès'''")
	t = p.events_epochs_test1( t, "other", "-520", nil, "400", nil)
	t = p.events_epochs_test1( t, "other", "-20", nil, "100", nil)
	t = p.events_epochs_test1( t, "other", "400", nil, "520", nil)
	t = p.events_epochs_test1( t, "other", "400", nil, nil, "5")
	t = p.events_epochs_test1( t, "other", "400", nil, nil, "6")
	t = p.events_epochs_test1( t, "other", nil, "4", "555", nil)
	--
	t = t .. CA.Tr() .. headers .. CA.Tc(" '''Autres cas : pas d'époque''' ")
	t = p.events_epochs_test1( t, "other")
	--
	t = t .. CA.Tr() .. headers .. CA.Tc(" '''Autres cas : année ou siècle en nombre romain''' ")
	t = p.events_epochs_test1( t, "other", nil, "début du XVIIème siècle", "avant 1885", nil)
	t = p.events_epochs_test1( t, "other", "1768", nil, nil, "fin du XIXème siècle")
	t = p.events_epochs_test1( t, "other", "après CDLVII", nil, "585", nil)
	t = t .. CA.Te()
	--
	return t
end -- function p.events_epochs_test(res, args_final)

function CA.Th(t) return '\n{| class="wikitable alternative center" | ' .. tostring(t or " ") end -- Table header
-- ! style="text-align:left;"| Item
-- {| class="wikitable" style="text-align: center; color: green;"
-- {| border="1" style="border-collapse:collapse"
-- {| class="wikitable sortable" border="1" mw-collapsible mw-collapsed"
function CA.Tc(t) return '\n! scope="col" | ' .. tostring(t or " ") end -- Table row
function CA.Tr(t) return "\n|- " .. tostring(t or " ") end -- Table row
function CA.Td(t) return "\n| " .. tostring(t or " ") end -- Table data
function CA.Te(t) return "\n|}" end -- Table end

function CA.dropdown_func(if_view, title, content, ...)
	-- CA.dropdown_func(1, "Comptages des contenus de tables", CA.tables_comptes)
	-- CA.dropdown_func(1,  "Détails des arguments", CA.testable_lister, CA.args_source, "CA.args_source")
	local t = ""
	local func = ""
	if type(content) == "string" then -- optional arguments
		t = t .. content
	else
		func = content
		if type(func) == "function" then -- optional arguments
			t = t .. func(...)
		end
	end
	return CA.dropdown_box(if_view, title, t, nil, "===")
end -- function CA.dropdown_func(if_view, title, content, ...)

function p.events_century_test_life_2( t, region, birthyear, deathyear, epoch_arg, name)
	--local ee = AT.events_epochs(args_final, mode, ":", verif)
	local args_final = { c = ":", nowyear = CA.nowyear, region = region, birthyear = birthyear, deathyear = deathyear, epoch_arg = epoch_arg }
	CA.catView = ":"
	args_final = mw.clone(args_final) -- to not disturb args in final version
	if args_final and tonumber(args_final.birthyear) and tonumber(args_final.deathyear) then
		-- compute midle_life
		args_final.midle_life = math.floor( tonumber(args_final.birthyear) / 2 + tonumber(args_final.deathyear) / 2 )
	elseif args_final and tonumber(args_final.birthyear) then
		args_final.midle_life = tonumber(args_final.birthyear) + 20
	elseif args_final and tonumber(args_final.deathyear) then
		args_final.midle_life = tonumber(args_final.deathyear) - 5
	end
	if args_final and args_final.epoch_arg then
		args_final.midle_life = args_final.epoch_arg -- activate epoch_arg, else midle_life
	end
	if args_final and tonumber(args_final.midle_life) then
		args_final.midle_century = math.floor( tonumber(args_final.midle_life) / 100 )
		if args_final.midle_century > 0 then
			args_final.midle_century = args_final.midle_century + 1
		end
	end
--	local ee = AT.events_epochs(args_final, mode, ":", verif)
--	args_final.epoch_arg = epoch_arg
	local ee_epoch_arg = AT.events_epochs(args_final, mode, ":", verif)
	t = t .. CA.Tr() .. CA.Td(name) .. CA.Td(region) .. CA.Td(birthyear) .. CA.Td(deathyear)
	t = t .. CA.Td(args_final.midle_life) .. CA.Td(epoch_arg) .. CA.Td(args_final.midle_century)
	t = t .. CA.Td( (ee_epoch_arg.events_text or " ") .. " " .. (ee_epoch_arg.cats or " ") .. " " .. (ee_epoch_arg.errs or " ") )
	return t
end -- function p.events_century_test_life_2( t, region, birthyear, deathyear, epoch_arg, name)

-- In the chain of calls : p.a_number() p.year_century() p.century_epoch() p.events_epochs()
function p.events_century_test_life(res, args_final)
	-- Unitary tests of p.a_number
	local t = ""
	CA.catView = ":"
	local nowyear = tonumber(os.date("%Y") ) -- local now_date = os.date("%Y-%m-%d %H:%M:%S")
--	t = t .. "\n* '''Epoque unique pour divers auteurs :'''"
	if res then t = "\n* " .. tostring(res) .. " : "
	else t = "\n* '''Epoque unique pour divers auteurs :'''" end
	t = t .. "\n* Le siècle unique convient-il dans tous les cas ?"
	t = t .. CA.Th() .. CA.Tc("nom") .. CA.Tc("région") .. CA.Tc("né") .. CA.Tc("mort")
	t = t .. CA.Tc("mi vie") .. CA.Tc("force époque") .. CA.Tc("siècle unique") .. CA.Tc("catégories et erreurs <b>AVANT modification</b>")
	t = p.events_century_test_life_2( t, "china", " -551", " -479", nil, "Confucius")
	t = p.events_century_test_life_2( t, "other", "  -59", "   17", nil, "Tite-Live")
	t = p.events_century_test_life_2( t, "other", "  120", "  180", nil, "Aulu-Gelle")
	t = p.events_century_test_life_2( t, "century"," 400", "     ", nil, "Astérix")
	t = p.events_century_test_life_2( t, "century","    ", "  500", nil, "Obélix")
	t = p.events_century_test_life_2( t, "india", "  685", "  763", nil, "Shantideva")
	t = p.events_century_test_life_2( t, "other", " 1822", " 1909", nil, "Ernest Pinard")
	t = p.events_century_test_life_2( t, "other", " 1868", " 1955", nil, "Paul Claudel")
	t = p.events_century_test_life_2( t, "other", " 1955", " 1868", nil, "Claudel Paul")
	t = p.events_century_test_life_2( t, "other", " 1918", " 2013", nil, "Nelson Mandela")
	t = p.events_century_test_life_2( t, "other", " 1918", " 2013", "1678", "Nelson Mandela")
	t = t .. CA.Te()
	return t
end -- function p.events_century_test_life(res, args_final)

-- More detailed tests
-- Pruebas más detalladas
-- Tests détaillés supplémentaires
function p.gener_tests(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local res = "\n:.\n"
	local content = ""
	CA.catView = ":"
	res = res .. "\n<b>For other tests, look at [[" .. mw.site.namespaces.Module.name .. ":ControlArgs]].</b>"
--	local valid, infos = p.validDocBox()
--	res = res .. CA.dropdown_box(1, "validDocBox displays or not the documentation panel.", infos)
	res = res .. CA.dropdown_func(1, "Options and their uses. Options et leurs utilisations.", CA.used_options_list)
	res = res .. CA.dropdown_func(1, "Comptages des contenus de tables", CA.tables_comptes)
	res = res .. CA.dropdown_func(1, "Module, namespaces, and page names", CA.search_namespace)
	res = res .. CA.dropdown_func(1, "Données structurées de wikidata", CA.wikidata_test)
	res = res .. CA.dropdown_func(1, "Tester toutes les notices d'autorités", AT.HTMLnotice_test, nil, args_final)
	res = res .. CA.dropdown_func(1, "Sélection de notices de wikidata", p.authorities_select_test)
	res = res .. CA.dropdown_func(1, "Siècle unique pour divers auteurs", p.events_century_test_life)
	res = res .. CA.dropdown_func(1, "Détails des arguments reçus, args_source", CA.testable_lister, CA.args_source, "CA.args_source")
	res = res .. CA.dropdown_func(1, "Détails des arguments inconnus, args_unknown ", CA.testable_lister, CA.args_unknown, "CA.args_unknown")
	res = res .. CA.dropdown_func(1, "Manques de traductions i18n. Translations missing in i18n.", CA.verif_i18n, CA.i18n)
	res = res .. CA.dropdown_func(1, "Tests de nombres romains", p.roman_number_test , "Tests of roman to digital conversion : ", args_final)
	res = res .. CA.dropdown_func(1, "Siècles et époques selon les régions", AT.century_epoch_test, "Siècles et époques selon les régions : ", args_final)
	res = res .. CA.dropdown_func(1, "Evenements et époques", AT.events_epochs_test, "Evenements et époques. Events and epochs :", args_final)
	res = res .. CA.dropdown_func(1, "Siècle d'un auteur. Author's century.", p.events_century_test_life, "Siècle d'un auteur. Author's century :", args_final)
	res = res .. CA.dropdown_func(1, "Détails des arguments connus : args_known", CA.testable_lister, CA.args_known, "CA.args_known")
	res = res .. CA.dropdown_func(1, "Détails des tables de traductions : i18n", CA.testable_lister, CA.i18n, "CA.i18n")
	--
	CA.catView = CA.option(":")
	return res
end -- function p.gener_tests(args_final)

function p.gener_tests_init(args_source)
	if type(args_source) ~= "table" then args_source = CA.args_source end -- optional arguments
	--[[
	if lang == "en" then args_source = ArgtestEN end
	if lang == "es" then args_source = ArgtestES end
	if lang == "fr" then args_source = ArgtestFR end
	if not args_source.debug then args_source.debug = "docdata docdef docview docline " end
	--]]
--	if CA.i18n and CA.i18n.en then CA.i18n.en.error_i18n_wanted = 'EN error wanted' end
--	if CA.i18n and CA.i18n.es then CA.i18n.es.error_i18n_deseada = 'ES error deseada' end
--	if CA.i18n and CA.i18n.fr then CA.i18n.fr.error_i18n_voulue = 'FR erreur voulue' end
	if not args_source.description then args_source.description = "Victor Hugo est très connu." end
	if not args_source.genre then args_source.genre = "Romanciers/Poètes/Auteurs de théatre" end
	if not args_source.language then args_source.language = "français/japonais" end
	if not args_source.occupation then args_source.occupation = "Académiciens/Personnalités politiques" end
	if not args_source.prize then args_source.prize = "Nobel de littérature/Pulitzer" end
	if not args_source.wikipedia then args_source.wikipedia = "Alain Fournier" end
	if not args_source.wikiquote then args_source.wikiquote = "Charles Beaudelaire" end
	if not args_source.commons then args_source.commons = "Victor Hugo" end
	if not args_source.indexpages then args_source.indexpages = "Paul Claudel" end
	return
end -- function p.gener_tests_init(args_source)

-- relire ControlArgs/Author : module code in english

function p.get_namespaces()
	local res = ""
	local localspace = mw.title.getCurrentTitle().namespace -- tit.namespace: The namespace number.
	local canonicalName = mw.site.namespaces[localspace].canonicalName
	local isContent = mw.title.getCurrentTitle().isContentPage -- tit.isContentPage: Whether this title is in a content namespace.
	res = res .. CA.ta("localspace", localspace) .. CA.ta("canonicalName", canonicalName) .. CA.ta("isContent", isContent)
	local ns_tab = {}
	local ns = ""
	for ins = 1, 2000 do
	--	if mw.site.contentNamespaces[ins] then
		if mw.site.namespaces[ins] then
			ns = mw.site.namespaces[ins].canonicalName
			res = res .. CA.ta(ns, ins)
		end
	end
	return res
end -- function p.get_namespaces()

-- Show or no the documentation DocBox
-- Afficher ou non la documentation DocBox
function p.validDocBox()
--	local valid, infos = p.validDocBox()
	local res = ""
	local valid = true
	local isContent = mw.title.getCurrentTitle().isContentPage
	local Nspace = mw.title.getCurrentTitle().namespace
	local canonicalName = mw.site.namespaces[Nspace].canonicalName
	res = res .. "\n* "
	res = res .. CA.ta("namespace", canonicalName)
	res = res .. CA.ta("isContent", isContent)
	res = res .. CA.ta("namespaces valid", CA.str_vars("docbox_namespace_valid"))
	res = res .. CA.ta("namespaces error", CA.str_vars("docbox_namespace_error"))
	res = res .. CA.ta("namespaces stop", CA.str_vars("docbox_namespace_stop"))
--	res = res .. infos
	-- select by page name, namespace and isContent
	-- A faire ? to detect create mode : mw.title.getContent()
	local isContent = mw.title.getCurrentTitle().isContentPage
	local Nspace = mw.title.getCurrentTitle().namespace
	if Nspace == 0 then local canonicalName = "Main"
	else local canonicalName = mw.site.namespaces[Nspace].canonicalName end
	local canonicalName = mw.site.namespaces[Nspace].canonicalName
	local content_val = string.find( CA.str_vars("docbox_namespace_valid"), "isContent")
	local content_err = string.find( CA.str_vars("docbox_namespace_error"), "isContent")
	local content_stop = string.find( CA.str_vars("docbox_namespace_stop"), "isContent")
	local i_val = string.find( CA.str_vars("docbox_namespace_valid"), canonicalName)
	local i_err = string.find( CA.str_vars("docbox_namespace_error"), canonicalName)
	local i_stop = string.find( CA.str_vars("docbox_namespace_stop"), canonicalName)
	res = res .. "\n* " .. CA.ta("content_val", content_val) .. CA.ta("i_val", i_val) .. CA.ta("content_err", content_err) .. CA.ta("i_err", i_err) .. CA.ta("content_stop", content_stop) .. CA.ta("i_stop", i_stop) .. " <br/> "
	if ( i_val and (i_val > 0) ) or content_val then
		-- a valid namespace is ok for the documentation panel
	elseif ( i_err and (i_err > 0) ) or content_err then
		-- an error namespace is bad but not forbiden for the documentation panel
		CA.err_add("docbox_namespace_error_err", canonicalName)
		CA.cat_add("docbox_namespace_error_cat")
	elseif ( i_stop and (i_stop > 0) ) or content_stop then
		-- a stop namespace is forbiden for the documentation panel
		CA.cat_add("docbox_namespace_error_cat")
		valid = false
		return valid, res
	end
	return valid, res
end -- function p.validDocBox()

function p.docbox_namespace_error_and_cat()
	-- If DocBox is displayed out of Module or Template namespace, générate an error and a category "Module with usage error"
	-- Si DocBox est affiché hors de l'espace de nom Module ou Modèle, générer une erreur et une catégorie "erreur d'utilisation"
	local namespace = mw.title.getCurrentTitle().namespace
	local nsText = mw.title.getCurrentTitle().nsText
	if namespace ~= 10 and namespace ~= 828 then -- ns:Template and ns:Module
		CA.err_add("docbox_namespace_error_err", nsText)
		CA.cat_add("docbox_namespace_error_cat")
	end
	return
end -- function p.docbox_namespace_error_and_cat()

-- Display the documentation in an infobox, similar to edit-boxs
-- Affichage de documentation dans un cadre (box), semblable aux boites d'edition
function p.generDocBox(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local err = CA.verify_args_tables(CA.args_known, CA.args_source)
	if err then return err end
	p.docbox_namespace_error_and_cat()
	local res = CA.str_vars("err_delete_docbox")
	res = CA.error_color("<center><b>" .. res .. "</b><br/></center>")
	res = res .. "\n:.\n: " .. CA.sources_of_datas_colors()
	if CA.option("debug")		then res = res .. "\n*" .. CA.ta("p.catView", p.catView) .. CA.ta("p.invoke_options", p.invoke_options) .. CA.ta("p.mode_options", p.mode_options) end
	if CA.option("docdata")		then res = res .. "\n*" .. CA.generDoc(" docdef docline ", CA.args_wikidata_import, "Wikidata imported") end
--	if CA.option("docdata")		then res = res .. "\n*" .. CA.generDoc(" docdef docline ", CA.args_wikidata_selected, "Wikidata selected") end
	if CA.option("docview")		then res = res .. "\n*" .. CA.generDoc("", args_final, "Arguments") end
	if not CA.option("noerr")	then res = res .. "\n*" .. CA.errors_lister() end
	res = res .. "\n* " .. CA.categories_lister(":")
	res = '<div style=" width=90%; border: 1px solid #AAAAAA; margin:1em; background-color:#F1F1F1; padding:0.3em; ">' .. res .. '</div>'
	return res
end -- function p.generDocBox(args_final)

function p.editstate(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local res, normal = "", ""
	-- Version du 2014-07-22T15:52:54 = 4652115
	-- Version du 2014-07-28T00:32:29 = 4657071
	-- record REVISIONID at each edit of any page, in a class id REVISIONold of the page recorded.
	-- each time REVISIONID # REVISIONold the page is in edit state
	-- if the new 
	-- 2014-08-02T12:05:04‎ = REVISIONold = 4657071 , REVISIONID = 4662885 , REVISIONnew = true
--	local REVISIONID = frame:preprocess( string )
	local REVISIONold = tonumber("4657071") -- derniere de Module:Auteur3
	local REVISIONID = CA.frame:preprocess(" {{REVISIONID}} ") -- , REVISIONID = 4638129 a 20140802 11:09 de Tite-Live
	local REVISIONnbr = tonumber(REVISIONID)
	local REVISIONnew = (REVISIONnbr > REVISIONold)
	res = res .. CA.ta("REVISIONold", REVISIONold) .. CA.ta("REVISIONID", REVISIONID) .. CA.ta("REVISIONnew", REVISIONnew)
	--
	local REVISIONcontent = " REVISION content "
	local REVISIONzone = " REVISION zone "
	local mwtitle = mw.title.getCurrentTitle()
	local url = tostring(mwtitle:canonicalUrl( mwtitle.prefixedText ))
	local content = tostring(mwtitle:getContent()) -- unparsed content of the page, or nil
	local id = tostring(mwtitle.id) -- id: The page_id. 0 if the page does not exist.
	local i = string.find(content, "REVISIONID") or 1
	local j = string.find(content, "REVISIONID", i+7) or 1
	local i = string.find(content, "de") or 1
	local j = string.find(content, "de", i+7) or 1
	if i and (i > 1) and j and (j > 1) and ((j-i) < 20) then -- 
		REVISIONcontent = string.sub(content, i+10, j-1)
		REVISIONzone = string.sub(content, i-55, j+55)
	--	CA.editstate = false
	end
	--
	res = res .. CA.ta("REVISIONcontent", REVISIONcontent) .. CA.ta("id", id)
--	res = res .. " < < < < " .. string.sub(content, 1, 99) .. " X X X X " .. REVISIONzone .. " X X X X " .. string.sub(content, -99, -1) .. " > > > > "
	res = res .. " < < < < " .. content .. " > > > > "
	return res, REVISIONnew, REVISIONID, REVISIONcontent
end -- function p.editstate(args_final)

-- Normal result of the module
function p.gener_result(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local res, normal = "", ""
	if not CA.option("nobox")	then normal = normal .. p.author_box(args_final) end
	if not CA.option("nobox")	then p.gener_categories(args_final) end
--	local valid, infos = p.validDocBox()
	if CA.option("docview") then res = res .. p.generDocBox(args_final) end
	--
	res = res .. " " .. normal .. " "
	-- Générer normalement le wikitext, les catégories et autres
	if not CA.option("nobox")	then res = res .. microformat(CA.args_source, args_final) end
	if not CA.option("nobox")	then res = res .. p.author_rights(CA.args_source, args_final) end
	--	if not CA.option("nobox")	then res = res .. defaultsort(CA.args_source, args_final) end
	--	if not CA.option("nobox")	then Interprojet.interprojet( CA.frame ) end
	if not CA.option("nocat") then res = res .. CA.categorizer() end
--	local content = p.events_century_test_life("\n* Siècle unique pour divers auteurs : ")
	res = res .. CA.dropdown_func(1, "Siècle unique pour divers auteurs", p.events_century_test_life)
--	res = res .. CA.dropdown_func(1, "Sélection de notices de wikidata", p.authorities_select_test)
	return res
end -- function p.gener_result(args_final, lang)

-- relire ControlArgs/Author : module code in english

------------------------------------------------------------
-- Arguments sources exemples
------------------------------------------------------------

p.ArgtestEN = { c=": debug wikidata docview docdef docline docafter erron interon data-on test-on i18non ",
	--bug6 local ArgtestEN = { c=": docdef docline docafter ",
	lastname = "Pierre Yves-André de La Fontaine", rights = "50", image = "Carjat Arthur Rimbaud 1872 n2.jpg",
	birthyear = "before 1793", deathyear = "1850", region = "chine",
	description = "French poet.", genre = "Poètes‎", Prize = "Goncourt", prizze = "Lauréats du Prix Goncourt",
	occupation = "Idéologues/Personnalités politiques", language = "Littérature bretonne",
	BNF = "cb11888266r"
}

p.ArgtestES = { c=": debug wikidata docview docdef docline docafter erron interon data-on test-on i18non ",
	--bug6 local ArgtestES = { c=": docdef docline docafter ",
	nom = "Pierre Yves-André de La Fontaine", droits = "non", image = "Carjat Arthur Rimbaud 1872 n2.jpg",
	anneeNaissance = "antes 1793", anneeDeces = "1950", ["región"] = "chine",
	description = "Poeta francés", Pris = "Goncourt", genre = "Poètes‎", commons = "Andréas del Fontana‎",
	metier = "Idéologues/Personnalités politiques", prix = "Lauréats du Prix Goncourt", langue = "Littérature bretonne",
	BNF = "cb11888266r"
}

p.ArgtestFR = { c=": debug wikidata docview docdef docline docafter erron interon data-on test-on i18non ",
	--bug6 local ArgtestFR = { c=": docdef docline docafter ",
	nom = "Pierre Yves-André de La Fontaine", droits = "non", image = "Carjat Arthur Rimbaud 1872 n2.jpg",
	siecleNaissance = "au XJX ème", anneeDeces = "1950", ["région"] = "chine",
	description = "Poète français.", Pris = "Goncourt", genre = "Poètes‎",
	metier = "Idéologues/Personnalités politiques", prix = "Lauréats du Prix Goncourt", langue = "Littérature bretonne",
	BNF = "cb11888266r"
} -- err_roman2int

p.ArgtestFR_min = { c=": debug wikidata docview docdef docline docafter erron interon data-on test-on i18non ",
	--bug6 local ArgtestFR = { c=": docdef docline docafter ",
	nom = "Jacques Brel", droits = "70", image = "Carjat Arthur Rimbaud 1872 n2.jpg",
	anneeNaissance = " 1793", anneeDeces = "1970", ["région"] = "chine",
	description = "Poète français.", BNF = "11888266r"
}

-- ARCid = "R457-J-44", BNF = "45274126861", DNB = "3684200072", GKD = "71yhjey852", IBLid = "37581257954"
-- BNF = cb11888266r = Alain Fournier
-- LCCN = n/50/23101 = Alain Fournier
-- = http://www.worldcat.org/identities/lccn-n50-23101
-- NLA = 35096649 = Alain Fournier
-- PND = 11850133X = Alain Fournier
-- VIAF = 7396281 = Arthur Rimbaud
-- VIAF = 34452139 = Alain Fournier
-- worldcat = 35096649 = Happy Gilmore

-- relire ControlArgs/Author : module code in english

------------------------------------------------------------
-- Main interface to templates
-- Interfaz principales de modelos
-- Interface principal avec les modèles
------------------------------------------------------------

function p.base(frame, function_mode, mode_options)
	Interprojet.interprojet( frame )
	CA.time1 = os.clock()
	local res, t = "", ""
	CA.frame = frame
	CA.module_name = CA.frame:getTitle() -- example "Module:Author"
	local lang = tostring(mw.language.getContentLanguage().code)
	-- import and count sources arguments in wiki language
	local args_invoke = frame.args
	local args_template = frame:getParent().args
	--
	--	Add or replace all the arguments from the template inside arguments from the module.
	--	Remplacer ou ajouter tous les champs du modèle dans ceux du module.
	local args_source, args_src_ni, args_src_nn = CA.table_mixer(args_invoke, args_template)
	CA.args_source = args_source
--	CA.args_source = p.ArgtestFR
	--	CA.args_source = p.ArgtestFR_min -- ArgtestFR_min
	--
	CA.nowyear = tonumber(os.date("%Y") ) -- local now_date = os.date("%Y-%m-%d %H:%M:%S")
	-- Initialize i18n languages tables
	CA.add_i18n(CA.i18n_args)
	--	CA.add_i18n("Module:ControlArgs/I18N")
	CA.add_i18n(p.i18n_args)
	--	CA.add_i18n(CA.module_name .. "/I18N")
	CA.categories_init() -- initialize the category list
	CA.init_user_lang(lang, CA.wiki_translations)
	CA.verif_i18n("Module:ControlArgs/I18N")
	if function_mode == "langtest" then
		CA.args_source = p.ArgtestEN
	end
	CA.args_source.langues = "chinois,grec"
	CA.init_args( p.args_known_default, CA.args_source, lang, msgs_list)
	--
	-- Import and adapt wikidata
	CA.args_wikidata_import, t = CA.import_wikidata(CA.args_known)
	-- CA.args_wikidata, CA.args_wikidata_selected, t = p.authorities_select()
--	function p.authorities_select(authorities_selector, args_wikidata, args_known)
--	CA.args_wikidata = CA.args_wikidata_selected
	CA.import_arguments(p.args_known_default, CA.args_source) --, CA.wiki_translations, CA.args_wikidata)
	--	CA.args_import, t = CA.import_arguments(p.args_known_default, CA.args_source, CA.wiki_translations, CA.args_wikidata)
	--	res = res .. "\n* " .. CA.ta("CA.import_arguments_err", CA.import_arguments_err)
	--
	-- Interactions between argumensts (title, initiale, mode)
	-- Interactions entre parametres (title, initiale, mode)
	CA.args_final = p.interact_args_final(CA.args_import)
	--
	-- Mode from arguments
	CA.args_final.mode = args_template.mode or args_template[1] or args_template["1"]
	or args_invoke.mode or args_invoke[1] or args_invoke["1"]
	or function_mode or "normal"
	CA.mode_name = CA.args_final.mode
	CA.time2 = os.clock()
	--
	-- Options from mode
	if CA.mode_name == "normal" then
		mode_options = "noerr nocat"
	elseif CA.mode_name == "doc" then
		mode_options = " : docdef docview docline"
	elseif CA.mode_name == "notice" then
		mode_options = "noerr nocat"
	elseif CA.mode_name == "langtest" then
		mode_options = " : docdef docview docline docdata"
	elseif CA.mode_name == "tests" then
		mode_options = " : docdef docview docline docdata tests"
	end
	CA.mode_options = mode_options
	--
	local res_function = "\n" .. CA.module_name .. ":" .. CA.mode_name .. ":" .. CA.wiki_lang .. " "
	if CA.mode_name == "doc" or CA.mode_name == "tests" then
--		res = res .. "<br/>" .. res_function
	end
	if CA.mode_name == "langtest" then
		-- Detailed tests depends from options
		res = res .. CA.tests_langs(args_known, args_source)
	elseif CA.mode_name == "tests" then
		CA.trc = "\n* CA.tests : Traces du module."
		p.gener_tests_init(CA.args_source)
		-- Generate normal wikitext, categories, and others
		res = res .. p.gener_result(args_final, lang)
		res = res .. p.gener_tests(CA.args_final)
	elseif CA.mode_name == "notice" then
		-- Generate autority notices. Generer la ou les notices.
		res = res .. p.gener_notices(CA.args_known, CA.args_final)
	elseif CA.mode_name == "doc" then
		-- Generate normal wikitext, categories, and others
		res = res .. p.gener_result(args_final, lang)
		-- modif to test also
	elseif CA.mode_name == "oldargs" then
		-- Identify the special arguments of the previous template.
		-- Repérer les arguments spéciaux de l'ancien modèle.
		CA.categories_list = { }
		CA.args_final = { }
		p.gener_oldargs(args_final)
		res = res .. CA.categories_lister() -- categories in wikitext
	else
		-- Generate normal wikitext, categories, and others
		res = res .. p.gener_result(args_final, lang)
	end
	CA.time3 = os.clock()
	--
	-- Detailed tests and depends from options
	--	res = res .. CA.tables_comptes("\n* Comptes des tables '''base''' : ")
	if CA.mode_name == "tests" then
--		res = res .. p.gener_tests(CA.args_final)
	end
	CA.time4 = os.clock()
	--
	if CA.option("tests") or CA.option("debug") then -- or CA.option("docview")
		res = res .. CA.tests_time(true, "")
--		res = res .. res_function
	end
	return res
end -- function p.base(frame, function_mode, mode_options)

------------------------------------------------------------
-- Interfaces, alias and functions to templates
-- Interfaces, alias y funciones para modelos
-- Interfaces, allias et fonctions pour les modèles
------------------------------------------------------------

function p.normal(frame)
	return p.base(frame, "normal", "noerr ")
end

function p.doc(frame)
	return p.base(frame, "doc", " : docdef docview docline docsrc")
end
--[ [
function p.tests(frame)
	return p.base(frame, "tests", " : docdef docview docline docsrc docdata tests ")
end --] ]

function p.langtest(frame)
	return p.base(frame, "langtest", "noerr nocat docsrc")
end

------------------------------------------------------------
-- Interface to generate independent authority notices.
-- Interfaz para generar autoridad independiente instrucciones.
-- Interface pour générer les notices d'autorités indépendantes.
------------------------------------------------------------

function p.instructions(frame) return p.notice(frame) end
function p.instrucciones(frame) return p.notice(frame) end
function p.notices(frame) return p.notice(frame) end
function p.notice(frame)
	return p.base(frame, "notice", "docdata docdef docview docline")
end

return p