Module:Centralizer

Une page de Wikiversité.
Sauter à la navigation Sauter à la recherche

Documentations and live examples[modifier le wikicode]

Doc with item = docitem[modifier le wikicode]

{{Centralizer|doc|dockey=versions_support_desk_title|docitem=Q535}}


Doc with function from string[modifier le wikicode]

{{Centralizer|doc|dockey=modes_get_args_report_title|docfunc=modes.get_args_report}}


Central normal read mode[modifier le wikicode]

{{Centralizer|read|QITEM=Q535}}

modes.mode_name = read , modes.options = nil ,
(p.box_read)
firstname: Galileo, sitelink: nil - Datas

Labels in langs: Galileo.arp.300pix.jpg, user: nil, content: Galilée, page: Galilée
description: physicien, philosophe et astronome italien ( 1564 - 1642 )

Flag of England.svg * used languages: user:⧼Lang⧽, content:fr, page:fr * Galileo.arp.300pix.jpg
catview = Module with internal error Module with usage error

Edit mode example for English user / Local project[modifier le wikicode]

{{Centralizer|edit|contentlang=en|pagelang=en|userlang=en|itemid=Q868|QITEM=Q868}}

Library:langsmodes.mode_name = edit , modes.options = nil ,
(p.box_read)
firstname: Galileo, sitelink: nil - Datas

Labels in langs: Galileo.arp.300pix.jpg, user: nil, content: Galilée, page: Galilée
description: physicien, philosophe et astronome italien ( 1564 - 1642 )

Flag of England.svg * used languages: user:⧼Lang⧽, content:fr, page:fr * Galileo.arp.300pix.jpg
catview = Module with internal error Module with usage error
  • datas.default_item = Q307, datas.default_name = Q307
Centralizer 1.0.0(181227T22:44), content = en , page = en , user = en , - User manual - viewers.phab_task('T135845', 'Convert') - viewers.phab_task('T198107', 'Begin to use')
You must remove this documentation before recording.
Remove all modes to return to read mode.

  • Module:Centralizer err_args_final=nil
    contentlang = en , title = Q868 , QITEM = Q868 , pagelang = en , itemid = Q868 , userlang = en , , ( properties)
  • Arguments contentlang = en , title = Q868 , QITEM = Q868 , pagelang = en , itemid = Q868 , userlang = en ,
  • Support on the parameters of this model:
    * Error: This unnamed argument is too many: 1 = edit.
    * Error: parameter contentlang is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument contentlang ?
    * Error: parameter QITEM is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument QITEM ?
    * Error: parameter pagelang is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument pagelang ?
    * Error: parameter userlang is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument userlang ?
    * Error: parameter itemid is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument itemid ?
    * Module with internal error
    * Module with internal error
    * Module with usage error This module can translate 270 sentences into 7 languages: 282-brezhoneg(br=Breton), 234-Deutsch(de=German), 282-English(en=English), 283-español(es=Spanish), 283-français(fr=French), 246-magyar(hu=Hungarian), 282-Tiếng Việt(vi=Vietnamese),
  • Edit mode example for Spanish user / Local project[modifier le wikicode]

    {{Centralizer|edit|contentlang=es|pagelang=es|userlang=es|itemid=Q8023|QITEM=Q8023}}

    Library:langsmodes.mode_name = edit , modes.options = nil ,
    (p.box_read)
    firstname: Galileo, sitelink: nil - Datas

    Labels in langs: Galileo.arp.300pix.jpg, user: nil, content: Galilée, page: Galilée
    description: physicien, philosophe et astronome italien ( 1564 - 1642 )

    Flag of England.svg * used languages: user:⧼Lang⧽, content:fr, page:fr * Galileo.arp.300pix.jpg
    catview = Module with internal error Module with usage error Módulo con interno error
    • datas.default_item = Q307, datas.default_name = Q307
    Centralizer 1.0.0(181227T22:44), content = es , page = es , user = es , - User manual - viewers.phab_task('T135845', 'Convert') - viewers.phab_task('T198107', 'Begin to use')
    Debe quitar esta documentación antes de grabar.
    Retire todos los modos para volver al modo read.

  • Module:Centralizer err_args_final=nil
    contentlang = es , titulo = Q8023 , QITEM = Q8023 , pagelang = es , itemid = Q8023 , userlang = es , , ( properties)
  • Arguments contentlang = es , titulo = Q8023 , QITEM = Q8023 , pagelang = es , itemid = Q8023 , userlang = es ,
  • Asistencia de los parámetros de este modelo:
    * Error: Demasiado argumento sin nombre: 1 = edit.
    * Error: El parámetro contentlang es desconocido en este modelo. Compruebe el nombre o reportar esta falta.
    * Error : ¿Es usted conocido argumento contentlang ?
    * Error: El parámetro QITEM es desconocido en este modelo. Compruebe el nombre o reportar esta falta.
    * Error : ¿Es usted conocido argumento QITEM ?
    * Error: El parámetro pagelang es desconocido en este modelo. Compruebe el nombre o reportar esta falta.
    * Error : ¿Es usted conocido argumento pagelang ?
    * Error: El parámetro userlang es desconocido en este modelo. Compruebe el nombre o reportar esta falta.
    * Error : ¿Es usted conocido argumento userlang ?
    * Error: El parámetro itemid es desconocido en este modelo. Compruebe el nombre o reportar esta falta.
    * Error : ¿Es usted conocido argumento itemid ?
    * Módulo con error interno
    * Module with internal error
    * versions_err_module_miss_i18n_cat
    * Módulo con error del uso
    * Módulo con interno error Este módulo puede traducir 270 frases en 7 idiomas: 282-brezhoneg( br = Breton ), 234-Deutsch( de = German ), 282-English( en = English ), 283-español( es = Spanish ), 283-français( fr = French ), 246-magyar( hu = Hungarian ), 282-Tiếng Việt( vi = Vietnamese ),
  • Edit mode example for French user / Local project[modifier le wikicode]

    {{Centralizer|edit|contentlang=fr|pagelang=fr|userlang=fr|itemid=Q34743|QITEM=Q34743}}

    Library:langsmodes.mode_name = edit , modes.options = nil ,
    (p.box_read)
    firstname: Galileo, sitelink: nil - Datas

    Labels in langs: Galileo.arp.300pix.jpg, user: nil, content: Galilée, page: Galilée
    description: physicien, philosophe et astronome italien ( 1564 - 1642 )

    Flag of England.svg * used languages: user:⧼Lang⧽, content:fr, page:fr * Galileo.arp.300pix.jpg
    catview = Module with internal error Module with usage error
    • datas.default_item = Q307, datas.default_name = Q307
    Centralizer 1.0.0(181227T22:44), content = fr , page = fr , user = fr , - User manual - viewers.phab_task('T135845', 'Convert') - viewers.phab_task('T198107', 'Begin to use')
    Vous devez suprimer cette documentation avant d'enregistrer.
    Supprimez tous les modes pour revenir en mode read.

  • Module:Centralizer err_args_final=nil
    contentlang = fr , titre = Q34743 , QITEM = Q34743 , pagelang = fr , itemid = Q34743 , userlang = fr , , ( properties)
  • Arguments contentlang = fr , titre = Q34743 , QITEM = Q34743 , pagelang = fr , itemid = Q34743 , userlang = fr ,
  • Assistance sur les paramètres de ce modèle :
    * Erreur : Ce paramètre non nommé est en trop : 1 = edit.
    * Erreur : Le paramètre contentlang est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.
    * Erreur : Voulez vous l'argument connu contentlang ?
    * Erreur : Le paramètre QITEM est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.
    * Erreur : Voulez vous l'argument connu QITEM ?
    * Erreur : Le paramètre pagelang est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.
    * Erreur : Voulez vous l'argument connu pagelang ?
    * Erreur : Le paramètre userlang est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.
    * Erreur : Voulez vous l'argument connu userlang ?
    * Erreur : Le paramètre itemid est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.
    * Erreur : Voulez vous l'argument connu itemid ?
    * Module avec erreur interne
    * Module with internal error
    * versions_err_module_miss_i18n_cat
    * Module avec erreur d'utilisation Ce module peut traduire 270 phrases en 7 langues : 282-brezhoneg(br=Breton), 234-Deutsch(de=German), 282-English(en=English), 283-español(es=Spanish), 283-français(fr=French), 246-magyar(hu=Hungarian), 282-Tiếng Việt(vi=Vietnamese),
  • Tests mode example[modifier le wikicode]

    {{Centralizer|tests|itemid=Q535|QITEM=Q535}}

    • ARGS.t=, CNT.t=modes.mode_name = tests , modes.options = nil ,
      (p.box_read)
      firstname: Galileo, sitelink: nil - Datas

      Labels in langs: Galileo.arp.300pix.jpg, user: nil, content: Galilée, page: Galilée
      description: physicien, philosophe et astronome italien ( 1564 - 1642 )

      Flag of England.svg * used languages: user:⧼Lang⧽, content:fr, page:fr * Galileo.arp.300pix.jpg
      catview = Module with internal error Module with usage error
    • datas.default_item = Q307, datas.default_name = Q307
    Centralizer 1.0.0(181227T22:44), content = fr , page = fr , user = ⧼Lang⧽ , - User manual - viewers.phab_task('T135845', 'Convert') - viewers.phab_task('T198107', 'Begin to use')
    You must remove this documentation before recording.
    Remove all modes to return to read mode.

  • Module:Centralizer err_args_final=nil
    title = Q535 , QITEM = Q535 , itemid = Q535 , , (%1 properties);""
  • Arguments title = Q535 , QITEM = Q535 , itemid = Q535 ,
  • Support on the parameters of this model:
    * Error: This unnamed argument is too many: 1 = tests.
    * Error: parameter itemid is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument itemid ?
    * Error: parameter QITEM is unknown in this template. Check the name or report this gap.
    * Error: Do you need the known argument QITEM ?
    * Module with internal error
    * Module with internal error
    * Module with usage error This module can translate 270 sentences into 7 languages: 282-brezhoneg(br=Breton), 234-Deutsch(de=German), 282-English(en=English), 283-español(es=Spanish), 283-français(fr=French), 246-magyar(hu=Hungarian), 282-Tiếng Việt(vi=Vietnamese),
  • Display : langs_main_i18n_languages_list and langs_list_MediaWiki_languages_title
  • viewers_section_title_page

    viewers_section_title_module

    • versions.running_times() Running times and references for Lua-coders.
    • Local MediaWiki version = 1.35.0-wmf.2 (c045ed1) time=2018-12-20T17:20:46 ,
    • . Modules: Main module = Module:Centralizer , Proto version = Centralizer , Modules in this wiki = 376 ,
    • . Central module version: versionName = Centralizer , versionNumber = 1.0.0(181227T22:44) , versionDate = 2018-12-27T22:44:00 , taskDescription = enough advanced to use in CentralSchool OK ,
    • Users activities: activeUsers = 104 , Administrators(sysop) = 9 , bots(bot) = 9 , patrollers(patroller) = 60 , bureaucrats(bureaucrat) = 2 ,
    • Statistics on users and content mw mw:Special:ListGroupRights
    • Wivivi: In which language do you read Wikipedia?
    • Last revision: REVISIONTIMESTAMP = 20190508191120 , REVISIONUSER = Crochet.david.bot ,
    • Languages: PAGELANGUAGE = fr , CONTENTLANGUAGE = fr ,
    • User language: ⧼Lang⧽ = ⧼Lang⧽ , ⧼es⧽ = ⧼es⧽ , {{int:Lang}} = ⧼Lang⧽ , USERLANG = Modèle:USERLANG , UILANGCODE = Modèle:UILANGCODE , USERLANG = Modèle:USERLANG , USERLANGUAGE = Modèle:USERLANGUAGE , USERIFCODE = Modèle:USERIFCODE ,
    • Scribunto: , Extension:Scribunto Lua manual , version : = Lua 5.1 ,
    • Server mw.uri.new: protocol = nil , user = nil , password = nil , main_title = nil , label = nil , text = nil , host = fr.wikiversity.org , port = nil , path = /wiki/Module:Centralizer , query = nil , fragment = nil , userInfo = nil , hostPort = fr.wikiversity.org , authority = fr.wikiversity.org , queryString = nil , relativePath = /wiki/Module:Centralizer ,
    • Execution time and page: 2019-10-19 17:57:20 UTC, url = https://fr.wikiversity.org/wiki/Module:Centralizer ,
    • Running times: start in page = 6820 mS , import + 0 mS , form result + 0 mS , tests + 524 mS , duration = 524 mS ,

    local p = {}
    -- The main central module is mainly an installer of central libraries and a small demonstrator. OK for fr.wikiversity.org
    -- The main central module installs central libraries and bind the main and its sub-modules
    local Central = p -- Save as MdCentral.lua MdCentral from levenshtein_similar_tests OK 190202 0000.lua
    ------------------------------------------|------------------------ typical length --------------------------|----------max| DODO
    -- function drop_box.new(selector, title, content_or_func, ...) -- Formats a drop_box for a doc or a group of tests. Take apart onedrop options.
    
    -- MUMU : means to report in the CentralManual.
    -- MWMW : means add a mw version in the table versions.MediaWiki_Versions = { ... }
    -- COCO : is the present change point of Lua codage.
    -- MUMU : means to report in the CentralManual.
    
    p.teststests = "FAMLTVQDR"
    
    p.version = { -- Modules dependencies. Dependencias del módulo. Dépendances du module.
    	['versionFrom']			= "CentralTest begin debug from function modes.levenshtein_similar_tests OK.lua",
    	['versionName']			= "Centralizer",
    	['versionNumber']		= "1.0.0(190202T00:00)",
    	['versionDate']			=   "2019-02-02T00:00:00", -- UTC version structure MWMW
    	['mainDescription']		= "Begin to use",
    	['functionDescription'] = "first functional support",
    	['taskDescription']		= "enough advanced to use in CentralSchool OK",
    	--	p_template_drop_box_name		= 'Cuadro desplegable', -- Equivalent templates exist in other wikis
    	['sought']				= "Centralizer;Centralizer/I18N;Mathroman;TestRequire", -- Sought module and submodules versions
    	['known']				= "Centralizer;Central-s-fr;Central-14 * Centralizer/I18N;Central/i18n * Mathroman22;Mathroman34", -- Known module and submodules versions
    	['treebranches'] = { -- For each sought. Replace known. Later on 201811207
    		{ "Centralizer", "Central-s-fr", "Central-2017" }, -- upper
    		{ "Centralizer/I18N", "Central-s-fr", "Central-2018" }, -- median luatable
    		{ "Mathroman22", "Mathroman34" }, -- lower
    	}
    }
    Central.Central_version_name = Central.version.versionName
    p.ModuleNS = mw.site.namespaces.Module.name .. ":" -- translate Module: in other languages
    
    --	cut_libraries
    --------------------------------------------------|------------------------ typical length --------------------------|----------max| DODO
    
    -- only for ModuleCentralizer : restart from : ModuleCentralizer function modes.levenshtein_similar_tests OK.lua DODO
    -- only for ModuleCentralizer : then in function p.init_central_module() group only all sub-functions in the original order then delete duplicated one's
    -- only for ModuleCentralizer : then use function p.init_central_module() to replace function Central.init()
    -- only for ModuleCentralizer : delete tests_groups and args_final and boxviews and update activity.report_subtasks_list
    
    p.NOWNOW = { -- in work subtasks for replace on 20181205
    	{ "20190101", "20190101", "todo", "Rical", "S190101cTD", "Ask a central Template:Dropbox for all mediawikis users you and me. on 20190101", },
    	{ "20181225", "20181226", "todo", "Rical", "S181227trb", "treebranches -- For each sought. Replace known. Later on 201811207", },
    	{ "20181224", "20181224", "NOW", "Rical", "S181224rtn", "ModuleCentralizer replace template's display to their names in fr.wikipedia.org and fr.wikisouce.org", },
    --	S181224rtn : a similar comportment suggest a change in MW"
    --	S181224rtn : do not happened before the MediaWiki version "1.33.0-wmf.9 (02196d2)"
    	{ "20181224", "20181224", "NOW", "Rical", "S181224ust", "Module:Centralizer update subtasks list", },
    	{ "20181222", "20181225", "todo", "Rical", "S181222CrC", "Module:CentralSchool: finish reciprocal adaptation with Module:Centralizer", },
    	{ "20181222", "20181222", "done", "Rical", "S181222SCi", "For 'Begin' Simplify function Central.init(frame, ...) using function p.init_central_module()" },
    	{ "20181221", "20181222", "todo", "Rical", "S181221oTc", 'others: ["Tactic"] = "canbenil;nevererror" ', },
    	{ "20181220", "20181221", "NOW", "Rical", "S181220oso", "select only sub-functions in the right order in function p.init_central_module()", },
    	{ "20181220", "20181220", "NOW", "Rical", "S181220ust", "Module:Centralizer update subtasks list", },
    	{ "20181205", "20181206", "done", "Rical", "S181205mgT", "function modes.get_args_datas_tests(t) Tactic all in one for modes args datas no known_arguments no origins old" },
    }
    
    p.teststests = "FAMLTVQDR"
    
    p.version = { -- Modules dependencies. Dependencias del módulo. Dépendances du module.
    	["versionName"]			= "Centralizer",
    	["versionNumber"]		= "1.0.0(181227T22:44)",
    	["versionDate"]			=   "2018-12-27T22:44:00", -- UTC version structure MWMW
    	["mainDescription"]		= "Begin to use",
    	["functionDescription"] = "first functional support",
    	["taskDescription"]		= "enough advanced to use in CentralSchool OK",
    	--	p_template_drop_box_name		= 'Cuadro desplegable', -- Equivalent templates exist in other wikis
    	["sought"]				= "Centralizer;Centralizer/I18N;Mathroman;TestRequire", -- Sought module and submodules versions
    	["known"]				= "Centralizer;Central-s-fr;Central-14 * Centralizer/I18N;Central/i18n * Mathroman22;Mathroman34", -- Known module and submodules versions
    	["treebranches"] = { -- For each sought. Replace known. Later on 201811207
    		{ "Centralizer", "Central-s-fr", "Central-2017" }, -- upper
    		{ "Centralizer/I18N", "Central-s-fr", "Central-2018" }, -- median
    		{ "Mathroman22", "Mathroman34" }, -- lower
    	}
    }
    Central.Central_version_name = Central.version.versionName
    p.ModuleNS = mw.site.namespaces.Module.name .. ":" -- translate Module: in other languages
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ----------------- - - - - -----------------------------
    --	Development Tactic on 20180905
    --	A central module could need a translation service and a versioning service to enhance its functions or its stability without disturbing the preview normal use.
    --	A main module can define its sought sub-modules versions names and its known sub-modules versions names.
    --	The Library:versions installs other libraries, supports versions, binds modules, libraries and i18n translations.
    --	A central module and its translations can inpedendently change. Its p.version{} identifications change also.
    --	For this goal a module contains at least one i18n tranlations table. Its /I18N sub-modules contains translations in several languages.
    --	Central Libraries, like modules, contain their own p.version{} identifications and i18n translations in Module:Library/library_name/I18N.
    --	The adaptation to any number of languages is automatic.
    --	The highest level is the main module. The lowest level is the libraries level.
    --
    --	Any module or library can contain i18n tables.
    --	i18n tables are mixed from the lowest to the highest level, to permit at upper module to adapt the meaning of string to a new use.
    --	Each library is independent of other ones and they can be mixed in any order.
    --	To avoid conflict of translations keys between libraries, all translations keys names start with the library name.
    --
    --	Tactic for modules, arguments, options and default values 20180908.
    --	In all cases the main module protects all original tables, including for itself.
    --	Permit modules without versions for many existing modules. Modules are also simply tables for data-modules or PageData in Json.
    --	3 central functions bind sub-modules, translations and arguments in 3 new tables.
    --	All arguments can have default values, like "prop_default" for "prop" to use it in case of tests or missing value.
    --	Do not disturb actual modules, libraries, translations ; only add new structures and most explicit tables of args, i18n, modules, libraries...
    --
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	The central system permits to convert any module as central.
    --	The Lua part of the central modules support contains some libraries used by central modules.
    --	The Module:Centralizer installs central libraries (waiting stable Scribunto central repository).
    --	An object has a function object.new() to form several objects
    --	A library is unic and come from Scribunto.
    --	Unique declarations of libraries and objects:
    --	To split ModuleCentral-s-fr delete activity. on 2018-01-10T09:35:00
    activity = {}			-- Library:activity from 20170611 Search story in Central modules.txt
    --	args = {}				-- Object:args from 20180106 form known arguments to import, complete from datas and finalize
    datas = {}				-- Library:datas from ?
    drop_box = {}			-- Object:drop_box from 20170615 rename viewers.drop_box.form() in viewers.drop_box on 20170615
    events = {}				-- Object:events from ? "events"
    langs = {}				-- Library:langs from i18n tables on 20130118, br-de-en-es-fr-vi from 20170217,
    lua_table = {}			-- Library:lua_table from lua_table.level_list() from 20170808
    mathroman = {}			-- Library:mathroman from ?
    modes = {}				-- Library:modes from arguments support on 20130125 in Module:Author, 20130312 in Module:ControlArgs
    central_library = {}	-- Object:central_library from versions.central_library on 20171211 in Module:Centralizer
    tableview = {}			-- Object:tableview from 20170208
    tab_view = {}			-- Object:tab_view from 20170208
    tracker = {}			-- Object:tracker from 20170628
    versions = {}			-- Library:versions from versioning on 20170316. From versions support in Module:Author3 on 20150225.
    viewers = {}			-- Library:viewers from 20170209
    -- versions.args = args -- Object:args from 20180106 todo
    --	Records are in function versions.setup_central_libraries(bindable_libraries, opt) -- Install central bindable libraries in package.loaded
    
    Central.infos = { -- from 20171218
    	["libname"] = "Central", typ = "Module",
    	libdesc = "The main central module install central libraries and bind the main and sub modules.",
    	versfirst = "130312.12:00", verslast = "180626:08:54",
    	versionName = "Central-s-fr", versionNumber = "180626:08:54", versionDate = "2018-03-13 10:31", -- UTC
    	versions = {
    		{ ["libname"] = "Central", verstime = "2018-01-06T08:30:10", versid = "180106.0830", phabtask = "T135845", subtask = "S180106arg", change = "new: args.infos todo later", },
    		{ ["libname"] = "Central", verstime = "2017-12-25T23:10:10", versid = "171225.2310", phabtask = "T135845", subtask = "S170901mMW", change = "MWversions_report()", },
    		{ ["libname"] = "Central", verstime = "2013-03-12T12:00:00", versid = "130312.1200", phabtask = "T135845", subtask = "S000000new", change = "new: manage translations, arguments for central modules", },
    	}, -- infos.version
    } -- infos
    
    --	See: Short story of development
    --	Initial history : On [https://test2.wikipedia.org/w/index.php?title=Module:ControlArgs&oldid=48210 2013-03-12],
    --	Initial history : the Module:ControlArgs groups complex translations and arguments support for other modules to become <b>centralisable</b>.
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    --	The Library:activity supports Lua-coders sub-tasks and inter-wikis central modules.
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    activity.infos = { -- from 20171218
    	["libname"] = "activity", typ = "Library",
    	libdesc = "The Library:activity supports Lua-coders sub-tasks and inter-wikis central modules.",
    	versfirst = "171218.12:00", verslast = "180626:08:54",
    
    		versionName = "Central-s-fr", versionNumber = "1.0.0(180624T09:12)", versionDate = "2018-06-24T09:12:00",
    	-- UTC version structure :		  main.fonction.task(yymmdd:hh:mm)
    	mainDescription = "Begin to use", functionDescription = "first functional support", taskDescription = "T198107 Begin to use central modules",
    	versions = {
    		{ ["libname"] = "activity", verstime = "2018-06-24T09:12:00", versid = "1.0.0(180624T09:12)",
    			phabtask = "T198107", subtask = "S180625btu", change = "S171201xyz", },
    		{ ["libname"] = "activity", verstime = "2017-12-14T20:13:27", versid = "171214.13:27",
    			phabtask = "T000000", subtask = "S171201xyz", change = "S171201xyz", },
    		{ ["libname"] = "activity", verstime = "2017-12-12T00:00:00", versid = "171212.00:00",
    			phabtask = "T000000", subtask = "S171201xyz", change = "S171201xyz", },
    	}, -- infos.version
    } -- infos asterisk
    
    activity.describ_version = "The Library:activity supports Lua-coders sub-tasks and inter-wikis central modules."
    activity.libname = "activity"
    activity.name = "activity"
    activity.infos.libname = "activity"
    activity.infos.name = "activity"
    activity.previous_versions = {
    	{ ["libname"] = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", },
    	{ ["libname"] = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", },
    	{ ["libname"] = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", },
    }
    
    central_library.infos = { -- from 20171218
    	["libname"] = "central_library", typ = "Object",
    	libdesc = "The Object:central_library, in the Library:versions, begin to form libraries and their properties.",
    	versions = {
    		{ ["libname"] = "central_library", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "central_library", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "central_library", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    events.infos = { -- from 20171218
    	["libname"] = "events", typ = "Library",
    	libdesc = "The Library:events form events like erros, warnings and categories.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    langs.infos = { -- from 20171218
    	["libname"] = "langs", typ = "Library",
    	libdesc = "The Library:lua_table i18n translates: arguments names, sentencies, error messages, catégories...",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    lua_table.infos = { -- from 20171218
    	["libname"] = "lua_table", typ = "Library",
    	libdesc = "The Library:lua_table enhances previous table library for counts and structure. It also converts to list or to rough_view.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    mathroman.infos = { -- from 20130312
    	["libname"] = "mathroman", typ = "Library",
    	libdesc = "The Library:mathroman converts roman to digital numbers and reverse. It also detects errors.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    modes.infos = { -- from 20171218
    	["libname"] = "modes", typ = "Library",
    	libdesc = "The Library:modes support modes and their options, like p.read(frame).",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    tableview.infos = { -- from 20171218
    	["libname"] = "tableview", typ = "Object",
    	libdesc = "The Object:tableview and tab_view, in the Library:viewers, formats tables in lines and columns.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    versions.infos = { -- from 20130312
    	["libname"] = "versions", typ = "Library",
    	libdesc = "The Library:versions installs central libraries, modules and translations. Also support versions management.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "versions", verstime = "2017-12-14T20:13:27", versid = "171221.0743", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "versions", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "versions", verstime = "2017-12-14T20:13:27", versid = "130312.1200", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    viewers.infos = { -- from 20130312
    	["libname"] = "viewers", typ = "Library",
    	libdesc = "The Library:viewers can formats texts to document in some languages.",
    	versfirst = "130312.12:00", verslast = "171221.07:43",
    	versions = {
    		{ ["libname"] = "viewers", verstime = "2017-12-14T20:13:27", versid = "171221.0743", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "viewers", verstime = "2017-12-13T10:10:00", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", },
    		{ ["libname"] = "viewers", verstime = "2013-03-12T20:12:00", versid = "130312.1200", phabtask = "T000000", subtask = "S000000abc", },
    	}, -- infos.version
    } -- infos
    
    modes.central_libraries = { -- New libraries to record in package.loaded[]
    	{ "activity",		"The Library:activity supports Lua-coders sub-tasks and inter-wikis central modules.", },
    	{ "datas",			"The Library:datas gets datas from the Wikibase.", },
    	{ "events",			"The Library:events form events like erros, warnings and categories.", },
    	{ "langs",			"The Library:langs supports i18n translations.", },
    	{ "lua_table",		"The Library:lua_table enhances the native Lua table library, to avoid ambiguities.", },
    	{ "mathroman",		"The Library:mathroman converts roman numbers and detect errors. It is here as an example of very small central library.", },
    	{ "modes",			"The Library:modes supports the modes and their options, like p.read(frame).", },
    	{ "tables",			"The Library:tables formats rows of tables in html. Sortable tables with buttons are forbiden in MediaWiki.", },
    	{ "versions",		"The Library:versions installs all central libraries, modules, their i18n translations and versions.", },
    	{ "viewers",		"The Library:viewer translates and formats strings to document texts and table views.", },
    	-- Objects have a function object.new() to form several objects.
    	{ "drop_box",		"The Object:drop_box, in the Library:viewers, formats drop-boxes. It needs a local template installed with Centralizer.", },
    	{ "central_library","The Object:central_library, in the Library:versions, formats the basis of libraries and their properties.", },
    	{ "tableview",		"The Object:tableview, in the Library:viewers, formats some viewers for tables, in lines and columns.", },
    	{ "tracker",		"The Object:tracker, in the Library:activity, formats parametrables tracks to help to debug the code.", },
    }
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Object:tracker implements parametrable track objects to debug the Lua code.
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	tracker = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    tracker.obj = { -- Options from: default, init and use steps. To mix in obj.*
    	["level"] = 1, -- level of detail of each track line
    	["name"] = "TRACK", -- name of the track
    	["where"] = "IN TRACK", -- name of the track
    	["limit"] = 2, -- Limit of track more or less details
    	["form"] = "\n* %1 in=<b>%2</b>", -- begin or each track line
    	["more"] = ", arg%1=<b>%2</b>", -- add to the previous text
    	["t"] = "", -- resulting text with all track lines
    	["groupname"] = "*.+!;-/", -- to display all grouped events with a same name
    	["add"] = function() return "" end, -- for tracker.initadd(opt)
    	["trk"] = function() return "" end, -- for tracker.initrack(opt)
    }
    
    function tracker.new(opt) -- Initializes a track list.
    	-- The groupid option can select which track select and add in the groupname group.
    	if (type(opt) ~= "table") then opt = {} end
    	opt.level = opt.level or 1 -- level of detail of each track line
    	opt.name = opt.name or "TRACK" -- name of the track
    	opt.limit = opt.limit or 1 -- limit of detailed lines
    	opt.form = opt.form or "\n* %1 in=<b>%2</b>" -- begin or each track line
    	opt.more = opt.more or ", arg%1=<b>%2</b>" -- add to the previous text
    	opt.t = opt.t or "" -- resulting text with all track lines
    	opt.trackon = 1 -- track on or not	(= 0) for one track object.
    	opt.groupid = opt.groupid -- to select tracks in a group
    	opt.groupname = opt.groupname -- to display all grouped events with a same name
    	return opt
    end -- function tracker.new(opt)
    
    function tracker.add(opt, level, IN, ... ) -- Adds, or not, a new track line to the track list.
    	local t = "" -- function tracker:add(self, ...) -- table.func = function ( self, var-list ) block end
    	if (type(opt) ~= "table") then return t end
    	if opt.trackon == 0 then return t end
    	if viewers.is_in_sp(opt.groupid, IN) then
    		opt.grouptrack = opt.groupname or opt.groupid
    	end
    	if opt.grouptrack then t = t .. "<b>" .. opt.grouptrack .. ":</b> " end
    	if (type(level) == "number") and (level > opt.limit) then return t end
    	local vals, vals_t = { ... }, ""
    	local vals_t = "\n* <b>" .. opt.name .. "</b>: " .. viewers.ta("in", IN)
    	if (type(vals[1]) == "table") then vals = vals[1] end
    	for k, var in pairs( vals ) do
    		if var ~= nil then vals_t = vals_t .. viewers.ta(k, tostring(var) ) end
    	end
    	if where == opt.name then -- List the tracker options
    		opt.values = viewers.ta("name", opt.name) -- .. viewers.ta("level", opt.level)
    		.. viewers.ta("limit", opt.limit) -- .. viewers.ta("form", opt.form) .. viewers.ta("more", opt.more)
    		.. viewers.ta("opt_N", lua_table.count_all(opt) ) .. viewers.ta("trackon", opt.trackon) -- .. viewers.ta("t", opt.t)
    		return opt.t .. vals_t .. opt.values .. "<br>"
    	end
    	opt.t = opt.t .. vals_t -- add this track to the list of track lines
    	t = t .. "<br>"
    	return t -- report local track line
    end -- tracker.ARGS.t
    
    function tracker.initadd_old(opt) -- Initialize a track
    	local obj = mw.clone(tracker.obj)
    	if (type(opt) ~= "table") then opt = {} end
    	for key, val in pairs(opt) do
    		if (type(key) == "string") and (val ~= nil) then obj[key] = val end
    	end
    	obj = tracker.new(obj)
    	opt.add = tracker.add
    	_G[obj.name] = obj
    	return obj
    end -- function tracker.initadd(opt)
    
    function tracker.initadd(opt) -- Initialize a track
    	if (type(opt) ~= "table") then opt = {} end
    	if (type(opt) == "table") and (type(opt.add) == "function") and (opt.name == _G[opt.name]) then
    	--	_G[opt.name] = opt -- Reuse already initialized tracker for its continuity.
    	--	return opt
    	end
    	opt = tracker.new(opt)
    	opt.add = tracker.add
    	_G[opt.name] = opt
    	return opt
    end -- ARGS = tracker.initadd({ ["name"] = "ARGS", limit = 2, }) -- Initialize a track
    
    -- See: "Function as a method in a table" in Lua_reference_manual#Function_declaration_statements
    function tracker.initrack(opt) -- Initialize one new tracker and its track lines.
    	if (type(opt) ~= "table") then opt = { ["name"] = "DEFAULTRACK", ["limit"] = 2 } end
    	if (type(opt.name) ~= "string") then opt.name = "DEFAULTRACK" end
    	if (type(opt.limit) ~= "number") then opt.limit = 2 end
    	local optrk = mw.clone(opt) -- New initial tracker object
    	function optrk:trk(self, limit, name, vals) -- see S171015trk
    		return tracker.add(self, limit, name, vals) or "\n* optrk:trk. "
    	end
    	_G[optrk.name] = optrk
    	return optrk
    end -- ARGS = tracker.initrack({ ["name"] = "ARGS", limit = 2, }) -- Initialize a track
    
    function tracker.init_trakers() -- Initialize some trakers. To run in Central.init()
    	ARGS = tracker.initadd({ ["name"] = "ARGS", ["limit"] = 2 }) -- Initialize a track
    	CNT = tracker.initadd({ ["name"] = "CNT", ["limit"] = 2 }) -- Initialize a track
    	DAT = tracker.initadd({ ["name"] = "DAT", ["limit"] = 2 }) -- Initialize a track
    	return "\n* ARGS.t=" .. tostring(ARGS.t) .. ", CNT.t=" .. tostring(CNT.t)
    end
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:activity begins to support other tests wikis. It translates tests pages names for these wikis.
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    activity.i18n = {} -- Translations for activity library
    activity.i18n.br = { -- br = Breton = Brezhoneg
    --	Pour traduire, les langues de référence sont l'anglais et le français.
    --	Pour traduire, ne traduisez pas des parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.",
    	activity_central_library_description		= "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Description des bibliothèques centrales",
    	activity_translate_string_guide				= "Pour traduire, ne traduisez pas les parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Module:Centralizer",
    	activity_Library_translate_I18N				= "Module:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Surveiller les sous-tâches. Voir "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Surveiller les versions de MediaWiki, les 3 derniers mois.", -- fr
    	activity_central_count_admins_active_users	= "Ce site, fr.wikisource.org, compte <b>%1</b> administrateurs pour <b>%2</b> utilisateurs actifs.",
    	activity_support_central_modules_title		= "activity.begin_central_modules_support() Soutenir les premières utilisations des Central modules.",
    	activity_support_central_modules_headers	= "Project; Language; Admins; Assets; Lien Modèle; Lien Module; Lien Tests; Début; Utilisé depuis; Codeur; OK", -- fr
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() États des tâches connexes dans Phabricator",
    	activity_phabricator_tasks_headers			= "Importance, modifiée le; Tâche; Etat; Titre",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Lister les fonctions actuelles.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Signaler les déséquilibres des débuts et des fins de gras dans le code.",
    	activity_space_name_module					= "Modulenn", -- br
    	activity_space_name_template				= "Patrom",
    	activity_space_name_user					= "Implijer", -- Implijer:VIGNERON - Wikimammenn
    	activity_test_page_user						= "Documentation", -- br Documentation, Dokumentation, D
    } -- activity.i18n.br
    activity.i18n.de = { -- de = German = Deutsche
    --	Modul:Central-s-de/Doku					{{#invoke:Central-s-de|read}}	de = German = Deutsch
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "Das Library:activity Das Ding unterstützt das Management von phaborator-Aufgaben, von inter-Lua-Coder-Unteraufgaben und von interwikis-Zentralmodulen.",
    	activity_central_library_description		= "Das Library:activity Das Ding unterstützt das Management von phaborator-Aufgaben, von inter-Lua-Coder-Unteraufgaben und von interwikis-Zentralmodulen.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Zentrale Bibliotheksbeschreibungen",
    	activity_Module_Central_central_version		= "Modul:Central",
    	activity_Library_translate_I18N				= "Modul:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_support_central_modules_title		= "<b>activity.begin_central_modules_support()</b> Unterstützen Sie die ersten Anwendungen von Central-Modulen.",
    	activity_support_central_modules_headers	= "Projekt; Speicher; Admins; Vermögenswerte; Modellverbindung; Modulverbindung; LinkTests; beginnen; Gebraucht seit; Encoder; Ok", -- fr
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Überwachen Sie den aktuellen Stand der subtasks. See "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Überwachen von MediaWiki-Versionen, letzten 3 Monate.", -- de
    	activity_central_count_admins_active_users	= "Für diese Seite, br.wikisource.org, Konto <b>%1</b> Direktoren für <b>%2</b> aktive Nutzer.",
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() Zuständige Aufgaben in Phabricator",
    	activity_phabricator_tasks_headers			= "Wichtigkeit; modifiziert die; Aufgabe; Status; Titel",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Listen Sie die aktuellen Funktionen auf.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Melden Sie Ungleichgewichte von Anfang und Ende von Fett im Code.",
    	activity_space_name_module					= "Modul", -- de
    	activity_space_name_template				= "Vorlage",
    	activity_space_name_user					= "Benutzer",
    	activity_test_page_user						= "Dokumentation",
    } -- activity.i18n.de
    activity.i18n.en = { -- en = English = English
    --	To translate, referral languages are English and French.
    --	To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "The Library:activity supports the management of phabricator tasks, of inter Lua-coders sub-tasks, and of interwikis central modules.",
    	activity_central_library_description		= "The Library:activity supports the management of phabricator tasks, of inter Lua-coders sub-tasks, and of interwikis central modules.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Central libraries descriptions",
    	activity_translate_string_guide				= "To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Module:Centralizer",
    	activity_Library_translate_I18N				= "Module:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Monitor the current subtasks. See "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Monitor MediaWiki versions, last 3 months.", -- en
    	activity_central_count_admins_active_users	= "This site, br.wikisource.org, count <b>%1</b> administrators for <b>%2</b> active users.",
    	activity_support_central_modules_title		= "<b>activity.begin_central_modules_support()</b> Support the first uses of Central modules.",
    	activity_support_central_modules_headers	= "Project; Save; Admins; assets; Model link; Module link; Link Tests; start; Used since; encoder; OK", -- fr
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() States of related tasks in Phabricator",
    	activity_phabricator_tasks_headers			= "Importance; modified on; Task; Status; Title",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) List actual functions.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Report imbalances of beginnings and ends of bold in code.",
    	activity_space_name_module					= "Module", -- en
    	activity_space_name_template				= "Template",
    	activity_space_name_user					= "User",
    	activity_test_page_user						= "Documentation",
    } -- activity.i18n.en
    activity.i18n.es = { -- es = Spanish = español
    --	To translate, referral languages are English and French.
    --	To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "La Library:activity soporta la gestión de tareas de phabricator, de sub-tareas inter Lua-coders, y de módulos interwikis centrales.",
    	activity_central_library_description		= "La Library:activity soporta la gestión de tareas de phabricator, de sub-tareas inter Lua-coders, y de módulos interwikis centrales.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Descripciones de bibliotecas centrales",
    	activity_translate_string_guide				= "Para traducir, no traducir partes como estas: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Módulo:Central",
    	activity_Library_translate_I18N				= "Módulo:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_support_central_modules_title		= "activity.begin_central_modules_support() Apoye los primeros usos de los módulos centrales.",
    	activity_support_central_modules_headers	= "proyecto; Guarde; Administradores; activos; Enlace modelo; Enlace del módulo; Enlace Tests; Inicio; Usado desde entonces; codificador; bueno", -- fr
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Monitorear las subtareas. See "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Monitorear las versiones de MediaWiki, últimos 3 meses.", -- es
    	activity_central_count_admins_active_users	= "Este sitio, br.wikisource.org, cuenta <b>%1</b> administradores para <b>%2</b> usuarios activos.",
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() Tareas relacionadas con los estados en Phabricator",
    	activity_phabricator_tasks_headers			= "Importancia; modificado; Tarea; Estado; Título",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Listar funciones actuales.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Informe los desequilibrios de los comienzos y los extremos de negrita en el código.",
    	activity_space_name_module					= "Módulo", -- es
    	activity_space_name_template				= "Modelo",
    	activity_space_name_user					= "Usuario",
    	activity_test_page_user						= "Documentación", -- br Documentation, Dokumentation, 
    } -- activity.i18n.es
    activity.i18n.fr = { -- fr = French = Français
    --	Pour traduire, les langues de référence sont l'anglais et le français.
    --	Pour traduire, ne traduisez pas des parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.",
    	activity_central_library_description		= "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Description des bibliothèques centrales",
    	activity_translate_string_guide				= "Pour traduire, ne traduisez pas les parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Module:Centralizer",
    	activity_Library_translate_I18N				= "Module:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Surveiller les sous-tâches. Voir "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Surveiller les versions de MediaWiki, les 3 derniers mois.", -- fr
    	activity_central_count_admins_active_users	= "Ce site, fr.wikisource.org, compte <b>%1</b> administrateurs pour <b>%2</b> utilisateurs actifs.",
    	activity_support_central_modules_title		= "activity.begin_central_modules_support() Soutenir les premières utilisations des Central modules.",
    	activity_support_central_modules_headers	= "Project; Language; Admins; Assets; Lien Modèle; Lien Module; Lien Tests; Début; Utilisé depuis; Codeur; OK", -- fr
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() États des tâches connexes dans Phabricator",
    	activity_phabricator_tasks_headers			= "Importance, modifiée le; Tâche; Etat; Titre",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Lister les fonctions actuelles.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Signaler les déséquilibres des débuts et des fins de gras dans le code.",
    	activity_space_name_module					= "Module", -- fr
    	activity_space_name_template				= "Modèle",
    	activity_space_name_user					= "Utilisateur",
    	activity_test_page_user						= "Documentation", -- br Documentation, Dokumentation, 
    } -- activity.i18n.fr
    activity.i18n.hu = { -- hu = Hungarian = Magyar -- Il n'y a aucun module dans l'espace module Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}}
    --	To translate, referral languages are English and French.
    --	To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_description						= "A Library:activity a phabricator feladatok kezelését, az inter Lua-kódoló al-feladatok és az interwikis központi modulok kezelését.",
    	activity_central_library_description		= "A Library:activity a phabricator feladatok kezelését, az inter Lua-kódoló al-feladatok és az interwikis központi modulok kezelését.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Központi könyvtárak leírása",
    	activity_translate_string_guide				= "Töltsd le a szöveget, és nyomd le a partit a cellák között: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Modul:Central",
    	activity_Library_translate_I18N				= "Modul:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Kíséri részfeladatok. See "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Monitor MediaWiki verziók, az elmúlt 3 hónapban.", -- hu
    	activity_central_count_admins_active_users	= "Ez az oldal, br.wikisource.org, fiók <b>%1</b> rendszergazdák és <b>%2</b> felhasználók aktív.",
    	activity_support_central_modules_title		= "activity.begin_central_modules_support() Támogassa a központi modulok első használatát.",
    	activity_support_central_modules_headers	= "Project mentése; Adminok; eszközöket; Modell link; Modul kapcsolat; Link Tests; indul el; Óta használják; jeladó; rendben", -- fr
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() Államokkal kapcsolatos feladatok a Phabricator",
    	activity_phabricator_tasks_headers			= "Fontosság; módosította; a Feladat; Állapot; Cím",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Listázza az aktuális funkciókat.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Jelentés a merész kódok kezdetének és végének egyenlőtlenségeiről.",
    	activity_space_name_module					= "Modul", -- hu
    	activity_space_name_template				= "Sablon",
    	activity_space_name_user					= "Dokumentáció", -- br Documentation, Dokumentation, 
    } -- activity.i18n.hu
    activity.i18n.vi = { -- vi = Vietnamese = Tiếng việt
    --	To translate, referral languages are English and French.
    --	To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	["docfunc"]									= "docfunc",
    	["docitem"]									= "docitem",
    	["dockey"]									= "dockey",
    	activity_central_library_description		= "Điều này Library:activity hỗ trợ việc quản lý các công việc để nhà phân tích, các nhiệm vụ phụ liên Lua-coders, và các mô-đun trung tâm liên thông.",
    	activity_display_central_libraries_title	= "activity.describe_central_libraries() Mô tả thư viện trung ương",
    	activity_translate_string_guide				= "Để dịch, không dịch các phần như thế này : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.",
    	activity_Module_Central_central_version		= "Mô đun:Central",
    	activity_Library_translate_I18N				= "Mô đun:Library/translate/I18N",
    	activity_Central_modules_reference_manual	= "Scribunto/Central modules reference manual",
    	activity_report_subtasks_title				= 'activity.central_subtasks_report(t) Xem việc phụ. See "NOW".',
    	activity_MW_Versions_report_title			= "<b>activity.MW_Versions_report()</b> Giám sát các phiên bản MediaWiki, 3 tháng gần đây.", -- vi
    	activity_central_count_admins_active_users	= "Trang web này, Br.wikisource.org có <b>%1</b> quản trị viên cho <b>%2</b> người dùng hoạt động.",
    	activity_support_central_modules_title		= "activity.begin_central_modules_support() Hỗ trợ sử dụng đầu tiên để mô-đun Trung tâm.",
    	activity_support_central_modules_headers	= "dự án; lưu; Quản trị viên; tài sản; Liên kết mô hình; Liên kết mô-đun; Liên kết Tests; bắt đầu; Được sử dụng kể từ; encoder; tốt",
    	activity_phabricator_tasks_title			= "activity.phabricator_tasks_report() Các nhiệm vụ liên quan đến Nhà nước trong Phabricator",
    	activity_phabricator_tasks_headers			= "Tầm quan trọng; sửa đổi; nhiệm vụ; tình trạng; tiêu đề",
    	activity_central_functions_report_title		= "activity.central_functions_report(t) Liệt kê các chức năng hiện tại.",
    	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Báo cáo sự mất cân đối của các khởi đầu và kết thúc bằng chữ in đậm.",
    	activity_space_name_module					= "Mô-đun", -- vi
    	activity_space_name_template				= "Mẫu",
    	activity_space_name_user					= "tài liệu", -- br Documentation, Dokumentation, 
    } -- activity.i18n.vi
    
    function activity.describe_central_libraries(t) -- Central libraries descriptions, activity_display_central_libraries_title
    	local memo = viewers.save_configs("activity.describe_central_libraries") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>activity.describe_central_libraries()</b> Monitor central libraries descriptions." -- t or
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = modes.central_libraries, -- List of subtasks to monitor.
    		title_memo = "activity_display_central_libraries_title", -- "activity.describe_central_libraries() Monitor central libraries descriptions",
    	--	headers = "activity_monitor_central_libraries_headers", -- " Name; Description of the library ",
    		headers = " Name; Description of the library ",
    		headers_class = "wikitable alternative center sortable",
    		rowGroup = {},
    	--	track_on == "details",
    	}
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "activity.describe_central_libraries") -- Restore global configurations after eventual changes.
    	return t
    end
    
    activity.wikis_names = { -- see mw:Extension:WikimediaIncubator
    	["b"] = "wikibooks",		["cm"] = "commons",		["meta"] = "meta",		["mw"] = "MediaWiki",		["d"] = "wikidata",
    	["n"] = "wikinews",			["p"] = "wiki",			["q"] = "wikiquote",	["s"] = "wikisource",
    	["species"] = "species",	["t"] = "wiktionary",	["test"] = "test",		["test2"] = "test2",
    	["v"] = "wikiversity",		["w"] = "wikipedia",	["wm"] = "wikimedia",	["y"] = "wikivoyage",
    } -- activity.wikis_names
    -- see https://fr.wikisource.org/wiki/Spécial:Interwiki
    -- see https://www.MediaWiki.org/wiki/Special:Interwiki
    -- see https://fr.wikisource.org/wiki/Sp%C3%A9cial:Matrice_des_sites
    activity.kiwis_names = {
    	["commons"] = "cm",			["MediaWiki"] = "mw",	["meta"] = "meta",		["species"] = "species",		["wikidata"] = "d",
    	["test"] = "test",			["test2"] = "test2",	["wiki"] = "p",			["wikibooks"] = "b",
    	["wikimedia"] = "wm",		["wikinews"] = "n",		["wikipedia"] = "w",	["wikiquote"] = "q",
    	["wikisource"] = "s",		["wikiversity"] = "v",	["wikivoyage"] = "y",	["wiktionary"] = "t",
    }
    
    activity.proto_version = "Centralizer-s-fr"
    activity.local_version = "Centralizer-s-fr" -- default Patrom:Central
    
    activity.coder_lang_module = { -- List to report of Module:Centralizer for 'Begin to use' 7 central modules, 7 coders, 7 projets, 7 langs to get.
    	--	br.wikisource.org/wiki/Modulenn:Centralizer-s-br/doc			{{#invoke:Centralizer-s-br|read}}	fr = Breton = Breton = Breitz
    	{ ["lang"] = "br",	["project"] = "wikisource", ["module_vers"] = "Centralizer",	["coder"] = "[[:s:br:Implijer:VIGNERON|VIGNERON]]", ["ok"] = "ok",
    	["project_short"] = "s",	["tests_lang"] = "Centralizer/Documentation",		["template"] = "Patrom",	["template_vers"] = "Centralizer",
    	["module"] = "Modulenn",	["admins"] = "16",	["assets"]	= "236",	["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	--
    	--	de.wikisource.org/wiki/Modul:Centralizer/Doku				{{#invoke:Centralizer-s-de|read}}	de = German = Deutsch
    	{ ["lang"] = "de",	["project"] = "wikisource", ["module_vers"] = "Centralizer",	["coder"] = "[[:s:de:Benutzer:DerFussi|DerFussi]]", ["ok"] = "...",
    	["project_short"] = "s",	["tests_lang"] = "Centralizer/Dokumentation",		["template"] = "Vorlage",	["template_vers"] = "Centralizer",
    	["module"] = "Modul",		["admins"] = "16",	["assets"]	= "236",	["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	-- sur la page de projet  je ne vois pas qui d'autre :Hexasoft Tejgad Arkanosis Xfigpower Zebulon84 ;Hlm Z.; Od1n TomT0m Archimëa 
    	-- sur la page de projet  je ne vois pas qui d'autre : {{u'|Hexasoft}}, {{u'|Tejgad}}, {{u'|Arkanosis}}, {{u'|Xfigpower}}, {{u'|Zebulon84}},, {{u'|Hlm Z.}}. 
    	-- Je rajoute au hasard {{u'|Od1n}}, {{u'|TomT0m}} et... -- [[Utilisateur:Archimëa|Archimëa]] <
    	--	en.wikipedia.org/wiki/Module:Centralizer/Documentation		{{#invoke:Centralizer-w-en|read}}	en = English = English
    	{ ["lang"] = "en",	["project"] = "wikipedia",	["module_vers"] = "Centralizer",	["coder"] = "[[:w:en:User:Toohool|Toohool]]",	["ok"] = "...",
    	["project_short"] = "w",	["tests_lang"] = "Centralizer/Documentation",		["template"] = "Template",	["template_vers"] = "Centralizer",
    	["module"] = "Module",		["admins"] = "0",	["assets"]	= "0",		["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	--
    	--	es.wikipedia.org/wiki/Módulo:Centralizers/Documentación		{{#invoke:Centralizer-w-es|read}}	es = Spanish = español
    	{ ["lang"] = "es",	["project"] = "wikipedia",	["module_vers"] = "Centralizer",	["coder"] = "[[:w:es:Usuario:Juan_Mayordomo|Juan_Mayordomo]]",	["ok"] = "...",
    	["project_short"] = "w",	["tests_lang"] = "Centralizer/Documentación",		["template"] = "Plantilla", ["template_vers"] = "Centralizer",
    	["module"] = "Módulo",		["admins"] = "16",	["assets"]	= "236",	["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	--
    	--	es.wikisource.org/wiki/Módulo:Centralizer-s-es/Documentación	{{#invoke:Centralizer-s-es|read}}	es = Spanish = española
    	{ ["lang"] = "es",	["project"] = "wikisource", ["module_vers"] = "Centralizer",	["coder"] = "[[:s:es:Usuario:Alex brollo|Alex brollo]]", ["ok"] = "...", -- Usuario:Juan_Mayordomo
    	["project_short"] = "s",	["tests_lang"] = "Centralizer/Documentación",		["template"] = "Plantilla", ["template_vers"] = "Centralizer",
    	["module"] = "Módulo",	["admins"] = "22",	["assets"]	= "234",		["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	--
    --  Module br Modulenn, de Modul, en Module, es Módulo, fr Module, hu Modul, vi Mô-đun,
    --  Template br Patrom, de Vorlage, en Template, es Modelo, fr Modèle, hu Modell, vi Mẫu,
    --  User br Implijer, de Benutzer, en User, es Usuario, fr Utilisateur, hu Használó, vi người sử dụng,
    --  Docum br Documentation, de Dokumentation, en Documentation, es Documentación, fr Documentation, hu Dokumentáció, vi tài liệu,
    	--	fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation	{{#invoke:Centralizer-s-fr|read}}	fr = French = Français
    	{ ["lang"] = "fr",	["project"] = "wikisource", ["module_vers"] = "Centralizer",	["coder"] = "[[:s:fr:Utilisateur:Rical|Rical]]",	["ok"] = "ok",
    	["project_short"] = "s",	["tests_lang"] = "Centralizer/Documentation",		["template"] = "Modèle",	["template_vers"] = "Centralizer",
    	["module"] = "Module",	["admins"] = "16",	["assets"]	= "204",		["beginon"] = "20180719",	["usedfrom"]	= "20180719 ?", },
    	--
    	--	fr.wikisource.org/wiki/Module:Auteur2Tpt/Tests	{{#invoke:Auteur2Tpt|read}} fr = French = Français
    	{ ["lang"] = "fr",	["project"] = "wikisource", ["module_vers"] = "Auteur2Tpt", ["coder"] = "[[:s:fr:Utilisateur:Rical|Rical]]",	["ok"] = "ok",
    	["project_short"] = "s",	["tests_lang"] = "Auteur2Tpt/Documentation",		["template"] = "Modèle",	["template_vers"] = "Auteur2Tpt",
    	["module"] = "Module",	["admins"] = "16",	["assets"]	= "204",		["beginon"] = "20180719",	["usedfrom"]	= "20180719 ?", },
    	--
    	--	hu.wikipedia.org/wiki/Modul:Centralizer-w-hu/doc				{{#invoke:Centralizer-w-hu|read}}	hu = Hungarian = Magyar
    	{ ["lang"] = "hu",	["project"] = "wikipedia",	["module_vers"] = "Centralizer",	["coder"] = "[[:w:hu:Szerkesztő:Tacsipacsi|Tacsipacsi]]",	["ok"] = "...",
    	["project_short"] = "w",	["tests_lang"] = "Centralizer/Dokumentáció",		["template"] = "Sablon",	["template_vers"] = "Centralizer",
    	["module"] = "Modul",		["admins"] = "3",	["assets"]	= "77",		["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	--
    	--	vi.wikipedia.org/wiki/Mô đun:Centralizer-w-vi/tài liệu			{{#invoke:Centralizer-w-vi|read}}	vi = Vietnamese = Tiếng Việt
    	{ ["lang"] = "vi",	["project"] = "wikipedia",	["module_vers"] = "Centralizer",	["coder"] = "[[:w:vi:Thành viên:mxn|mxn]]", ["ok"] = "...",
    	["project_short"] = "w",	["tests_lang"] = "Centralizer/vi tài liệu",		["template"] = "Bản mẫu",		["template_vers"] = "Centralizer",
    	["module"] = "Mô đun",	["admins"] = "3",	["assets"]	= "77",			["beginon"] = "20180719 ?", ["usedfrom"]	= "20180719 ?", },
    	-- Projects : MediaWikis wikidata wikipedia wikisource wikiquote meta test2
    	-- NOWNOW --  User = 2, Module = 828, Template = 10,
    	-- In all central wikis, install Dropbox template in Template:CentralDropbox and  sortable Table in template in Template:CentralTable
    --	{ "20170805", "20170807", "todo", "Rical", "S170702ALC", "Ask Lua-coders: Oliv0, Tpt, Od1n, Ayack, Kertraon, Julien1978, Thibaut120094", },
    --	{ "20170805", "20170807", "todo", "Rical", "S170702ALC", "Ask Lua-coders: Zolo, Zebulon84, Hlm Z., Cantons-de-l'Est, Daehan", },
    }
    
    function activity.begin_central_modules_support(t) -- Supports the first uses of Central modules.
    	local memo = viewers.save_configs("activity.begin_central_modules_support") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>activity.begin_central_modules_support()</b> Support the first uses of Central modules."
    	
    --	p.ModuleNS = mw.site.namespaces.Module.name .. ":" -- translate Module: in other languages ONLY FOR local site
    	t = t .. "\n* Local NameSpaces: " .. viewers.ta("Module=828", mw.site.namespaces.Module.name )
    	t = t .. viewers.ta("Template=10", mw.site.namespaces.Template.name )
    	t = t .. viewers.ta("User=2", mw.site.namespaces.User.name )
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = activity.coder_lang_module, -- CLM
    		rowGroup = {},
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			local mwuri = mw.uri.new()
    			local hostPort = mwuri.hostPort
    			local selector = mwuri.hostPort
    			case = activity.central_module_descriptor(case) -- Begin to adapt the main central module version to a case.
    			case.lang = tostring(case.lang)
    			case.project = tostring(case.project)
    			case.admins = tostring(case.admins)
    			case.assets = tostring(case.assets)
    			case.template = tostring(case.template)
    			case.template_vers = tostring(case.template_vers)
    			case.module = tostring(case.module)
    			case.module_vers = tostring(case.module_vers)
    			case.version = tostring(case.version)
    			case.page_template = case.template .. ":" .. case.template_vers
    			case.link_template = "[[" .. case.project_short .. ":" .. case.lang .. ":" .. case.page_template .. "|" .. case.page_template .. "]]"
    			case.page_module = case.module .. ":" .. case.module_vers
    			case.link_module = "[[" .. case.project_short .. ":" .. case.lang .. ":" .. case.page_module .. "|" .. case.page_module .. "]]"
    		--	case.page_doc = case.tests_lang
    		--	case.page_doc = case.module .. ":" .. case.tests_lang
    		--	case.link_doc = "[[" .. case.project_short .. ":" .. case.lang .. ":" .. case.module .. ":" .. case.tests_lang .. "|" .. case.tests_lang .. "]]"
    			case.link_Tests = "[[" .. case.project_short .. ":" .. case.lang .. ":" .. case.module .. ":" .. case.tests_lang .. "|" .. case.tests_lang .. "]]"
    			return { case.project, case.lang, case.admins, case.assets, case.link_template, case.link_module, case.link_Tests, case.beginon, case.usedfrom, case.coder, case.ok }
    		end,
    		title_memo = "activity_support_central_modules_title",
    										headers = "Project; Language; Admins; Assets; Lien Modèle; Lien Module; Lien Tests; Début; Utilisé depuis; Codeur; OK",
    	activity_support_central_modules_headers	= "Project; Language; Admins; Assets; Module version; Link to Tests; Start; Used since; Coder; OK", -- en
    	}
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	local langs, coders, projects, versions = {}, {}, {}, {}
    	for i, case in pairs(activity.coder_lang_module) do
    		if (type(case.lang) == "string") then table.insert(langs, case.lang) end
    		if (type(case.coder) == "string") then table.insert(coders, case.coder) end
    		if (type(case.project) == "string") then table.insert(projects, case.project) end
    		if (type(case.module_vers) == "string") then table.insert(versions, case.module_vers) end
    	end
    	local counter = lua_table.count_values(coders, "lang")
    	t = t .. "\n* Count begin coders: " .. viewers.ta("n", lua_table.level_count(counter) ) .. lua_table.rough_view(counter)
    	local counter = lua_table.count_values(langs, "lang")
    	t = t .. "\n* Count begin langs: " .. viewers.ta("n", lua_table.level_count(counter) ) .. lua_table.rough_view(counter)
    	local counter = lua_table.count_values(projects, "lang")
    	t = t .. "\n* Count begin projects: " .. viewers.ta("n", lua_table.level_count(counter) ) .. lua_table.rough_view(counter)
    	local counter = lua_table.count_values(versions, "lang")
    	t = t .. "\n* Count begin versions: " .. viewers.ta("n", lua_table.level_count(counter) ) .. lua_table.rough_view(counter)
    	viewers.restore_configs(memo, "activity.begin_central_modules_support") -- Restore global configurations after eventual changes.
    	return t
    end -- t = t .. activity.begin_central_modules_support(t) -- Survey the current state of sub tasks to debug. len
    
    function activity.central_module_descriptor(wiki, selector) -- Begin to adapt the main central module version to a wiki.
    	local mwuri = mw.uri.new()
    	local hostPort = mwuri.hostPort
    	local actual_wiki = false
    	if type(selector ~= "string") then selector = hostPort end -- Adapt to actual wiki as default
    --			wiki.doc_full = wiki.version_full .. "/" .. wiki.doc -- fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation
    	if not CMD then CMD = tracker.initadd({ ["name"] = "CMD", ["limit"] = 2 }) end -- Initialize a track
    	wiki.actual_wiki = actual_wiki -- Is this wiki selected?
    	if (type(wiki.doc_full) == "string") then -- fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation
    		local points = string.gsub(wiki.doc_full, "/", ".") -- fr.wikisource.org.wiki.Module:Centralizer-s-fr.Documentation
    		local points = string.gsub(points, ":", ".") -- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation
    		local s = mw.text.split(points, '.', true)-- { "fr", "wikisource", "org", "wiki", "Module", "Central-s-fr", "Documentation" }
    		wiki.url_ref = "https://fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation"
    		wiki.protocol = "https://" -- https://
    		wiki.lang_project_org = s[1] .. "." .. s[2] .. "." .. s[3]
    		if (type(wiki.enforce_main_version) == "string") then wiki.lang_project_org = wiki.enforce_main_version end
    		wiki.doc_full = string.gsub(wiki.doc_full, wiki.lang_project_org, wiki.enforce_main_version)
    		-- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation
    		local points = string.gsub(wiki.doc_full, "/", ".") -- fr.wikisource.org.wiki.Module:Centralizer-s-fr.Documentation
    		local points = string.gsub(points, ":", ".") -- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation
    		local s = mw.text.split(points, '.', true)-- s= { "fr", "wikisource", "org", "wiki", "Module", "Central-s-fr", "Documentation" }
    		wiki.lang = s[1] -- fr
    		wiki.project = s[2] -- wikisource
    		if wiki.project =="MediaWiki" then wiki.lang = "en" end
    		wiki.proj = activity.kiwis_names[wiki.project] or "proj" -- s in brief for wikisource
    		wiki.org = s[3] -- org
    		wiki.lang_project_org = wiki.lang .. "." .. wiki.project .. "." .. wiki.org -- fr.wikisource.org
    		if wiki.lang_project_org == hostPort then actual_wiki = true ; wiki.actual_wiki = actual_wiki end
    		if wiki.actual_wiki then
    			wiki.admins = tostring(mw.site.stats.usersInGroup("sysop"))
    			wiki.assets = tostring(mw.site.stats.activeUsers)
    			wiki.found = true -- This wiki is selected
    			CMD.add(CMD, 1, "descriptor admins assets hostPort", { ["admins"] = wiki.admins, ["assets"] = wiki.assets, ["actual_wiki"] = wiki.actual_wiki, ["lang_project_org"] = wiki.lang_project_org, } )
    		else
    			wiki.admins = wiki.admins
    			wiki.assets = wiki.assets
    			wiki.actual_wiki = wiki.actual_wiki -- This wiki is selected
    			CMD.add(CMD, 1, "descriptor admins assets else", { ["admins"] = wiki.admins, ["assets"] = wiki.assets, ["actual_wiki"] = wiki.actual_wiki, ["lang_project_org"] = wiki.lang_project_org, } )
    		end
    		CMD.add(CMD, 1, "descriptor wikis_to_begin", { ["i"] = i, ["s"] = s, ["wiki.lang"] = wiki.lang, ["wiki.lang_project_org"] = wiki.lang_project_org, } )
    		wiki.wiki = s[4] -- wiki
    		wiki.transmodule = s[5] -- Module
    		wiki.version = "Central-" .. wiki.proj .. "-" .. wiki.lang -- Central-s-fr
    		wiki.modulename = wiki.version -- s[6] -- Module
    		wiki.version_full = wiki.lang_project_org .. "/" .. wiki.wiki .. "/" .. wiki.transmodule .. ":" .. wiki.version
    		wiki.version_url = wiki.protocol .. wiki.lang_project_org .. "/" .. wiki.wiki .. "/" .. wiki.transmodule .. ":" .. wiki.version
    		wiki.version_link = "[" .. wiki.version_url .. " " .. wiki.version .. "]" -- To link to the central version
    		wiki.doc = s[7] -- Documentation
    		wiki.doc_full = wiki.version_full .. "/" .. wiki.doc -- fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation
    		wiki.doc_url = wiki.protocol .. wiki.doc_full -- https://fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation
    		wiki.doc_link = "[" .. wiki.doc_url .. " " .. wiki.doc .. "]" -- To link to the documentation of the central version
    		CMD.add(CMD, 1, "activity.descriptor links", { ["wiki.lang_project_org"] = wiki.lang_project_org, ["wiki.version"] = wiki.version, ["version_link"] = wiki.version_link, ["doc_link"] = wiki.doc_link, } )
    	end
    --	CMD.t = "\n* <b>:activity.central_module_descriptor()</b> END."
    	return wiki
    end -- function activity.central_module_descriptor(wiki, selector)
    
    function lua_table.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    	local t = viewers.ta("\n* Begin tab", tab ) .. viewers.ta("sortfield", sortfield) .. viewers.ta("sortorder", sortorder)
    	local tab = tab or {}
    	if (type(tab) == "string") then
    		tab = mw.text.split(tostring(tab), ';') -- table to sort
    	end
    	t = t .. versions.sorted_libraries_list
    	t = t .. viewers.ta("\n* Count of central libraries", lua_table.level_count(versions.sorted_libraries) )
    	if (type(tab) ~= "table") then tab = {} end
    	if not ( (type(sortfield) == "number") or (type(sortfield) == "string") ) then sortfield = 1 end
    	if (type(sortorder) ~= "string") then sortorder = "<" end
    	local sorted, i = {}, 0
    	for key, elem in pairs(tab) do
    		i = i + 1
    		table.insert(sorted, elem)
    	end
    	if (type(sortfield) == "string") then
    		table.sort(sorted, function (a, b) return ( ( a[sortfield or "a"] ) < ( b[sortfield or "b"] ) ) end ) -- Sort libraries
    	end
    	if (type(sortfield) == "number") then
    --		table.sort(sorted, function (a, b) return ( ( a[sortfield or 1] ) < ( b[sortfield or 1] ) ) end ) -- Sort libraries
    	end
    	t = t .. viewers.ta("\n* End tab", tab ) .. viewers.ta("sortfield", sortfield) .. viewers.ta("sortorder", sortorder)
    	return sorted, (t or "lua_table.to_sort()")
    end -- local sorted = lua_table.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    
    local ftd = ";"
    ftd = ftd .. "activity.phabricator_tasks_report;activity.rough_date_days;"
    ftd = ftd .. "activity.central_subtasks_report;activity.describe_central_libraries;activity.init_selected_wiki;activity.begin_central_modules_support;"
    ftd = ftd .. "activity.begin_central_modules_support;activity.central_functions_report;activity.central_subtasks_report;"
    ftd = ftd .. "activity.MW_Versions_report;activity.phabricator_tasks_report;"
    ftd = ftd .. "central_library.binded_in;central_library.new;"
    ftd = ftd .. "datas.get_image;datas.get_item;datas.get_item_report;datas.property;drop_box.new;"
    ftd = ftd .. "events.add_cat;events.add_cat_group;events.add_err;events.add_wng;events.all_kinds_test;"
    ftd = ftd .. "events.categories_lister;events.errors_lister;events.gener_categories;"
    ftd = ftd .. "langs.dummy_languages;langs.init_content_page_user_lang;langs.list_MediaWiki_languages;langs.main_i18n_languages_list;"
    ftd = ftd .. "langs.missing_translations;langs.translations_counts;"
    ftd = ftd .. "lua_table.count_all;lua_table.count_tests;lua_table.count_types;lua_table.count_values;"
    ftd = ftd .. "lua_table.from_subnames_object;lua_table.from_subnames_table;lua_table.level_count;lua_table.level_get;"
    ftd = ftd .. "lua_table.level_list;lua_table.named_sub_counts;lua_table.obj_from_subnames;lua_table.sort_onkey;"
    ftd = ftd .. "lua_table.sort_types;lua_table.structure;lua_table.structure_recursive_report;lua_table.tab_from_subnames;"
    ftd = ftd .. "lua_table.to_list;lua_table.to_list_tests;lua_table.to_table;lua_table.to_table_test;"
    ftd = ftd .. "mathroman.int2roman;mathroman.int2roman_test;mathroman.roman2int;mathroman.roman2int_tests;"
    ftd = ftd .. "modes.all_categories_list;modes.all_errors_list;modes.get_args;modes.get_args_report;modes.get_default_args;modes.levenshtein;"
    ftd = ftd .. "modes.multiple_selection_tests;modes.options_from_args_tests;modes.recursive_normal;modes.recursive_normal_tests;modes.similar_args_list;"
    ftd = ftd .. "tableview.form_one_case;tableview.new;"
    ftd = ftd .. "version descriptor;versions.all_G_and_loaded_list;versions.get_one_module_or_library;versions.setup_central_libraries;"
    ftd = ftd .. "viewers.day_to_stamp;viewers.day_to_UTC;viewers.discreet_main_version;viewers.doc_group;viewers.doc_internal;"
    ftd = ftd .. "viewers.doc_module;viewers.doc_page;viewers.doc_section;viewers.form99content;viewers.form99page;viewers.phab_task;"
    ftd = ftd .. "viewers.form99user;viewers.form9content;viewers.form9en;viewers.form9page;viewers.form9user;viewers.form9user_test;"
    ftd = ftd .. "viewers.form_image;viewers.is_in;viewers.is_in_sp;viewers.main_view;viewers.restore_configs;lua_table.rough_view;"
    ftd = ftd .. "lua_table.rough_view_test;viewers.save_configs;viewers.save_restore_balance_report;viewers.simple_list;"
    ftd = ftd .. "viewers.simple_list_test;viewers.styles_small_caps;viewers.ta;viewers.tam;viewers.table_col;viewers.table_dat;"
    ftd = ftd .. "viewers.table_end;viewers.table_head;viewers.table_row;viewers.styles_color_add;viewers.styles_color_colargs;"
    ftd = ftd .. "viewers.styles_color_delete;viewers.styles_color_discreet;viewers.styles_color_error;viewers.styles_color_mask;"
    ftd = ftd .. "viewers.styles_color_normal;viewers.styles_color_warning;viewers.styles_color_wikidata;viewers.usual_color;"
    
    activity.functions_to_doc = ftd
    
    function activity.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    	local t = viewers.ta("\n* Begin tab", tab ) .. viewers.ta("sortfield", sortfield) .. viewers.ta("sortorder", sortorder)
    	local tab = tab or {}
    	if (type(tab) == "string") then
    		tab = mw.text.split(tostring(tab), ';') -- table to sort
    	end
    	t = t .. viewers.ta("\n* Count of central libraries", lua_table.level_count(libname_libraries) )
    	if (type(tab) ~= "table") then tab = {} end
    	if not ( (type(sortfield) == "number") or (type(sortfield) == "string") ) then sortfield = 1 end
    	if (type(sortorder) ~= "string") then sortorder = "<" end
    	local sorted, i = {}, 0
    	for key, elem in pairs(tab) do
    		i = i + 1
    		table.insert(sorted, elem)
    	end
    	if (type(sortfield) == "string") then
    		table.sort(sorted, function (a, b) return ( ( a[sortfield or "a"] ) < ( b[sortfield or "b"] ) ) end ) -- Sort libraries
    	end
    	if (type(sortfield) == "number") then
    --		table.sort(sorted, function (a, b) return ( ( a[sortfield or 1] ) < ( b[sortfield or 1] ) ) end ) -- Sort libraries
    	end
    	t = t .. viewers.ta("\n* End tab", tab ) .. viewers.ta("sortfield", sortfield) .. viewers.ta("sortorder", sortorder)
    	return sorted, (t or "activity.to_sort()")
    end -- local sorted = activity.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    
    function activity.sort_central_libraries_functions(sorted_central_libraries) -- Select and sort central libraries and functions
    	local sorted_central_libraries = sorted_central_libraries or {} -- To sort any table and convert in sequence if needed.
    	local sorted_functions, libname, libname_funcname = {}
    	for libname, lib in pairs(package.loaded) do -- search directly in package.loaded
    		if(type(lib) == "table") and (type(lib.i18n) == "table") and (type(libname) == "string") -- Select central i18n objects
    		and (not string.find(libname, ":") ) then -- Avoid central modules
    			lib.libname = libname
    			table.insert(sorted_central_libraries, lib)
    			for funcname, func in pairs(lib) do -- search directly in package.loaded Rical 20180321
    				if (type(func) == "function") then -- select central libraries
    					libname_funcname = libname .. "." .. funcname
    					table.insert(sorted_functions, { ["libname"] = libname, ["funcname"] = funcname, ["libname_funcname"] = libname_funcname } )
    				end
    			end
    		end
    	end
    	table.sort(sorted_central_libraries, function (a, b) return ( a.libname < b.libname ) end ) -- Sort libraries
    	table.sort(sorted_functions, function (a, b) return ( (a.libname_funcname < b.libname_funcname ) ) end ) -- Sort libraries
    	activity.sorted_central_libraries = sorted_central_libraries
    	activity.sorted_functions = sorted_functions
    	return sorted_central_libraries, sorted_functions
    end -- local sorted_central_libraries, sorted_functions = activity.sort_central_libraries_functions() -- Select and sort central libraries and functions
    
    -- Last
    function activity.central_functions_report(t) -- Lists actual functions for documentations.
    	local t = t or "\n* <b>activity.central_functions_report(t)</b> List all actual functions."
    	t = t .. '\n* Selected functions come from: <b>activity.functions_to_doc</b> = "<b>;activity.central_functions_report;events.add_cat;</b>"'
    	t = t .. "\n* The fonctions to document are in bold like <b>activity.central_functions_report</b>"
    	local sorted_central_libraries, sorted_functions = activity.sort_central_libraries_functions() -- Select and sort central libraries and functions
    	local libname, funcname, libname_funcname, asterisk = "", "", "", ""
    	t = t .. viewers.ta("\n* Count of central libraries", lua_table.level_count(sorted_central_libraries) )
    	local nlibfunc, nallfunc, nlibdoc, nalldoc = 0, 0, 0, 0
    	local sorted_to_autodoc = {}
    	local UPPER = ""
    	for i, lib in pairs(sorted_central_libraries) do
    		nlibfunc = 0
    		nlibdoc = 0
    		lib.libname = (lib.libname or lib.name or "libname")
    		t = t .. "\n* <b>Library " .. libname .. "</b>: "
    		for i, func_record in pairs(sorted_functions) do -- search all functions
    			if func_record.libname == lib.libname then
    				nallfunc = nallfunc + 1
    				nlibfunc = nlibfunc + 1
    				libname_funcname = tostring(func_record.libname_funcname)
    				asterisk = ""
    				if string.find(activity.functions_to_doc, libname_funcname, 1, true) then --OK
    					nlibdoc = nlibdoc + 1
    					nalldoc = nalldoc + 1
    					if string.lower(libname_funcname) ~= libname_funcname then UPPER = UPPER .. libname_funcname .. ", " end -- funcname with uppercase
    					t = t .. " <b>" .. libname_funcname .. "</b>, "
    					table.insert(sorted_to_autodoc, { ["name"] = name, ["funcname"] = funcname, ["libname_funcname"] = libname_funcname } )
    				else
    					t = t .. libname_funcname .. ", "
    				end
    			end
    		end
    		table.insert(sorted_functions, { ["name"] = name, ["funcname"] = funcname, ["libname_funcname"] = libname_funcname } )
    		t = t .. viewers.ta("* <i>Count of functions in this library</i>", nlibfunc) .. viewers.ta("<i>to document</i>", nlibdoc)
    	end
    	table.sort(sorted_functions, function (a, b) return ( (a.libname_funcname < b.libname_funcname ) ) end ) -- Sort libraries
    	t = t .. viewers.ta("\n* <i>Count of functions in all libraries</i>", nallfunc)
    	t = t .. viewers.ta("<i>functions to doc</i>", lua_table.level_count(sorted_to_autodoc) )
    	t = t .. viewers.ta("<i>functions with doc</i>", nalldoc)
    	t = t .. viewers.ta("\n* <b>Count of sorted functions: </b>", lua_table.level_count(sorted_functions) )
    	t = t .. viewers.ta("\n* <b>List of functions with uppercase in funcname</b>: ", UPPER )
    	activity.sorted_functions = sorted_functions
    	activity.sorted_to_autodoc = sorted_to_autodoc
    	return t
    end -- function activity.central_functions_report(t)
    -- Last
    
    function activity.central_libraries_autodoc(t, sorted_functions) -- Formats a basic documentation for sorted functions.
    	local t = t or "\n* <b>activity.central_libraries_autodoc(t)</b> Formats a basic documentation for sorted functions."
    	t = t .. "\n*"
    	local sorted_functions = sorted_functions or activity.sorted_functions
    	local one_autodoc = "<br>[[= = = %1 = = =]]<br> "
    	for i, lib_func in pairs(activity.sorted_to_autodoc) do -- form one_autodoc
    		t = t .. viewers.form9user(one_autodoc, lib_func.libname_funcname)
    	end
    	t = string.gsub(tostring(t), "= = =", "===")
    	t = string.gsub(tostring(t), "= =", "==")
    	return t
    end -- function activity.central_libraries_autodoc(t, sorted_functions)
    
    activity.report_subtasks_list = { -- List of subtasks to report. See "NOW",
    	-- Begin later below
    	--loadData
    	-- DUPLICATE NOWNOW, in change. toDoc
    	{ "---",		"---",		"---",	"---",	"---",		"DUPLICATE NOW, in change", },
    	{ "20181101", "20181101", "NOW", "Rical", "S181101tgl", "Begin: translate by groups of languages : like for viet, laos, cambodgia, allways with en, es, fr 1 days", },
    	{ "20181101", "20181101", "NOW", "Rical", "S181101aip", "Begin: when 10 used cases, announce that in the phabtask, then when 20, then for xmas 1 days", },
    	{ "20181023", "20181030", "NOW", "Rical", "S181023s7P", "Begin: search 7 Projects : MediaWikis wikidata wikipedia wikisource wikiquote ? 3 days", },
    	{ "20181023", "20181030", "NOW", "Rical", "S181023iLC", "Begin: Rical invite 7 Lua-coders : Tpt, Zolo, Od1n, Julien1978, Daehan, VIGNERON ? 3 days", },
    	{ "20181020", "20181022", "NOW", "Rical", "S181020umf", "update MediaWiki:Scribunto/Central manual for ;activity.phabricator_tasks_report;activity.rough_date_days;...", },
    	{ "20181018", "20181020", "NOW", "Rical", "S181018CrC", "Module:CentralSchool: finish reciprocal adaptation with Module:Centralizer", },
    	{ "20181016", "20181017", "NOW", "Rical", "S181016vap", "restore versions.anti_crash(frame) if not pcall() recursive in versions.tree_branch='v1;v2;v3' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_arg has a arg_default in p.known_args and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_data has a data_default in datas.known_datas and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_mode has a mode_default in modes.known_modes and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_version has a version_default in versions.version_args and a .delete = 'delete' ", },
    -- function versioning.antiCrash(options, content_or_func, ...) -- Form the display of a running error. in ModuleCentral 20170902.ModuleCentral 2e no antiCrash ok.lua
    	{ "20181014", "20181014", "NOW", "Rical", "S181014uft", "update function tab_view.form_one_case + translate from multiple_selection_test1(...", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014uft", "update function tab_view.form_one_case + translate from recursive_normal_test1(...", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014upt", "update activity.phabricator_tasks_report", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014ust", "Module:Centralizer update subtasks list", },
    	--
    	-- Automatic shift of below "todo" subtasks.
    	{ "---",		"---",		"---",	"---",	"---",		"Automatic shift of below todo subtasks", },
    	{ "20180108", "20180109", "todo", "Rical", "S180108wtd", "Restore old function datas.wikidata_time_details()", },
    	{ "20180108", "20180109", "todo", "Rical", "S180108blg", "For each wikidata search the better lang in userlang, userlang2, pagelang, contentlang", },
    	{ "20180106", "20180108", "todo", "Rical", "S180106arg", "new Object:args form known arguments to import, complete from datas and finalize", },
    	{ "20171019", "20171022", "todo", "Rical", "S171019ime", "include Lua modules in extensions like Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.lua, see phabtask T41610.", },
    	{ "20171015", "20171018", "todo", "Rical", "S171015trk", "add a method tracker:trk(self, ...) from tracker.add(opt, ...). see Lua_reference_manual#Function_declaration_statements", }, --
    	{ "20171001", "20171002", "todo", "Rical", "S170801cvG", "put MW versions and Central versions in _G and CentralData", },
    	{ "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create Special:PageData/CentralData (change from MW only)", },
    	{ "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create MediaWiki:Scribunto/CentralData (change from admin only)", },
    	{ "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create Central/PageData/CentralData (change from any user)", },
    	{ "20170915", "20170917", "todo", "Rical", "S170915ajb", "phabtask extend tests_groups.subdiffs() to lua_table.trees.all_jobs", },
    	{ "20170910", "20170914", "todo", "Rical", "S170910wpw", "Use: wikidata = { property = 'P84',... syntax like {{Wikidata}} for wikidata", },
    	-- see 4.2 Paramètre "wikidata" https://fr.wikipedia.org/wiki/Aide:Infobox_en_Lua#Param.C3.A8tre_.22wikidata.22
    	{ "20170910", "20170914", "todo", "Rical", "S170910bob", "Create a button object for boxes, like drop_box with: n, states, shapes, keywords, colors", },
    	{ "20170828", "20170905", "todo", "Rical", "S170828dut", "delete unused tracker in _G : ARGS, IAMO, MAMO, tests_groups", },
    	{ "20170828", "20170905", "todo", "Rical", "S170820vtg", "try graphics in viewers.try_graph() -- see Macron", },
    	{ "20170816", "20170823", "todo", "Rical", "S170901adl", "automatize langs.dummy_languages() using isSupportedLanguage(xx)", },
    	{ "20170816", "20170823", "todo", "Rical", "S170901sas", "debug modes.similar_args_search() Test des mots proches similaires", },
    	{ "20170816", "20170823", "todo", "Rical", "S170901mMW", "use Special:PageData CentralData T163923+T168726 in activity.MW_Versions_report()", },
    	{ "20170816", "20170823", "todo", "Rical", "S170729eli", "easy https://en.wikisource.org/wiki/Template:Lorem_ipsum", },
    	{ "20170816", "20170823", "todo", "Rical", "S170728acr", "debug versions.anti_crash() + tests", },
    	{ "20170816", "20170823", "todo", "Rical", "S170801uPD", "automatize PageData change in datas.update_PageData(t) for activity.MW_Versions_report()", },
    	{ "20170811", "20170815", "todo", "Rical", "S170716tac", "langs.abnormal_char_in_text() fails", },
    	{ "20170811", "20170815", "todo", "Rical", "S170615css", "use Conventional css parameters cssview in edit, content, drop_box, infobox, tableview ... ", },
    	{ "20170811", "20170815", "todo", "Rical", "S170720diw", "Enhance datas.get_item() from 20170403 ModuleCentral 6a clean display.lua", },
    	{ "20170811", "20170815", "todo", "Rical", "S170718FLI", "Propose Firstname, Lastname and Initial in wikidata", },
    	{ "20170811", "20170815", "todo", "Rical", "S170718FLI", "lua_table.4_diffs(A, B) Detect 4 first diffs of tables A/B and B/A, in-deep/in-next with limits", },
    	{ "20170811", "20170815", "todo", "Rical", "S170811uMD", "After 'Begin' fully use Module:drop_box from es.wikipedia.org/wiki/Módulo:Lista_plegable", },
    	-- S170718FLI : in https://www.wikidata.org/wiki/Wikidata:Property_proposal/Person#Noms().", },
    	-- S170718FLI : T53657 is Close : Firstname and Lastname properties
    	-- S170718FLI : T53657 to re Open : Firstname and Lastname properties. Follow Aklapper comment on Jul 19 2013, 12:51
    	{ "20170810", "20170811", "todo", "Rical", "S180311a2c", "if _i_cat or _u_cat add 2 categories: detailed and ( internal or usage )", },
    	--		if viewers.is_in("_i_cat", key) then key = "versions_with_internal_error" -- = "Module with internal error",
    	--	elseif viewers.is_in("_u_cat", key) then key = "versions_with_usage_error" -- = "Module with usage error",
    	{ "20170810", "20170811", "todo", "Rical", "S180810lts", "continue function lua_table.to_sort(tab, ...) To convert any table in sequence, and sort it.", },
    	{ "20180410", "20180414", "todo", "Rical", "S180410ilp", "After 'Begin' T20180621 Enough inform Central modules for jumps to lang.project URI.", },
    	{ "20180410", "20180414", "todo", "Rical", "S180410alp", "After 'Begin' T20180621 Automatic adapt Central modules for lang.project URI.", },
    	{ "20180407", "20180410", "todo", "Rical", "S180407rlv", "After 'Begin' Fully report modules and libraries versions.", },
    	{ "20180407", "20180409", "todo", "Rical", "S180407ruc", "After 'Begin' report all viewers.usual_color(t)", },
    	{ "20170810", "20170811", "todo", "Rical", "S180306vdf", "debug function versions.deprecated_function() nil table : mask it on 20180306", },
    	{ "20170810", "20170811", "todo", "Rical", "S170617rpd", "debug modes.recursive_normal() test", },
    	{ "20170810", "20170811", "todo", "Rical", "S170614tva", "Use tableview.new() for all tables, search .table_end()", }, --
    	{ "20170810", "20170811", "todo", "Rical", "S170813lll", "debug lua_table.level_list(mw) for all uses", }, --
    	{ "20170808", "20170810", "todo", "Rical", "S170707icc", "Begin: begin to integrate	 changes from other coders", },
    	{ "20170808", "20170810", "todo", "Rical", "S170707icc", "Begin: update important Phabricator tasks to activate their availability", },
    	-- Inform after 'Create Begin'
    	{ "20170805", "20170807", "todo", "Rical", "S170702cJP", "Begin: Lua-coders Utilisateur:JackPotte [[:fr:Utilisateur:JackPotte|JackPotte fr de es en]]", },
    	{ "20170805", "20170807", "todo", "Rical", "S170702wvm", "Begin: announce Meet coders throught Wikis video meeting France SWEL-fr https://meet.jit.si/swel-fr", },
    	{ "20170805", "20170807", "todo", "Rical", "S170702atr", "Begin: Ask translations in meta [https://meta.wikimedia.org/wiki/Translation_requests Translation_requests]", },
    	{ "20170805", "20170807", "todo", "Rical", "S170604iTN", "Begin: inform [https://meta.wikimedia.org/wiki/Tech/News#contribute Tech News] about central modules begin phase", },
    	-- S170604iTN : Tech/News#contribute : central, begin to use, efficiency, ask lua coders ?
    	-- Debug to support Create Begin's group
    	-- Automatic shift of behind "todo" subtasks.
    	-- Begin later behind
    	--
    	-- NOWNOW DP, NOW, in change
    	{ "---",		"---",		"---",	"---",	"---",		"NOW, in change", },
    	{ "20181101", "20181101", "NOW", "Rical", "S181101tgl", "Begin: translate by groups of languages : like for viet, laos, cambodgia, allways with en, es, fr 1 days", },
    	{ "20181101", "20181101", "NOW", "Rical", "S181101aip", "Begin: when 10 used cases, announce that in the phabtask, then when 20, then for xmas 1 days", },
    	{ "20181023", "20181030", "NOW", "Rical", "S181023s7P", "Begin: search 7 Projects : MediaWikis wikidata wikipedia wikisource wikiquote ? 3 days", },
    	{ "20181023", "20181030", "NOW", "Rical", "S181023iLC", "Begin: Rical invite 7 Lua-coders : Tpt, Zolo, Od1n, Julien1978, Daehan, VIGNERON ? 3 days", },
    	{ "20181020", "20181022", "NOW", "Rical", "S181020umf", "update MediaWiki:Scribunto/Central manual for ;activity.phabricator_tasks_report;activity.rough_date_days;...", },
    	{ "20181018", "20181020", "NOW", "Rical", "S181018CrC", "Module:CentralSchool: finish reciprocal adaptation with Module:Centralizer", },
    	{ "20181016", "20181017", "NOW", "Rical", "S181016vap", "restore versions.anti_crash(frame) if not pcall() recursive in versions.tree_branch='v1;v2;v3' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_arg has a arg_default in p.known_args and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_data has a data_default in datas.known_datas and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_mode has a mode_default in modes.known_modes and a .delete = 'delete' ", },
    	{ "20181015", "20181016", "NOW", "Rical", "S181015odd", "one_version has a version_default in versions.version_args and a .delete = 'delete' ", },
    -- function versioning.antiCrash(options, content_or_func, ...) -- Form the display of a running error. in ModuleCentral 20170902.ModuleCentral 2e no antiCrash ok.lua
    	{ "20181014", "20181014", "NOW", "Rical", "S181014uft", "update function tab_view.form_one_case + translate from multiple_selection_test1(...", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014uft", "update function tab_view.form_one_case + translate from recursive_normal_test1(...", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014upt", "update activity.phabricator_tasks_report", },
    	{ "20181014", "20181014", "NOW", "Rical", "S181014ust", "Module:Centralizer update subtasks list", },
    	-- Already done
    	{ "---",	  "~sort~",	  "---",  "---",   "---",		 "Already done", },
    	{ "20180824", "20180825", "done", "Rical", "S180824iCD", "in activity.begin_central_modules_support() header namespace and local links.", },
    	{ "20180730", "20180730", "done", "Rical", "S180730ust", "Module:Centralizer update subtasks list", },
    	{ "20180722", "20180726", "done", "Rical", "S180722sLc", "Update activity.begin_central_modules_support() to begin to search 7 Lua-coders.", },
    	{ "20180715", "20180722", "done", "Rical", "S180715srb", "Update viewers.save_restore_balance_report(t) OK.", },
    	{ "20180708", "20180715", "done", "Rical", "S180708Ric", "Begin: Rical start with Auteur2Tpt ... until 7 Lua-coders, in 7 projects, in 7 Languages.", },
    	{ "20180708", "20180708", "done", "Rical", "S180708ust", "Module:Centralizer update subtasks list", },
    	{ "20180701", "20180714", "done", "Rical", "S180718Ric", "Begin: Rical continue with Auteur2Tpt to enhance translations.", },
    	{ "20180625", "20180625", "done", "Rical", "S180625ALC", "Begin: Ask Lua-coders: Zolo, Zebulon84, Hlm Z., Cantons-de-l'Est, Thibaut120094, Daehan", },
    	{ "20180625", "20180625", "done", "Rical", "S180621new", "For 'Begin' complete translations in Module:Centralizer/I18N.lua.", },
    	{ "20180625", "20180625", "done", "Rical", "S180625btu", "Begin: Create phab task T198107 Begin to use central modules", },
    	{ "20180624", "20180625", "done", "Rical", "S180624cMA", "Begin: for Rical : convert Module:Auteur2 to central, from Tpt", },
    	{ "20170824", "20170825", "done", "Rical", "S170620dcm", "Begin: announce and description in Discussion MediaWiki:Scribunto/Central manual", },
    	{ "20180621", "20180625", "done", "Rical", "S180621new", "For 'Begin' document Module:Centralizer/I18N.lua. Do not really help.", },
    	{ "20180619", "20180619", "done", "Rical", "S180619icm", "For 'Begin' Install the Central-s-fr last version in s-br s-de w-es s-es s-fr s-es w-hu w-vi", },
    	{ "20180619", "20180619", "done", "Rical", "S180619tMI", "For 'Begin' group all translations in Module:Centralizer/I18N.lua", },
    	{ "20170727", "20170612", "done", "Rical", "S171210arg", "Avoid upercase in near all fucntions names", },
    	{ "20170724", "20170610", "done", "Rical", "S180128lit", "Show details link to internal error cat ending _i_cat, _u_cat in events.add_record()", },
    	{ "20180607", "20180608", "done", "Rical", "S180607uts", "After 'Begin' Update all important tasks to support central modules", },
    	{ "20180601", "20180606", "done", "Rical", "S180617upt", "For 'Begin' Update all phabtask in activity.phabricator_tasks_Group{}", },
    	{ "20180601", "20180604", "done", "Rical", "S180617ufc", "For 'Begin' update Central-s-fr functions comments from Central manual.", },
    	{ "20180604", "20180604", "done", "Rical", "S180604crm", "For 'Begin' T20180604 Update Central modules reference manual. DONE", },
    	{ "20180518", "20180518", "done", "Rical", "S180518ust", "Module:Centralizer update subtasks list", },
    	{ "20180421", "20180421", "done", "Rical", "S180421CGL", "For 'Begin' renew CentralGuideline from CentralModules and CentralManual", },
    	{ "20180419", "20180420", "done", "Rical", "S180419aCv", "add Central version in running_times", },
    	{ "20180414", "20180414", "done", "Rical", "S180414ust", "Module:Centralizer update subtasks list", },
    	{ "20180413", "20180416", "done", "Rical", "S180413uia", "Update modes.get_args()=args_known +source +template +import +... with priorities", },
    	{ "---",		"---",		"---",	"---",	"---",		"STOP the display of this table", },
    	{ "20170729", "20170729", "done", "STOP", STOP = "STOP", }, -- STOP the display of this table
    	{ "20180329", "20180407", "done", "Rical", "S180329uma", "For 'Begin' Update ModuleAuthor3.lua.", },
    	{ "20180322", "20180323", "done", "Rical", "S180322crm", "For 'Begin' Update Stability in Central modules reference manual", },
    	{ "20180307", "20180326", "done", "Rical", "S180307clr", "For 'Begin' debug function activity.central_functions_report look OK", },
    }
    --	return activity.report_subtasks_list
    --end -- activity.report_subtasks_list = { -- List of subtasks to monitor.
    
    --	See tasks in activity.phabricator_tasks_report() and sub-tasks in activity.central_subtasks_report(t)
    function activity.central_subtasks_report(t) -- Reports the current state of subtasks defined by Lua-coders. See "NOW",
    	local memo = viewers.save_configs("activity.central_subtasks_report") -- Save global configuration before eventual changes.
    	local t = t or '\n* <b>activity.central_subtasks_report()</b> Report the current state of subtasks. Automaticaly shifts tasks to do later, See "NOW".'
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = activity.report_subtasks_list, -- List of subtasks to monitor.
    		title_memo = "activity_report_subtasks_title", -- "activity.central_subtasks_report(t) Report the current state of subtasks, See "NOW".",
    		headers = " start;		end;	state;	user;	sub id; bug description; duration ",
    		headers_class = "wikitable alternative center sortable",
    	--	track_on = true,
    		ccc = {}, -- To communicate and compute between cases
    		rowGroup = {},
    	}
    	local function tab_view_rough_shifter(tab_view) -- Monitor and shift tasks.
    		tab_view.ccc.now = os.date("%Y%m%d")
    		tab_view.ccc.now_days = activity.rough_date_days(tab_view.ccc.now)
    		local stop_min_days, delay_min = 999999, 999999, 999999
    		tab_view.ccc.shift_days = 999999
    		tab_view.ccc.stop_min = "99999999"
    		for i, bug in pairs(tab_view.test_group) do -- First: Compute how to shift subtasks.
    			bug.track = ""
    			local now = tab_view.ccc.now
    			tab_view.ccc.now_days = activity.rough_date_days(tab_view.ccc.now)
    			bug.start = bug[1]
    			bug.stop = bug[2]
    			bug.plan = bug[3]
    			local y2 = tonumber(string.sub(bug.stop,1,4))
    			local m2 = tonumber(string.sub(bug.stop,5,6))
    			local d2 = tonumber(string.sub(bug.stop,7,8))
    			local date_days, y2, m2, d2, years, months, days = activity.rough_date_days(bug.stop) -- Rough date days of a time stamp, from 0000-01-01.
    			bug.start_days = activity.rough_date_days(bug.start)
    			bug.stop_days = activity.rough_date_days(bug.stop)
    			bug.duration = bug.stop_days - bug.start_days
    			if (type(bug.start) == "string") and (type(bug.stop) == "string") and (bug.plan == "todo") then
    				if bug.stop < tab_view.ccc.stop_min then
    					tab_view.ccc.stop_min = bug.stop
    					tab_view.ccc.stop_min_days = activity.rough_date_days(tab_view.ccc.stop_min)
    					if tab_view.ccc.stop_min_days < tab_view.ccc.now_days then tab_view.ccc.stop_min_days = tab_view.ccc.now_days end
    					tab_view.ccc.shift_days = (tab_view.ccc.stop_min_days + 2) - bug.stop_days
    				end
    				bug.track = bug.track.."<br/>"..viewers.ta("now", now)..viewers.ta("y2", y2)..viewers.ta("m2", m2)..viewers.ta("d2", d2)
    				bug.track = bug.track.."<br/>"..viewers.ta("stop", bug.stop)..viewers.ta("delay", bug.duration)..viewers.ta("date_days", date_days)
    			end
    		end
    		for i, bug in pairs(tab_view.test_group) do -- After: really shift subtasks.
    			bug.start = bug[1]
    			bug.stop = bug[2]
    			bug.plan = bug[3]
    			bug.start = bug.start --.. "+3 " .. bug.start
    			if bug.plan == "todo" then -- Only for todo tasks
    				bug.start_days = activity.rough_date_days(bug.start)
    				bug.start = activity.rough_days_timestamp(bug.start_days + tab_view.ccc.shift_days) -- Rough time stamp from date days, like "20170806".
    				bug.stop_days = activity.rough_date_days(bug.stop)
    				bug.stop = activity.rough_days_timestamp(bug.stop_days + tab_view.ccc.shift_days) -- Rough time stamp from date days, like "20170806".
    			end
    		end
    	end -- function tab_view_rough_shifter(tab_view) -- Shift todo tasks.
    	function tab_view.form_one_case(bug, tab_view) -- Convert a case from test_group to rowGroup.
    		bug.start = bug.start or bug[1] or "---"
    		bug.stop = bug.stop or bug[2] or "---"
    		bug.plan = bug.plan or bug[3] or "---"
    		if bug.plan == "todo" then -- Display one row whole in bold.
    			bug[6] = bug[6] -- .. bug.track
    		end
    		if bug.plan == "NOW" then -- Display one row whole in bold.
    			bug.start = "<b>" .. bug.start .. "</b>"
    			bug.stop = "<b>" .. bug.stop .. "</b>"
    			bug.plan = "<b>" .. bug.plan .. "</b>"
    			bug[4] = "<b>" .. bug[4] .. "</b>"
    			bug[5] = "<b>" .. bug[5] .. "</b>"
    			bug[6] = "<b>" .. bug[6] .. "</b>"
    			bug.duration = "<b>" .. bug.duration .. "</b>"
    		end
    		return { bug.start, bug.stop, bug.plan, bug[4], bug[5], bug[6], bug.duration, }
    	end
    	tab_view_rough_shifter(tab_view) -- Monitor and shift tasks.
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "activity.central_subtasks_report") -- Restore global configurations after eventual changes.
    	return t
    end -- t = function activity.central_subtasks_report(t) -- Report the current state of subtasks, See "NOW".
    
    activity.phabricator_tasks_Group = { -- toDoc
    --	Importance: Important
    	{ 102, "Important", "20180412", "T185557", 0, "Open", "Create the easy function mw.wikibase.property('P21', 'Q8023', 'en')", },
    	{ 106, "Important", "20170703", "T20170703", 0, "ToCreate", "Standardize content, page and user langages availability", },
    --	T20170703 : Rename T68051 : "Central modules need the user language to display errors and category names"
    --	T20170703 : Standardize content, page and user langages availability
    --	T20170703 : Content, page and user langages are not available nor defined in the same ways for scribunto modules.
    --	T20170703 : That complicate modules which use them. Similar ways could enhance efficiency and reduce the development tasks.
    	{ 110, "Important", "20170325", "T20170325", 0, "ToCreate", "Centralize and share central datas about central modules", },
    --	T20170325 : Centralize datas as MediaWiki versions installations in each lang-project, uses of central modules (helpers, projects, languages ...).
    	{ 114, "Important", "20180626", "T135845", 0, "Assigned", "Convert any module as central or centralisable", },
    --	T135845 : Central modules must be really multi wikis.
    --	T135845 : For this goal they need to join a standard template with the central module.
    --	T135845 : But the MediaWiki security prohibit them in Lua modules. Then the deployment must do these.
    	{ 116, "Important", "20160822", "T53660", 0, "Open", "Detect the edit state for modules which help users and helpers", },
    	{ 118, "Important", "20180806", "T4085", 0, "Open", "Add a {{USERLANGUAGE}}/{{USERLANG}} magic word", },
    	{ 118, "Important", "20181005", "T173207", 0, "Open", "Implement Lua alternative to {{int:Lang}} / wgUserLanguage", },
    	{ 119, "Important", "20180710", "T107119", 0, "Open", "Provide a Lua method mw.loadTemplateData()", }, -- See PageData
    	{ 120, "Important", "20170713", "T163923", 0, "Resolved", "Create Special:PageData as a canonical entry point for machine readable page data.", },
    	-- T163923: Permit at modules to change PageData (for stat, modules versions, mw versions...).
    	{ 122, "Important", "20170727", "T149532", 0, "Resolved", "Why Multi-Content-Revisions? Use cases and requirements.", },
    	{ 124, "Important", "20180817", "T168726", 0, "Open", "Create syntax documentation page for Special:PageData.", },
    	{ 126, "Important", "20170907", "T68051", 1, "Open", "Central modules need the user language to display errors and category names", },
    	{ 132, "Important", "20180603", "T85461", 0, "Resolved", "Lua error: too many language codes requested", },
    --	T85461 https://meta.wikimedia.org/wiki/Module:Assemble_multilingual_message
    --	T85461 https://meta.wikimedia.org/w/index.php?title=Module:Assemble_multilingual_message&action=edit#mw-ce-l46
    	{ 134, "Important", "20170309", "T159322", 0, "Open", "Central categories and alerts for central modules", },
    --	T159322 : Does the community agree to implement central categories and alerts for central modules?
    --	T159322 : This enhances the efficiency of the detection and the correction of errors, in some ways:
    	{ 136, "Important", "20160522", "T85419", 0, "Open", "User groups should be exposed to Scribunto", },
    --	T85419: to adapt errors and warning for administrators or modules coders
    	{ 138, "Important", "20180413", "T142093", 0, "Open", "Decide how to do usage tracking for strings_c used to lookup entities (page titles, external ids, …)", },
    	{ 140, "Important", "20170211", "T20170211", 1, "ToCreate", "In mw.language.fetchLanguageNames( 'fr' ) some languages names are not in French", },
    --	T20161220 : ToDo: test: local getContentLanguage = mw.language.getContentLanguage().code -- default content_lang
    	{ 146, "Important", "20170921", "T176362", 0, "Declined", "Implement ClassNameTests in Scribunto to enhance central modules stability", },
    --	T176362 : phabtask : Implement getTestProvider in Scribunto to enhance central modules stability
    --	T176362 : phabtask : proposed functions in MediaWiki:
    --	T176362 : phabtask : mw.getTestProvider(mw_tests, nmaxi) -- To initialise, to limit all tests in time and to limit cases to nmaxi.
    --	T176362 : phabtask : mw.ClassNameCase(case, n), used inside mw.getTestProvider() to run each test case of number 1 to nmaxi.
    --	T176362 : phabtask : The case object contains fields: count, OK="OK"..., n, name, type, args{}, expect{}, NameTest{}, func(), provide(), run()
    --	T176362 : phabtask : Functions used in central modules: tests_groups.getTestProvider(), .init(), .gettests_groups(), .getcases(), .subdiffs(), .normalcase(case), viewers.form9en()
    --	T176362 : phabtask : In the tests_groups library, tests cases are in recursive groups of groups of cases. Groups levels: main module, sub modules or libraries, functions and their tests cases.
    	{ 148, "Important", "20170121", "T122752", 1, "Open", "#invoke do not record the main module in package.loaded", },
    --	T122752: 20161202 18:25 See example https://fr.wikisource.org/wiki/Module:Phab.TestpackG : detect "in " "_G" or package.loaded
    --	T122752: 20160102 22:46 See example https://fr.wikisource.org/wiki/Module:TestRequire
    --	T122752: To locate and to debug the bug T122752 in time, Rical lists here the versions of fr.wikisource.org/wiki/Module:ControlArgs1
    --	T122752: Oldest research of "Replace the missing of record of the module by" : ModuleControlArgs 6 tools...lua 2016-01-16
    --	T122752: (actu | diff) 2015-11-25T11:43:11‎ Rical (discussion | contributions | bloquer)‎ . . (261 314 octets) (-3 519)‎ . . (The versions management seems OK) (annuler)
    --	T122752: (actu | diff) 2015-11-28T09:55:37‎ Rical (discussion | contributions | bloquer)‎ . . (267 472 octets) (+5 809)‎ . . (find_main_module)
    --	T122752: (actu | diff) 2015-12-01T14:18:22‎ Rical (discussion | contributions | bloquer)‎ . . (268 956 octets) (+1 614)‎ . . (find_main_module OK ?)
    --	T122752: (actu | diff) 2016-01-18T02:09:45‎ Rical (discussion | contributions | bloquer)‎ . . (319 599 octets) (+10 183)‎ . . (translate library.i18n first)
    --	T122752: 2016-01-02 phabricator: T122752 Rical created this task. Sat, Jan 2, 2016-01-02 23:08
    	{ 156, "Important", "20180508", "T63958", 0, "Assigned", "Use existing $dateFormats to format dates on Wikidata", },
    	{ 160, "Important", "20170521", "T67687", 0, "Resolved", "mw.load_data can be used to pass data between #invoke's by reading frame arguments", },
    	--
    --	Importance: Central
    	{ 202, "Central", "20180701", "T198107", 0, "Open", "Begin to use central modules in 7 wikis S180625btu", },
    	{ 206, "Central", "20171106", "T20171106", 0, "ToCreate", "Lua-coders could better report bugs with recent MediaWiki versions for each wiki", },
    	{ 210, "Central", "20181002", "T121470", 0, "Open", "Central Global Repository for Templates, Lua modules, and Gadgets", },
    	{ 214, "Central", "20180718", "T52329", 0, "Stalled", "We need a common repository for Scribunto modules and templates", },
    	{ 218, "Central", "20180312", "T41610", 0, "Open", "Scribunto should support global module invocations", },
    --	T41610: subscriber: kaldari 2017-05-20, 16:03
    --	T41610: You can include Lua modules in extensions and then register them with Scribunto as global modules.
    --	T41610: Wikibase, for example, includes 2 Lua modules:
    --	T41610: Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.entity.lua
    --	T41610: Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.lua
    	{ 224, "Central", "20170301", "T20170301", 0, "ToCreate", "Phabricator tasks states for easier versions management of modules", },
    --	datas to get for each query: Task number, title, state, priority, Authored By and date, Last event date, number of subscribers, Assigned.
    	{ 228, "Central", "20170225", "T20170225", 0, "ToCreate", "? Report MediaWiki changes for the versions management, and use {{subst:}}", },
    --	T20170225: The gerrit team needs the date of a bug and the dates of mw install in each wiki to debug mw.
    --	T20170225: We could detect, record and report all date-time changes of MediaWiki, for some weeks.
    --	T20170225: We could use {{subst:}} in 2 ways. See https://www.MediaWiki.org/wiki/Manual:Substitution
    --	T20170225: duplicate of T121470: Central Global Repository for Templates, Lua modules, and Gadgets.
    	{ 230, "Central", "20170314", "T1238", 0, "Close", "Central Code Repository for code used on wikis (Templates, Lua modules, Gadgets)", },
    --
    --	Importance: Other
    	{ 302, "Other", "20180320", "T147618", 0, "Open", "Localize one or more major WMF software products related to new editor retention to hu.wikipedia", },
    	{ 304, "Other", "20180320", "T132308", 0, "Open", "Internationalise citoid dates", },
    	{ 306, "Other", "20180320", "T142906", 1, "Close", "Data access in user language doesn't obey the uselang get parameter", },
    	{ 308, "Other", "20180106", "T104109", 0, "Close", "No syntax highlight for large JavaScript/CSS/Lua/API pages", },
    	{ 310, "Other", "20170427", "T162877", 0, "Close", "CodeEditor default changed if you have never used the toggle", },
    	{ 312, "Other", "20170427", "T161875", 0, "Close", "CodeEditor is always enabled when starting an edit on a page containing code", },
    --	T161875: Actual: It is enabled, though mw.user.options.get('usecodeeditor') correctly gives 0.
    	{ 314, "Other", "20180412", "T85412", 0, "Open", "The formatPropertyValues needs an option to format data from date-time, angle or geographic coordinates", },
    	{ 316, "Other", "20170912", "T156048", 0, "Open", "Add syntax highlighting to wiki diff of source code pages (like Gerrit)", },
    	{ 318, "Other", "20180710", "T107119", 0, "Open", "Provide a Lua method mw.loadTemplateData()", },
    	{ 320, "Other", "20170524", "T166202", 0, "Open", "Strings defined as long comments give a Lua modules syntax error", },
    	--
    -- Other, ToCreate or not
    	{ 321, "Other", "20170213", "T20170213", 0, "ToCreate", "Some languages have not French names in French language", },
    	{ 322, "Other", "20151215", "T20151215", 0, "ToCreate", "In some cases the box of the drop_box is not displayed", },
    --	T20151215: .. "\n------ " -- This code interact with drop_box and debug the task T20151215 2016-11-13 17:57.
    --	T20151215: if there is "\n------ " before editDocBox and  then the editDocBox <div> is only a bar of 1 em hight, and its content is after the <div>. Rical 2016-10-24 08:15.
    	{ 326, "Other", "20160616", "T20160616", 0, "ToCreate", "? Add module and library types in scribunto ?", },
    --	T20160616: get.is_library = ( true ) -- true if the object is a library
    	{ 328, "Other", "20171007", "T155624", 0, "Open", "Special:Version not showing SHA info for MediaWiki version on fr.wikisource", },
    --	UTC-20170407-20:21 : reported in T155624 Special:Version not showing SHA info for MediaWiki version on fr.wikisource
    	--
    --	Importance: Obsolete: Do not create, these functions come from mw... libraries.
    	{ 428, "Obsolete", "20161022", "T20161022", 0, "ToCreate", "? Scribunto functions are out of package.loaded", },
    --	T20161022: --	Found in Lua_reference_manual but not in Module:Centralizer-s-fr :
    --	T20161022: --	2016-10-22 15:45 : versions.all_G_and_loaded_list() : Variables in _G global space without libraries and modules in packageloaded. ,
    --	xpcall = function , tostring = function , _VERSION = Lua 5.1 , unpack = function , require = function , pairs = function , next = function ,
    --	assert = function , ipairs = function , rawequal = function , getmetatable = function , rawset = function , pcall = function , type = function ,
    --	selector = function , rawget = function , tonumber = function , error = function , setmetatable = function
    	{ 430, "Obsolete", "20170324", "T133498", 1, "Declined", "Detect and extend known title <-> entity links in a semi-automatic way", },
    	{ 432, "Obsolete", "20161128", "T151715", 0, "Invalid", 'string.gsub( s, "%%1", repl) fails as "invalid capture index"', },
    	{ 434, "Obsolete", "20170110", "T154769", 0, "Invalid", 'When "Erreur Lua : attempt to call a string value", where?', },
    --	T154769: Rical 2017-01-08 My main mistake was to write xpcall() where pcall() is right.
    --	T154769: Tests are there https://fr.wikisource.org/wiki/Module:Phab.T154769.Test
    --	T154769: versions.anti_crash() preserve pages against residual errors which can crash pages.
    	{ 436, "Obsolete", "20170202", "T155898", 0, "Invalid", "Preview change from external local editors", },
    -- T155898: OK, I will continue to search in JEdit plugins. Perhaps I will ask them an adapted solution.
    	{ 438, "Obsolete", "20160424", "T67507", 0, "Resolved", "It should be possible to get entity id from page title", },
    	{ 440, "Obsolete", "20160524", "T119978", 0, "Invalid", "Get name and record-time of all modules to better manage their versions", },
    	{ 442, "Obsolete", "20160813", "T75460", 0, "Resolved", "[Story] Make Lua functions default to the user's language on multilingual wikis", },
    } -- activity.phabricator_tasks_Group = {...}
    
    function activity.phabricator_tasks_report(t, short) -- Reports the Phabricator tasks linked with central modules.
    	local memo = viewers.save_configs("activity.phabricator_tasks_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>activity.phabricator_tasks_report()</b> Monitor states of known phabricator tasks,"
    	t = t .. "\n* How to well report a task like in <b><big>viewers.phab_task('T149532#2878699', 'that task')</big></b> :"
    	t = t .. "\n* 1) <b>What happens in brief</b> 2) <b>Type of activity</b> 3) <b>What is the problem</b>"
    	t = t .. "\n* 4) <b>Dedicated test case without ambiguity.</b> "
    	t = t .. "\n* 5) <b>Expected outcome</b> 6) <b>Proposed solution</b>"
    	t = t .. "\n* 7) <b>Where and when to use the proposed solution</b>"
    	t = t .. "\n* 8) <b>Who would benefit + your name.</b> 9) <b>Current status of the discussion</b>"
    	t = t .. "\n* 10) <b>Links</b> 11) <b>Your name linked to your MediaWiki URL, or profile elsewhere on the internet</b>"
    	local mwtitle = mw.title.getCurrentTitle()
    	local tasks_Group = activity.phabricator_tasks_Group
    	local sort_importance = "Obsolete;Other;Important;Central"
    	local split_importance = mw.text.split(sort_importance, ';') -- table of words
    	local sort_import, split_n, split_import = {}, 1, "Open"
    	for i, task in pairs(tasks_Group) do
    		task.iii = tostring(task[1])		; task.importance = tostring(task[2])
    		task.lastdate = tostring(task[3])	; task.phab = tostring(task[4])
    		task.detect = tostring(task[5])		; task.status = tostring(task[6])
    		task.title = tostring(task[7])		; task.shortext = tostring(task[8])
    		task.sort = "s"
    		for split_n, split_import in pairs(split_importance) do
    			if task.importance == split_import then -- to sort on importance then lastdate
    				task.sort = task.sort .. split_n .. task.lastdate .. task.phab
    			end
    		end
    		table.insert(sort_import, task)
    	end
    	table.sort(sort_import, function (a, b) return ( a.sort > b.sort ) end ) -- to sort on importance then lastdate
    	table.sort(sort_import, function (a, b) return ( a.lastdate > b.lastdate ) end ) -- to sort on importance then lastdate
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = sort_import, -- = sorted activity.phabricator_tasks_Group,
    		title_memo = "activity_phabricator_tasks_title", -- "activity.phabricator_tasks_report() Monitor states of known phabricator tasks",
    		headers = "Importance; modified on; Task; Status; Title",
    		headers = "activity_phabricator_tasks_headers", -- "Importance; modified on; Task; Status; Title"
    		headers_class = "wikitable alternative center sortable",
    		rowGroup = {},
    		--	track_on = true,
    	}
    	function tab_view.form_one_case(task) -- Convert a task from test_group to rowGroup.
    		task.phab = viewers.phab_task(task.phab, task.phab)
    		local usual = "discreet"
    		if viewers.is_in(task.status, "ToCreate, Declined, Invalid, ") then usual = "discreet"
    		elseif viewers.is_in(task.status, "Open, Assigned, Gerrit") then usual = "normal"
    		elseif viewers.is_in(task.status, "Resolved") then usual = "invoke"
    		else usual = "discreet" end -- All states : ToCreate, Open, Stalled, Assigned, Resolved, Declined, Invalid, Gerrit
    		task.title = viewers.usual_color(task.title, usual)
    		if task.detect == 1 then task.title = task.title .. " - ( detected state )" end
    		--	headers =	"Importance; modified on; Task; Status; Title" -- "Importance, modifiée le, Tâche, Etat, Titre"
    		local importance = task.importance .. viewers.styles_color_discreet(" on " .. task.lastdate)
    		return { importance , task.phab, task.status, task.title, } -- task.sort, task.shortext }
    	end -- function tab_view.form_one_case(task)
    	t = t .. "<br>Used colors: "
    	.. viewers.ta("ToCreate, Declined, Invalid", viewers.usual_color("task to create or activate", "discreet") )
    	.. viewers.ta("Open, Assigned, Gerrit", viewers.usual_color("task in way to Resolved", "normal") )
    	.. viewers.ta("Resolved", viewers.usual_color("task already Resolved", "invoke") )
    	.. viewers.ta("Other", viewers.usual_color("other tasks or track objects", "discreet") )
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "activity.phabricator_tasks_report") -- Restore global configurations after eventual changes.
    	return t
    end -- function activity.phabricator_tasks_report(t, short)
    
    function activity.rough_delay_timestamps(stamp1, stamp2) -- Rough delay between two time stamps, like 31.
    	local delay, years, months, days = 0, 0, 0, 0
    	if (type(stamp1) ~= "string") or (type(stamp2) ~= "string") then return delay end
    	local y1 = tonumber(string.sub(stamp1,1,4))
    	local y2 = tonumber(string.sub(stamp2,1,4))
    	if y1 and y2 then years = y2 - y1 end
    	local m1 = tonumber(string.sub(stamp1,5,6))
    	local m2 = tonumber(string.sub(stamp2,5,6))
    	if m1 and m2 then months = m2 - m1 end
    	local d1 = tonumber(string.sub(stamp1,7,8))
    	local d2 = tonumber(string.sub(stamp2,7,8))
    	if d1 and d2 then days = d2 - d1 end
    	delay = years * 365 + months * 30 + days
    	return delay
    end
    
    function activity.rough_date_days(stamp1) -- Rough date days of a time stamp, like 736447.
    	local date_days, years, months, days = 0, 0, 0, 0
    	if (type(stamp1) ~= "string") then return delay end
    	local y1 = tonumber(string.sub(stamp1,1,4)) or 2001
    	local m1 = tonumber(string.sub(stamp1,5,6)) or 1
    	local d1 = tonumber(string.sub(stamp1,7,8)) or 1
    	years = y1 * 365
    	months = m1 * 30
    	days = d1
    	date_days = years + months + days
    	return date_days, y1, m1, d1, years, months, days
    end
    
    function activity.rough_days_timestamp(date_days) -- Rough time stamp from date days, like "20170806".
    	local timestamp = "no timestamp"
    	if (type(date_days) ~= "number") then return timestamp end
    	local year = math.floor(date_days / 365)
    	local day = date_days - (year * 365)
    	local month = math.floor(day / 30)
    	local day = day - (month * 30)
    	local yyyy = string.sub( ("0000" .. tostring(year) ), -4, -1)
    	local mm = string.sub( ("0000" .. tostring(month) ), -2, -1)
    	local dd = string.sub( ("0000" .. tostring(day) ), -2, -1)
    	timestamp = yyyy .. mm .. dd
    	return timestamp
    end
    
    function activity.MW_Versions_report(t) -- Reports versions of MediaWiki for 3 months.
    	local memo = viewers.save_configs("activity.MW_Versions_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>activity.MW_Versions_report()</b> Monitor MediaWiki versions."
    --	t = t .. activity.MediaWiki_Versions_code(versions.MediaWiki_Versions, ">") -- First on begin, Last on end
    --	t = t .. activity.MediaWiki_Versions_code(versions.MediaWiki_Versions, "<") -- First on end, Last on begin
    	table.sort(versions.MediaWiki_Versions, function (a, b) return (a["verstime"] > b["verstime"]) end )
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = versions.MediaWiki_Versions,
    		title_memo = "activity_MW_Versions_report_title", -- "<b>activity.MW_Versions_report()</b> Monitor MediaWiki versions.",
    		headers = "	 verstime;		versid;			site;		seen_time ",
    	--	local case = { version.MW, version.versid, version.site, version.seen_time, }
    		headers_class = "wikitable alternative center sortable",
    		rowGroup = {},
    		--	track_on = true,
    	}
    --	from MediaWiki	1.30.0-wmf.4 (3248a17)	22:41, 7 June 2017
    --	See ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 heures de décalage) = 1977-04-22T06:00:00Z local time
    	function tab_view.form_one_case(version, all_cases) -- Convert a case from test_group to rowGroup.
    		local example =
    	{ site = "fr.wikisource", verstime = "2017-12-15T23:35:09", versid = "1.31.0-wmf.16 (a31d45c)", seen_time = "2018-01-12T07:43:00",
    		task = "T155624", title = "In wikisource/Spécial:Version:wmf.15 (0953700) but Central module mw = 1.31.0-wmf.16 (a31d45c) seen by Rical.", }
    		if version.task then version.versid = version.versid .. "<br/>" .. viewers.phab_task(version.task, version.task) end
    		if version.title then version.seen_time = version.seen_time .. "<br/>" .. version.title end
    		return { version.site, version.verstime, version.versid, version.seen_time, }
    		--	function versions.detect_MediaWiki_changes() display only 3 last months
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	t = t .. "\n* Counts of MW_Versions_report: "
    	t = t .. viewers.ta("#test_group", lua_table.level_count(tab_view.test_group) ) .. viewers.ta("#rowGroup", lua_table.level_count(tab_view.rowGroup) )
    	local list, count_done, level, split = lua_table.level_list(tab_view.rowGroup, "string", "MediaWiki", 3)
    	local list, count_now, level, split = lua_table.level_list(tab_view.rowGroup, "string", "wikisource", 3) -- function lua_table.level_list(
    	local list, count_later, level, split = lua_table.level_list(tab_view.rowGroup, "string", "2017-08", 1) -- subtasks S170813lll
    	t = t .. viewers.ta("MW_Versions MediaWiki count_done", count_done) .. viewers.ta("MW_Versions wikisource count_now", count_now) .. viewers.ta("MW_Versions 2017-08 count_later", count_later)
    --	Counts of selected and sorted sub-tasks: , #test_group = 52 , #rowGroup = 0
    --	{ "20170529", "20170530", "done", "Rical", "S170530mwv", "versions.MediaWiki_Versions in Module:MediaWikiVersions for activity.MW_Versions_report()", },
    	viewers.restore_configs(memo, "activity.MW_Versions_report") -- Restore global configurations after eventual changes.
    	return t
    end -- t = activity.MW_Versions_report(t)
    
    function activity.MediaWiki_Versions_code(MediaWiki_Versions, sort) -- Re_form the Lua code of versions.MediaWiki_Versions{}.
    	local MediaWiki_Versions = MediaWiki_Versions or versions.MediaWiki_Versions
    	if (type(MediaWiki_Versions) ~= "table") then MediaWiki_Versions = {} end
    	local MediaWiki_Versions_example = { -- Example only
    		{ site = "fr.wikisource", verstime = "2017-05-11T00:48:00", versid = "1.29.0-wmf.21 (d6c07d1)", seen_time = "2017-05-11T00:48:00-00:00",
    			task = "T165000",	title = "The version date of MW 1.29.0-wmf.21 (d6c07d1) is in the future !",
    			report = "Rical: Schedule in https://www.MediaWiki.org/wiki/MediaWiki_1.29/Roadmap", },
    	}
    	-- alphabetic sort vesions on verstime
    	local sort = sort
    	if (type(sort) ~= "string") then sort = activity.MediaWiki_Versions_sort end
    	if sort == ">" then table.sort(MediaWiki_Versions, function (a, b) return (a["verstime"] > b["verstime"]) end ) end -- First on begin, Last on end
    	if sort == "<" then table.sort(MediaWiki_Versions, function (a, b) return (a["verstime"] < b["verstime"]) end ) end -- First on end, Last on begin
    	local code = '\n* activity.MediaWiki_Versions_sort = "' .. sort .. '"'
    	code = code .. "\n* versions.MediaWiki_Versions = {"
    	for i, version in ipairs(MediaWiki_Versions) do
    --	See ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 heures de décalage) = 1977-04-22T06:00:00Z local time
    		code = code .. '<br/>	{ site = "' .. version.site
    		code = code .. '", verstime = "' .. version.verstime
    		code = code .. '", versid = "' .. version.versid
    		code = code .. '", seen_time = "' .. version.seen_time
    		if (type(version.task) == "string") then code = code .. '", task = "' .. version.task end
    		if (type(version.title) == "string") then code = code .. '", title = "' .. version.title end
    		if (type(version.report) == "string") then code = code .. '", report = "' .. version.report end
    		code = code .. '", },' -- end of line
    	end
    	code = code .. "<br/>}<br/>"
    	return code
    end -- t = t .. activity.MediaWiki_Versions_code(MediaWiki_Versions, sort)
    
    function activity.extract_MW_Versions() -- Extract MediaWiki versions from the page.
    	local memo = viewers.save_configs("activity.extract_MW_Versions") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>activity.extract_MW_Versions()</b> Report the current state of subtasks the current state of subtasks the current state of subtasks."
    	local actual_title = mw.title.getCurrentTitle() -- Returns the title object for the current page.
    	local actual_content = actual_title:getContent() -- Returns the (unparsed) content of the page, or nil if there is no page. The page will be recorded as a transclusion.
    	local i = string.find(actual_content, "Central Normal mode example")
    	if i then t = t .. "\n* " .. string.sub(actual_content, i, i + 222) end
    	viewers.restore_configs(memo, "activity.extract_MW_Versions") -- Restore global configurations after eventual changes.
    	return t
    end -- t = activity.extract_MW_Versions() -- Extract MediaWiki versions from the page.
    
    function central_library.binded_in(object, name) -- Detects if the object is binded in _G space or in package.loaded.
    	local binded_in = "xx"
    	if _G[name] == object then binded_in = "_G" end
    	if package.loaded[name] == object then binded_in = "LD" end
    	return binded_in
    --	20161202 18:25 See example https://fr.wikisource.org/wiki/Module:Phab.TestpackG : detect "in " "_G" or package.loaded
    end -- binded_in = central_library.binded_in(object, name)
    
    function central_library.new(name, library, options) -- Installs a library in package.loaded. The new library must be a Lua table.
    	-- Installs only a table as a new library.
    	-- RunOnce : Do not repeat this function to not disturb subsequent processes.
    	-- A Sribunto library can be a table, a string or a function, not a nil.
    	-- Modules can only install libraries in tables.
    	options = options or {}
    	options.err = ""
    	options.name = options.name or name
    	options.library = options.library or library
    	if (type(options.library) == "table") then
    		options.library.libname = options.name
    	elseif (type(options.library) ~= "table") then
    		options.err = "library~=table"
    		return library
    	end
    	if (type(options.name) ~= "string") then return options.library end
    	local object = library
    	local php = nil
    	function object.setupInterface(options)
    		-- Remove setup function
    		if options.library then options.library.setupInterface = nil end
    		-- Copy the PHP callbacks to a local variable, and remove the global
    		php = mw_interface
    		mw_interface = nil
    		-- Do any other setup here
    		-- Install into the mw global
    		mw = mw or {}
    		mw.ext = mw.ext or {}
    		mw.ext[options.name] = options.library
    		-- Indicate that we're loaded
    		package.loaded[options.name] = options.library
    		options.err = ""
    	end
    	object = object.setupInterface(options)
    	central_library.i18n_libraries_list = central_library.i18n_libraries_list or {} -- Build a list of central libraries
    	central_library.i18n_libraries_list[options.name] = object
    	options.binded_in = central_library.binded_in(object, options.name)
    	return package.loaded[options.name], options.err
    end -- return object, err = function central_library.new(name, library, options)
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    --	The Library:datas imports datas of Wikidata from mw.wikibase
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    --	datas = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    
    datas.default_item = datas.default_item or "Q307" -- Keep Galilée (Q307)
    
    datas.i18n = {} -- Translations for datas library
    datas.i18n.br = {
    --	Pour traduire, les langues de référence sont l'anglais et le français.
    --	Pour traduire, ne traduisez pas des parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	-- Wikidata
    	datas_Wikidata_header					= "Données : ",
    	datas_known_Datas_header				= "Données connues : ",
    	datas_sougth_Datas_header				= "Données souhaitées : ",
    	datas_needed_Datas_header				= "Données nécessaires : ",
    	datas_Wikidata_wikibase_err				= "Erreur : Wikibase n'est pas disponible.",
    	datas_Wikidata_getEntity_err			= "Erreur : getEntity Wikidata n'est pas disponible.",
    	datas_Wikidata_getEntityObject_err		= "Erreur : L'élément <b>%1</b> de Wikidata n'est pas trouvé.",
    	datas_Wikidata_property_err				= "Erreur : La propriété <b>%1</b> de Wikidata n'est pas trouvée.",
    	datas_Wikidata_error_err				= "Erreur Wikidata : <b>%1</b> ",
    --	datas_Wikidata_cat_err					= "modes_no_source_arguments_cat",
    	datas_Wikidata_cat_err					= "Module with internal error",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Données de Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata pour une autre page :",
    	datas_Wikidata_details_test_title		= "Tests et données importées de Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Test de Wikidata accès arbitraire",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata pour un titre : ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata propriétés de temps pour plus de détails",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Partager des DATA entre modules en Special:PageData",
    	datas_update_Special_PageData_header	= "site; temps de version; identificateur de version; heure de vue",
    	datas_get_item_report_title				= "datas.get_item_report() Rapporte les données de mw.wikibase pour la page ou tout autre élément.",
    	-- Messages et erreurs divers
    	datas_no_args_Wikidata_err				= "Erreur interne : Module sans table d'arguments Wikidata.",
    	datas_sources_of_datas					= "Informations de : /Wikidata, /modèle ou module, /autres, /warning, /erreur",
    } -- datas.i18n.br
    datas.i18n.de = {
    --	Zum Übersetzen sind die Referenzsprachen Englisch und Französisch.
    --	Übersetze keine Teile wie diese: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	datas_Wikidata_header					= "Daten: ",
    	datas_known_Datas_header				= "Bekannte Daten: ",
    	datas_sougth_Datas_header				= "Gewünschte Daten: ",
    	datas_needed_Datas_header				= "Daten benötigt: ",
    	datas_Wikidata_wikibase_err				= "Fehler: Wikibase ist nicht verfügbar.",
    	datas_Wikidata_getEntity_err			= "Fehler: getEntity Wikidata ist nicht verfügbar.",
    	datas_Wikidata_getEntityObject_err		= "Fehler: Der Eintrag <b>%1</b> von Wikidata wurde nicht gefunden.",
    	datas_Wikidata_property_err				= "Fehler: Die Wikidata <b>%1</b> Eigenschaft wurde nicht gefunden.",
    	datas_Wikidata_error_err				= "Wikidata-Fehler: <b>%1</b> ",
    --	datas_Wikidata_cat_err					= "modes_no_source_arguments_cat",
    	datas_Wikidata_cat_err					= "Modul mit internem Fehler",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Wikidata daten',
    	datas_Wikidata_any_page_title			= "Wikidata für eine andere Seite:",
    	datas_Wikidata_details_test_title		= "Tests und Daten, die aus Wikidata importiert wurden",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Wikidata Test beliebiger Zugriff",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata für einen Titel: ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata Zeiteigenschaften für weitere Details",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Partager des DATA entre modules en Special:PageData",
    	datas_update_Special_PageData_header	= "Ort; Versionszeit; Versionskennung; Stunde der Sicht",
    	datas_get_item_report_title				= "datas.get_item_report() Gibt mw.wikibase-Daten für die Seite oder einen anderen Artikel aus.",
    	-- Verschiedene Nachrichten und Fehler
    	datas_no_args_Wikidata_err				= "Interner Fehler: Modul ohne Wikidata-Argumenttabelle.",
    	datas_sources_of_datas					= "Informationen von: / Wikidata, / Modell oder Modul, / andere, / Warnung, / Fehler",
    } -- datas.i18n.de
    datas.i18n.en = {
    --	To translate, referral languages are English and French.
    --	To translate, do not translate parts like these: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	args_known_country						= "England", -- English
    	args_known_flag							= "Flag_of_England.svg", -- English
    	args_known_monument						= "St_Pauls_aerial_%28cropped%29.jpg", -- English St Paul's Cathedral
    	args_known_town							= "London", -- English
    	datas_Wikidata_header					= "Datas: ",
    	datas_known_Datas_header				= "Known datas: ",
    	datas_sougth_Datas_header				= "Sougth datas: ",
    	datas_needed_Datas_header				= "Needed datas: ",
    	datas_Wikidata_wikibase_err				= "Error: Wikibase is not available.",
    	datas_Wikidata_getEntity_err			= "Error: getEntity Wikidata is not available.",
    	datas_Wikidata_getEntityObject_err		= "Error: Element Wikidata <b>%1</b> is not found.",
    	datas_Wikidata_property_err				= "Error: Wikidata property <b>%1</b> is not found.",
    	datas_Wikidata_error_err				= "Error Wikidata: <b>%1</b> ",
    --	datas_Wikidata_cat_err					= "Error Wikidata",
    	datas_Wikidata_cat_err					= "Module with internal error",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Datas from Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata for any page:",
    	datas_Wikidata_details_test_title		= "Tests and imported datas from Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Test of Wikidata arbitrary access",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata for Title: ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata time properties for more details",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Share DATAS between modules in Special:PageData",
    	datas_update_Special_PageData_header	= "site; version time; version identifier; seen hour",
    	datas_get_item_report_title				= "datas.get_item_report() Reports datas from mw.wikibase for the page or any other item.",
    	-- Miscellaneous warnings and errors
    	datas_no_args_Wikidata_err				= "Error: Module without Wikidata arguments table.",
    	datas_sources_of_datas					= "Informations from: /Wikidata, /template or module, /other, /warning, /error",
    } -- datas.i18n.en
    datas.i18n.es = {
    --	Para traducir, los idiomas de referencia son inglés y francés.
    --	Para traducir, no traduzca partes como estas: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	-- Wikidata
    	args_known_country						= "España", -- Spanish
    	args_known_flag							= "Flag_of_Spain.svg", -- Flag of Spain
    	args_known_monument						= "MADRID_100206_UDCI_023.jpg", -- Puerta del Sol
    	args_known_town							= "Madrid", -- Capital city
    	datas_Wikidata_header					= "Datos: ",
    	datas_known_Datas_header				= "Datos conocidas: ",
    	datas_sougth_Datas_header				= "Datos deseados: ",
    	datas_needed_Datas_header				= "Datos necesarios: ",
    	datas_Wikidata_wikibase_err				= "Error: Wikibase no está disponible.",
    	datas_Wikidata_getEntity_err			= "Error: getEntity Wikidata no está disponible.",
    	datas_Wikidata_getEntityObject_err		= "Error: Elemento <b>%1</b> de Wikidata no se encuentra.",
    	datas_Wikidata_property_err				= "Error: La propiedad <b>%1</b> de Wikidata no se encuentra.",
    	datas_Wikidata_error_err				= "Error Wikidata : <b>%1</b> ",
    	datas_Wikidata_cat_err					= "Módulo con error interno",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Datos de Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata para cualquier página:",
    	datas_Wikidata_details_test_title		= "Pruebas y datos importados de Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Prueba de Wikidata acceso arbitrario",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata por título: ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata propiedades de tiempo para más detalles",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Compartir DATOS entre módulos en Special:PageData",
    	datas_update_Special_PageData_header	= "sitio; tiempo de versión; identificador de versión; tiempo visto",
    	datas_get_item_report_title				= "datas.get_item_report() Informes de datos de mw.wikibase para la página o cualquier otro elemento.",
    	-- Diversos mensajes y errores
    	datas_no_args_Wikidata_err				= "Error: Módulo sin argumentos Wikidata tabla.",
    	datas_sources_of_datas					= "Informaciones de: /Wikidata, /template o module, /other, /warning, /error",
    } -- datas.i18n.es
    datas.i18n.fr = {
    --	Pour traduire, les langues de référence sont l'anglais et le français.
    --	Pour traduire, ne traduisez pas des parties comme celles-ci : <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	-- Wikidata
    	args_known_country						= "France", -- French
    	args_known_flag							= "Flag_of_France.svg.png", -- French
    	args_known_monument						= "Tour Eiffel", -- French
    	args_known_town							= "Paris", -- French
    	datas_Wikidata_header					= "Données : ",
    	datas_known_Datas_header				= "Données connues : ",
    	datas_sougth_Datas_header				= "Données souhaitées : ",
    	datas_needed_Datas_header				= "Données nécessaires : ",
    	datas_Wikidata_wikibase_err				= "Erreur : Wikibase n'est pas disponible.",
    	datas_Wikidata_getEntity_err			= "Erreur : getEntity Wikidata n'est pas disponible.",
    	datas_Wikidata_getEntityObject_err		= "Erreur : L'élément <b>%1</b> de Wikidata n'est pas trouvé.",
    	datas_Wikidata_property_err				= "Erreur : La propriété <b>%1</b> de Wikidata n'est pas trouvée.",
    	datas_Wikidata_error_err				= "Erreur Wikidata : <b>%1</b> ",
    --	datas_Wikidata_cat_err					= "modes_no_source_arguments_cat",
    	datas_Wikidata_cat_err					= "Module with internal error",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Données de Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata pour une autre page :",
    	datas_Wikidata_details_test_title		= "Tests et données importées de Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Test de Wikidata accès arbitraire",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata pour un titre : ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata propriétés de temps pour plus de détails",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Partager des DATA entre modules en Special:PageData",
    	datas_update_Special_PageData_header	= "site; temps de version; identificateur de version; heure de vue",
    	datas_get_item_report_title				= "datas.get_item_report() Rapporte les données de mw.wikibase pour la page ou tout autre élément.",
    	-- Messages et erreurs divers
    	datas_no_args_Wikidata_err				= "Erreur interne : Module sans table d'arguments Wikidata.",
    	datas_sources_of_datas					= "Informations de : /Wikidata, /modèle ou module, /autres, /warning, /erreur",
    } -- datas.i18n.fr
    datas.i18n.hu = {
    --	Zum Übersetzen sind die Referenzsprachen Englisch und Französisch.
    --	Übersetzen Sie keine Teile wie diese: <b>%1</b> ; <b>%1</b> = <b>%2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.
    	datas_Wikidata_header					= "Adat: ",
    	datas_known_Datas_header				= "Ismert adatok: ",
    	datas_sougth_Datas_header				= "Kívánt adatokat: ",
    	datas_needed_Datas_header				= "Szükséges adatok: ",
    	datas_Wikidata_getEntity_err			= "Hiba: a getEntity Wikidata nem érhető el.",
    	datas_Wikidata_getEntityObject_err		= "Lỗi: Không tìm thấy mục <b>%1</b> để Wikidata.",
    	datas_Wikidata_property_err				= "Erreur : La propriété <b>%1</b> de Wikidata n'est pas trouvée.",
    	datas_Wikidata_error_err				= "Lỗi Wikidata : <b>%1</b> ",
    	datas_Wikidata_cat_err					= "Mô-đun có lỗi nội bộ",
    	datas_structured_data_txt				= 'Dữ liệu Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata cho một trang khác:",
    	datas_Wikidata_details_test_title		= "Kiểm tra và dữ liệu được nhập từ Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Wikidata kiểm tra truy cập tùy ý",
    
    	datas_Wikidata_arbitrary_access_text	= "Wikidata cho một tiêu đề : ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Wikidata thuộc tính thời gian để biết thêm chi tiết",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Megosztja a DATA-t a speciális modulok között: Special:PageData",
    	datas_update_Special_PageData_header	= "webhely; verzióidő; verzióazonosító; látott órát",
    
    	datas_get_item_report_title				= "datas.get_item_report() Rapporte les données de mw.wikibase pour la page ou tout autre élément.",
    	-- Messages et erreurs divers
    	datas_no_args_Wikidata_err				= "Erreur interne : Module sans table d'arguments Wikidata.",
    	datas_sources_of_datas					= "Informations de : /Wikidata, /modèle ou module, /autres, /warning, /erreur",
    } -- datas.i18n.hu
    datas.i18n.vi = {
    --	Để dịch, các ngôn ngữ giới thiệu là tiếng Anh và tiếng Pháp.
    --	Để dịch, không dịch các phần như thế này: <b>%1</b> ; <b>%2</b> = <b>%3</b> (<b>%4</b>) ; <code>Q535</code> ; <br/> ; <br/> ; \n* ; _G.
    	datas_Wikidata_header					= "Dữ liệu: ",
    	datas_known_Datas_header				= "Dữ liệu nổi tiếng: ",
    	datas_sougth_Datas_header				= "Dữ liệu mong muốn: ",
    	datas_needed_Datas_header				= "Dữ liệu cần thiết : ",
    	datas_Wikidata_wikibase_err				= "Lỗi: Wikibase không khả dụng.",
    	datas_Wikidata_getEntity_err			= "Lỗi: getEntity Wikidata không khả dụng.",
    	datas_Wikidata_getEntityObject_err		= "Lỗi: Không tìm thấy mục <b>%1</b> để Wikidata.",
    	datas_Wikidata_property_err				= "Lỗi: Không tìm thấy thuộc tính Wikidata <b>%1</b>.",
    	datas_Wikidata_error_err				= "Lỗi Wikidata: <b>%1</b> ",
    --	datas_Wikidata_cat_err					= "modes_no_source_arguments_cat",
    	datas_Wikidata_cat_err					= "Mô-đun có lỗi nội bộ",	 -- modes_no_source_arguments_cat
    	datas_structured_data_txt				= 'Dữ liệu Wikidata',
    	datas_Wikidata_any_page_title			= "Wikidata cho một trang khác:",
    	datas_Wikidata_details_test_title		= "Các bài kiểm tra và dữ liệu được nhập từ Wikidata",
    	datas_Wikidata_arbitrary_tests_title	= "datas.get_item() Wikidata kiểm tra truy cập tùy ý",
    	datas_Wikidata_arbitrary_access_text	= "Wikidata cho một tiêu đề: ",
    	datas_Wikidata_time_details_title		= "datas.Wikidata_time_details{} Các thuộc tính thời gian để Wikidata để biết thêm chi tiết",
    	datas_update_Special_PageData_title		= "datas.update_PageData() Chia sẻ DATA giữa các mô-đun trong Special:PageData",
    	datas_update_Special_PageData_header	= "địa điểm; thời gian phiên bản; định danh phiên bản; thấy giờ",
    	datas_get_item_report_title				= "datas.get_item_report() Báo cáo dữ liệu mw.wikibase cho trang hoặc bất kỳ mục nào khác.",
    	-- Các thông báo và lỗi khác nhau
    	datas_no_args_Wikidata_err				= "Lỗi nội bộ: Mô-đun không có bảng đối số Wikidata.",
    	datas_sources_of_datas					= "Thông tin từ: /Wikidata, /mô hình hoặc mô-đun, /người khác, /cảnh báo, /lỗi",
    } -- datas.i18n.vi
    
    function datas.available_props_report(t) -- Reports available datas properties
    	local memo = viewers.save_configs("datas.available_props_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>datas.available_props_report(t)</b> Reports availables datas properties.\n* "
    	local i = 0
    --	t = t .. "\n* Guideline for this stat : Count lists of translations by languages and libraries, then convert in a 2D table, then format and report them."
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {...}
    	for key, argmt in pairs(args_known) do -- For all known parameters
    		if type(argmt.prop) == "string" then
    			i = i + 1 ; t = t .. viewers.ta(argmt.keyword, argmt.prop)
    		end
    	end
    	t = t .. viewers.ta("\n* Count of available datas properties: ", tostring(i) )
    	viewers.restore_configs(memo, "datas.available_props_report") -- Restore global configurations after eventual changes.
    	return t
    end -- t = t .. datas.available_props_report(t) -- Reports available datas properties drop_box.new(
    --	res = res .. drop_box.new(selector, "datas.available_props_report(t) Reports availables datas properties **", datas.available_props_report)
    
    function datas.getDateFromTimeStatement(statement, field)
    	local struct = {
    		year = nil,
    		century = nil,
    		text = nil,
    		precision = 0
    	}
    	local snak = statement.mainsnak
    	if snak.snaktype == 'novalue' then
    		return struct
    	end
    	if snak.snaktype == 'somevalue' then
    		struct.text = '??'
    		return struct
    	end
    	struct = parseWbTime(snak.datavalue.value)
    	local prefix = ''
    	if struct.precision == 8 then
    		prefix = 'vers '
    	end
    	--Extract circa
    	if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then
    		for _,qualifier in pairs(statement.qualifiers.P1480) do
    			if qualifier.datavalue.value.id == 'Q5727902' then
    				prefix = 'circa '
    				struct.precision = 8 --TODO: hacky
    			end
    		end
    	end
    	--Use before and after if precision <= century
    	if statement.qualifiers ~= nil and struct.precision <= 7 then
    		if statement.qualifiers.P1319 ~= nil then
    			for _,qualifier in pairs(statement.qualifiers.P1319) do
    				struct = parseWbTime(qualifier.datavalue.value)
    				prefix = 'après '
    				struct.precision = 8 --TODO: hacky
    			end
    		elseif statement.qualifiers.P1326 ~= nil then
    			for _,qualifier in pairs(statement.qualifiers.P1326) do
    				struct = parseWbTime(qualifier.datavalue.value)
    				prefix = 'avant '
    				struct.precision = 8 --TODO: hacky
    			end
    		elseif statement.qualifiers.P1317 ~= nil then
    			for _,qualifier in pairs(statement.qualifiers.P1317) do
    				struct = parseWbTime(qualifier.datavalue.value)
    				prefix = 'floruit '
    				struct.precision = 8 --TODO: hacky
    			end
    		end
    	end
    	--Create text
    	if struct.precision >= 9 then
    		struct.text = prefix .. getTextForYear(struct.year)
    	elseif struct.precision == 8 then
    		struct.text = prefix .. getTextForYear(struct.year)
    	elseif struct.precision == 7 then
    		struct.text = prefix .. getTextForCentury(struct.century, true)
    	else
    		struct.text = errorMessage('La date de ' .. field .. ' a une précision trop faible sur Wikidata')
    	end
    	return struct
    end
    
    datas.track_val = datas.track_val or ""
    function datas.tv(line, prop, what, val) -- track a property in datas.get_item
    	datas.track_val = datas.track_val or "" -- birthyear=P569
    	if prop == "P569" then
    		local line = "L" .. tostring(line)
    		local prop = tostring(prop)
    		local what = tostring(what)
    		local val = tostring(val)
    		datas.track_val = datas.track_val .. viewers.ta(line .. "-" .. prop .. ":" .. what, val)
    	end
    	return datas.track_val
    end -- datas.track_val = datas.tv(line, prop, what, val)
    
    function datas.get_uri(prop, better, lang) -- Get props.uri for the page.
    	local mwuri, uri = mw.uri.new(), "-" -- Server mw.uri.new for path like = /wiki/Utilisateur:Rical/Nelson_Mandela
    	local sub_parts = mw.text.split(mwuri.path, '/') ; for k, part in pairs(sub_parts) do uri = part end -- last text after /
    	uri = string.gsub(uri, "_", " ") ; return uri
    end
    
    function datas.get_image(prop, QITEM, lang) -- T185557 Gets the sought image name for the page, or some others for galeries.
    	-- see phabtask T185557 Authored By Rical on 20180123 : Create the easy function mw.wikibase.property('P21', 'Q8023', 'en')
    	if type(prop) ~= "string" then prop = "P18" end
    	if (prop == "image") then prop = "P18" end
    	local image = image or datas.props.image or datas.props.P18 or "Victor Hugo.jpg" or (datas.get_uri() .. ".jpg")
    	return image -- image = image or prop or "Victor Hugo.jpg" --
    end
    
    function datas.property(argmt) -- Get datas from mwwikibase for one property of the page.
    	argmt = mw.clone(argmt) -- avoid any interaction with other properties.
    	datas.QITEM = mw.wikibase.getEntityIdForCurrentPage() -- use props.QITEM Returns the Item id as string, like "Q42"
    	local QITEM = datas.QITEM or datas.default_item or "Q34743" -- Rudyard Kipling
    	datas.item = mw.wikibase.getEntity(QITEM)
    	local loc = {}
    	local label = nil
    	local val = nil
    	if argmt.prop then -- Admit any type of keyword and prop.
    		argmt.keyword = argmt.keyword or argmt.key or argmt.prop
    		argmt.prop = argmt.prop -- Get datas from mwwikibase for one property of the page.
    		if		argmt.prop == "QITEM"			then val = mw.wikibase.getEntityIdForCurrentPage() -- use props.QITEM Returns the Item id as string, like "Q42"
    		elseif	argmt.prop == "label"			then val = datas.item:getLabel(QITEM) ; label = label or val -- use props.label Returns a string, like "Berlin" with 'de'
    		elseif	argmt.prop == "sitelink"		then val = datas.item:getSitelink() -- use props.sitelink like Author:Aristotel
    		elseif	argmt.prop == "labelwithlang"	then val = mw.wikibase.entity:getLabelWithLang() -- use props.labelwithlang	 -- Returns a string like "Berlin" and a language like
    		elseif	argmt.prop == "description"		then val = mw.wikibase.description(QITEM) -- use props.description	-- ric : Description of the QITEM page
    		elseif	argmt.prop == "labelcontent"	then val = mw.wikibase.getLabelByLang(QITEM, langs.content_lang) ; label = label or val -- Returns the content_lang label of the item
    		elseif	argmt.prop == "labelpage"		then val = mw.wikibase.getLabelByLang(QITEM, langs.page_lang) ; label = label or val -- Returns the page_lang label of the item
    		elseif	argmt.prop == "labeluser"		then val = mw.wikibase.getLabelByLang(QITEM, langs.user_lang or "en") ; label = label or val -- Returns the user_lang label of the item
    		else -- ric (p.box_read)
    			loc.formatPropertyValues = datas.item:formatPropertyValues( argmt.prop ) -- like "P123"
    			-- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" }
    			if loc.wd_RANK_TRUTH then
    				loc.formatPropertyValues = datas.item:formatPropertyValues(	 argmt, { loc.wd_RANK_TRUTH } )
    			end
    			if loc.wd_claimRanks then
    				loc.formatPropertyValues = datas.item:formatPropertyValues(	 argmt, { loc.wd_claimRanks } )
    			end
    			val = loc.formatPropertyValues.value
    		end
    		val = tostring(val)
    		if argmt.format == "year" then val = mw.ustring.sub( val, -4, -1 ) end
    		val = tostring(val)
    		argmt.val = val
    	end --function modes.get_args(
    	argmt.label = label or argmt.label or argmt.labeluser or argmt.labelcontent or argmt.labelpage or argmt.labelbylang
    	argmt = mw.clone(argmt) -- avoid any interaction with other properties.
    	return argmt
    end -- argmt = datas.property(argmt) -- Get datas from mwwikibase for one property of the page.
    
    function datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page.
    --	from 2016-08-16 ModuleCentral 3a lua_table.to_list.lua
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {...}
    	local t = "\n* <b>datas.get_item(args_known, QITEM)</b>: Get datas from mw.wikibase for the page."
    	local Title, Label, prop, lang, description, val, label, adr, proplabel
    	local QITEM = QITEM or mw.wikibase.getEntityIdForCurrentPage() or datas.default_item or kipling
    	datas.QITEM = QITEM
    	datas.item = mw.wikibase.getEntity(datas.QITEM or "Q34743") -- Rudyard Kipling
    	local props = {} -- All properties form args_known with argmt.prop.
    	local prop = {} -- to collect properties
    	local loc = {} -- local values
    	for key, argmt in pairs(args_known) do -- For all known parameters
    		if type(argmt) == "table" then
    			argmt.key = key
    			argmt.syn = argmt.syn or 0
    			argmt = datas.property(argmt) -- Get datas from mwwikibase for one property of the page. function datas.property(
    			if argmt.keyword == "QITEM" then argmt.val = QITEM end
    			if argmt.prop then -- Admit any type of keyword and prop.
    				props[argmt.keyword] = mw.clone(argmt)
    				prop[argmt.keyword] = argmt.val -- ric (p.box_read)
    			end
    		end
    	end
    	prop.countall = tostring( lua_table.level_count(prop) )
    	props.countall = tostring( lua_table.level_count(props) )
    	datas.props = props
    	datas.prop = prop
    	return prop, props
    end -- local prop, props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page.
    
    function datas.get_item_report(t) -- datas.get_item() Report datas from mw.wikibase for the page **
    	local memo = viewers.save_configs("datas.get_item_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>datas.get_item_report(t)</b>: Report datas from mw.wikibase for the page **"
    	local args_known = args_known or modes.args_known or p.args_known or {} -- modes.args_known = { -- p.args_known = { -- }
    	local prop, props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page. ric
    	local countprops = tostring( lua_table.level_count(props) ) -- do not follow one_prop structure
    	local countallprops = tostring( lua_table.level_count(props) ) -- do not follow one_prop structure
    	t = t .. viewers.ta("\n* countprops", countprops) .. viewers.ta("\n* countallprops", countallprops)
    	local sortprops = {} -- to sort properties in alphabetic order
    	for key, val in pairs(props) do -- from list all fond datas
    	--	t = t .. "\n* get_item: " .. viewers.ta("key", key) .. viewers.ta("val", val)
    		table.insert(sortprops, props[key])
    	end
    	table.sort(sortprops, function (a, b) return ( tostring(a.keyword or a.prop) < tostring(b.keyword or b.prop)) end ) -- alphabetic sort of properties
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = sortprops, -- Use default cases.
    		rowGroup = {},
    		title_memo = "datas_get_item_report_title",
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    		return { case.key, case.val, case.typ, case.need, case.keyword, case.syn, case.prop, case.format, } end,
    		headers =	"key;		val;	typ;		need;		keyword;	syn;		prop;	format",
    	}
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	t = t .. viewers.ta("#test_group", lua_table.level_count(tab_view.test_group) )
    	t = t .. viewers.ta("#rowGroup", lua_table.level_count(tab_view.rowGroup) )
    	t = t .. "\n* <b>datas.get_item_report(t)</b>: end"
    	viewers.restore_configs(memo, "datas.get_item_report") -- Restore global configurations after eventual changes.
    	return t
    end -- local t = datas.get_item_report(t) -- datas.get_item() Report datas from mw.wikibase for the page **
    
    function datas.prot(prop) -- form a string to show a prop value
    	datas.props = datas.props or {}
    	local prop = prop
    	if type(prop) ~= "string"then prop = "prop" end
    	local t = prop
    	if type(prop) == "string" and not string.find(prop, "%s", 1, true) then t = datas.props[prop] or prop end
    	return t
    end
    
    function datas.PageData_to_table(datext) -- Convert a PageData in JSON to a table.
    	return "To do later : datas.PageData_to_table(datext) -- Convert a PageData in JSON to a table."
    end -- local tab = datas.PageData_to_table(datext)
    
    function datas.table_to_PageData(tab) -- Convert a table to JSON for PageData.
    	return datext
    end -- local datext = datas.table_to_PageData(tab)
    
    function datas.update_PageData(t, datext) -- Try to share INFOS between a group of modules in Module:Main/INFOS
    	local memo = viewers.save_configs("datas.update_PageData") -- Save global configuration before eventual changes.
    	local t = t or "\n* datas.update_PageData() Share DATAS between modules in Special:PageData for modules." -- PageData from 20170822
    	local tab = datas.PageData_to_table(datext)
    	local datext = datas.table_to_PageData(tab)
    	local Help_Tabular_DataExample = [=[{
    		"license": "CC0-1.0",
    		"description": {
    			"en": "Some good fruits for you",
    			"es": "Algunas buenas frutas para ti"
    		},
    		"sources": "http://example.com and [[Data]] page",
    		"schema": {
    			"fields": [
    				{ "name": "id", "type": "string", "title": { "en": "Fruit ID", "fr": "ID de fruit" }},
    				{ "name": "count", "type": "number", "title": { "en": "Count" }},
    				{ "name": "liked", "type": "boolean", "title": { "en": "Do I like it?" }},
    				{ "name": "description", "type": "localized", "title": { "en": "Fruit name", "fr": "Nom du fruit" }}
    			]
    		},
    		"data": [
    			[
    				"peaches",
    				100,
    				true,
    				{
    					"en": "Magnificent but a bit artificial sweet peaches",
    					"es": "esto puede estar en español",
    					"fr": "this could be in french"
    				}
    			],
    		]
    	}]=]
    	local lua_content = mw.text.jsonDecode(Help_Tabular_DataExample)
    	local json_content = mw.text.jsonEncode(lua_content)
    	local table_to_code = activity.wikis_names --[[ see activity.wikis_names
    		["b"] = "wikibooks",		["cm"] = "commons",		["meta"] = "meta",		["mw"] = "MediaWiki",
    		["n"] = "wikinews",			["p"] = "wiki",			["q"] = "wikiquote",	["s"] = "wikisource",
    		["species"] = "species",	["t"] = "wiktionary",	["test"] = "test",		["test2"] = "test2",
    		["v"] = "wikiversity",		["w"] = "wikipedia",	["wm"] = "wikimedia",	["y"] = "wikivoyage",
    	} -- activity.wikis_names
    	--]]
    	local table_json = mw.text.jsonEncode(table_to_code)
    	local table_lua = mw.text.jsonDecode(table_json)
    	local final_table = {}
    	for key, val in pairs(table_lua) do final_table[key] = val end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = final_table, -- Use default cases.
    		title_memo = "datas_update_Special_PageData_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)",
    		headers = "key;val",
    		rowGroup = {},
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		return { case.key, case.val }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	t = t .. viewers.ta("#test_group", lua_table.level_count(tab_view.test_group) )
    	t = t .. viewers.ta("#rowGroup", lua_table.level_count(tab_view.rowGroup) )
    	viewers.restore_configs(memo, "datas.update_PageData") -- Restore global configurations after eventual changes.
    	return t
    end -- function datas.update_PageData(t)
    
    function datas.load_data(t, datext) -- Pass data between #invoke's
    	local T67687 = "phabtask : mw.load_data can be used to pass data between #invoke's by reading frame arguments"
    	if false then
    		-- Create the following as Module:LoadData:
    		local p = {}
    		function p.main(frame)
    			return mw.load_data('Module:LoadData/data')[1]
    		end
    		return p
    	end
    	if false then
    		--	Create the following as Module:LoadData/data:
    		return { mw.getCurrentFrame().args[1] }
    	end
    	if false then
    	end
    end -- function datas.load_data(t, datext) -- Pass data between #invoke's
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:events supports events of types erros, warnings and categories.
    --	viewers.save_configs("events.save_configs" memo, tab_view, group ) -- Init a new events group
    --	events.add_err(key, ... ) -- Add an error in the actual table of events.
    --	events.add_cat_group(groupCat, groupList) -- Add some categories in the actual table of events.
    --	events.form(evt) -- Format events types
    --	events.all_categories_test(t) -- test categories
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    --	events = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loadedS
    
    events.i18n = {} -- Translations for Library:events
    events.i18n.br = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "Tester categ_Test : catégories dans quelques langues",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Test: toutes les sortes d'événements (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_add_cat_deprecated				= "Fonction obsolète dans le module principal.",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) sans <b>memo</b> dans le module <b>%1</b>.",
    	events_antiCrash_protect_err			= "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.",
    } -- events.i18n.br
    events.i18n.en = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "categ_Test test : classes in some languages",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Test: all kinds of events (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) without <b>memo</b> in module <b>%1</b>.",
    	events_antiCrash_protect_err			= "The antiCrash() function protects this page against a complete crash due to an internal error: %1.",
    } -- events.i18n.en
    events.i18n.es = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "Prueba categ_Test: clases en algunos lenguajes",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Prueba: todo tipo de eventos (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_add_cat_deprecated				= "Función obsoleto en módulo principal.",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) sin <b>memo</b> en el módulo <b>%1</b>.",
    	events_antiCrash_protect_err			= "La función antiCrash() protege esta página contra un colapso completo debido a un error interna: %1.",
    } -- events.i18n.es
    events.i18n.fr = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "Tester categ_Test : catégories dans quelques langues",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Test: toutes les sortes d'événements (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_add_cat_deprecated				= "Fonction obsolète dans le module principal.",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) sans <b>memo</b> dans le module <b>%1</b>.",
    	events_antiCrash_protect_err			= "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.",
    } -- events.i18n.fr
    events.i18n.hu = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "Tester categ_Test : catégories dans quelques langues",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Test: toutes les sortes d'événements (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_add_cat_deprecated				= "Fonction obsolète dans le module principal.",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) sans <b>memo</b> dans le module <b>%1</b>.",
    	events_antiCrash_protect_err			= "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.",
    } -- events.i18n.hu
    events.i18n.vi = {
    	events_test_tests_title					= "List a table, test with limits:",
    	events_test_resTest_title				= "List a table, test with limits:",
    	events_test_projects_title				= "Test and display tests events for projects",
    	events_test_projects_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_MediaWiki_title				= "Test and display tests events for MediaWiki",
    	events_test_MediaWiki_headers			= "Type;Key;Name test and values;result of the test",
    	events_test_categ_Test_title			= "Tester categ_Test : catégories dans quelques langues",
    	events_all_kinds_tests_title			= "events.all_kinds_test() Test: toutes les sortes d'événements (err, wng, cat)",
    	events_all_kinds_tests_headers			= "typ;key;idargs;result",
    	events_add_cat_deprecated				= "Fonction obsolète dans le module principal.",
    	events_close_without_memo_err			= "viewers.restore_configs(memo, where) sans <b>memo</b> dans le module <b>%1</b>.",
    	events_antiCrash_protect_err			= "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.",
    } -- events.i18n.vi
    
    events.test_group = {}
    events.rowGroup = {}
    events.tab_view = {}
    events.tab_view.test_group = {}
    events.tab_view.rowGroup = {}
    
    function events.add_cat(key, ... ) -- Add a category in the actual table of events.
    	return events.add_record("cat", key, ...) -- Add a error, warning or category in the lists. S170626rev
    end
    
    function events.add_err(key, ... ) -- Add an error in the actual table of events.
    	return events.add_record("err", key, ...) -- Add a error, warning or category in the lists. S170626rev
    end
    
    function events.add_wng(key, ... ) -- Add a warning in the actual table of events.
    	return events.add_record("wng", key, ...) -- Add a error, warning or category in the lists. S170626rev
    end
    
    function events.form_cat(evt, txt, lnk, c, space)
    	local space = space or (mw.site.namespaces.Category.name .. ":")
    	local c = c or evt.ccc or ":"
    	if evt.typ == "cat" then -- Format a category to display or activate
    		evt.content_wkt = viewers.form9content(evt.key, lua_table.to_list( evt.vals ) )
    		evt.page_wkt = viewers.form9page(evt.key, lua_table.to_list( evt.vals ) )
    		evt.user_wkt = viewers.form9user(evt.key, lua_table.to_list( evt.vals ) )
    		return " [[" .. c .. space .. (evt.content_wkt or lnk) .. "|" .. (evt.user_wkt or txt) .. "]] "
    	else
    		return ""
    	end
    end
    
    events.list_all_events = {} -- Table to collect all events types "err", "wng" and "cat".
    
    function events.new(typ, key, ...) -- Initialize and finalize a new event.
    	local evt = {} -- default event
    	if type(typ) == "table" then
    		evt = typ -- Use a predefined event
    	else -- To finalize an existing event.
    		evt.typ = typ
    		evt.key = key
    	end -- Finalize all events
    	evt.typ = evt.typ or typ -- Type of event: err, wng, cat
    	evt.key = evt.key or key -- Translation key, simple or extended by name
    	if type(typ) ~= "string" then typ = "notyp" end -- To debug abnormal type of event
    	if type(key) ~= "string" then key = "nokey" end -- To debug abnormal translation key
    	evt.name = evt.typ or evt.key or "name" -- Translation key, simple or extended by name
    	evt.vals = evt.vals or { ... } -- table of arguments values
    	evt.catview = evt.catview or  ":" -- Default value for eventual use
    	-- Check, yes or no, to form an event, in special cases
    	if		(evt.typ == "cat") then
    		evt.res, evt = events.form( evt ) -- Formats the resulting wikitext, can be re-form later
    	elseif	(evt.typ == "err") then
    		evt.res, evt = events.form( evt ) -- Formats the resulting wikitext, can be re-form later
    	elseif	(evt.typ == "wng") then
    		evt.res, evt = events.form( evt ) -- Formats the resulting wikitext, can be re-form later
    	end
    	return evt
    end -- function events.new(typ, key, ...)
    
    function events.add_new(evt) -- Add a error, warning or category in the lists. S170626rev
    	-- Select  only new events
    	if type(evt) ~= "table" then evt = {} end
    	local new_evt = viewers.form9tests( tostring(evt.key), lua_table.to_list( evt.vals ) )
    	for i, event in pairs(events.list_all_events) do
    		local old_evt = viewers.form9tests( tostring(event.key), lua_table.to_list( event.vals ) )
    		if new_evt == old_evt then new_evt = nil ; break end -- Add only new events. Reject already seen events.
    	end
    --	events.add_wng("modes_auto_val_warning_wng", langs.user_translations[key], val) -- form_result
    	if new_evt then table.insert(events.list_all_events, evt) end
    	return evt
    end -- function events.add_new(typ, ref, ...)
    
    function events.add_record(typ, key, ... ) -- Add a new error, warning or category in a list.
    	--	Guide line: all events are in a single table, including categories, without duplication.
    	--	Guide line: without duplication: events differ if the type, the key or any value of any argument differs.
    	--	Guide line: We can view or categorize categories.
    	local intern_or_use = versions.memo_i18n["en"][key]
    	local evt = events.new(typ, key, ...) -- Initialize and finalize a new event.
    	local evt = events.add_new(evt) -- Add an error, warning or category in the lists. S170626rev
    	local res, evt = events.form(evt, c) -- Format an event as an error, warning or category.
    	return res, evt
    end -- local res, evt = events.add_record(typ, key, ... )
    
    function events.form(evt, c) -- Format an event as an error, warning or category.
    	evt.res = tostring(evt.res) .. "? form " .. viewers.form9tests(".form evt.key=%1, evt.res=%2, ", evt.key, evt.res )
    	local evt = mw.clone(evt) -- do not disturb input event
    	if type(evt) ~= "table" then
    		evt.res = lua_table.rough_view(evt)
    		return evt.res, evt
    	end
    	if (evt.typ ~= "cat") and (evt.typ ~= "wng") and (evt.typ ~= "err") then
    		evt.res = lua_table.rough_view(evt)
    		return evt.res, evt
    	end
    	evt.tableStyle = evt.tableStyle or "" -- Could change the style of the wikitext. Not available on 20160916
    	if type(evt.name) ~= "string" then evt.name = ""
    	elseif evt.name ~= "" then evt.name = evt.name .. "_" end
    	evt.idargs = evt.name .. tostring( viewers.form9user( tostring(evt.key), lua_table.to_list( evt.vals ) ) )
    	-- Each type of event formats its own type of wikitext
    	evt.content_wkt = viewers.form9content(evt.key, lua_table.to_list( evt.vals ) )
    	evt.page_wkt = viewers.form9page(evt.key, lua_table.to_list( evt.vals ) )
    	evt.user_wkt = viewers.form9user(evt.key, lua_table.to_list( evt.vals ) )
    	evt.res = "" -- multilingual
    	if evt.typ == "err" then evt.res = viewers.styles_color_error(evt.user_wkt) end
    	if evt.typ == "wng" then evt.res = viewers.styles_color_warning(evt.user_wkt) end
    	evt.ccc = c or evt.catview or events.catview or ":"
    	evt.content_catspace = mw.site.namespaces.Category.name -- name: Local namespace name.
    	if evt.typ == "cat" then -- Format a category to display or activate
    		evt.res = events.form_cat(evt)
    		if viewers.is_in("_i_cat", key) then  -- If needed, add a second "Category:Module with internal error"
    			res = res .. events.add_cat("versions_with_internal_error")
    		end
    		if viewers.is_in("_u_cat", key) then  -- If needed, add a second "Category:Module with user error"
    			res = res .. events.add_cat("versions_with_user_error")
    		end
    	end
    	return evt.res, evt
    end -- function events.form(evt, c)
    
    events.all_kinds_test_test_group = {
    	{ "abc",		"langs_form9user_all_types_values", { "pi = ", "circle / diameter", 3.14, }, },
    	{ "equation",	"langs_form9user_all_types_values", { 11, 7, 3.14, }, },
    	{ "Matrix:",	"langs_form9user_all_types_values", { "2.1.0", "v4-6, ISO_8601, FC14 h6", }, },
    	{ "pi = ",		"langs_form9user_all_types_values", { "circle / diameter", 3.14, }, },
    	{ "quadrature", "langs_form9user_all_types_values", { function() end, "convert a square to a circle", }, },
    }
    --	langs_form9user_all_types_values	= "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.",
    function events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat)
    	local memo = viewers.save_configs("events.all_kinds_test") -- Save global configuration before eventual changes.
    	events.all_kinds_trck = "\n* events.all_kinds_trck: "
    	local t = t or ""
    	t = t .. "\n* events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat): "
    	t = t .. events.all_kinds_trck
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = events.all_kinds_test_test_group, -- Use default cases.
    		title_memo = "events_all_kinds_tests_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)",
    		headers = "events_all_kinds_tests_headers", -- "typ;key;idargs;result",
    		rowGroup = {},
    	}
    	function tab_view.form_one_case(evt) -- Convert a case from test_group to rowGroup.
    		return { evt.typ or "t", evt.key or "k", evt.idargs or "i", evt.res or "r" }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	t = t .. viewers.ta("end #test_group *2", lua_table.level_count(tab_view.test_group) ) -- function tableview.new( nil bug170602
    	t = t .. viewers.ta("end #rowGroup *2", lua_table.level_count(tab_view.rowGroup) ) -- function tableview.new( nil bug170602
    	t = t .. events.all_kinds_trck
    	viewers.restore_configs(memo, "events.all_kinds_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function events.all_kinds_test(t)
    
    function events.add_cat_group(groupCat, groupList) -- Add some categories in the actual table of events. Separated by ";".
    --	catGroup("Country %1", "France,Italia") -> [[Category:Country France]] [[Category:Country Italia]]
    	if type(groupCat) ~= "string" then groupCat = "%1" end
    	if type(groupList) ~= "string" then return "" end
    	local cats = ""
    	for i, str in mw.text.gsplit(groupList, ";", true) do
    		local wkt = viewers.form9user(groupCat, str)
    		cats = cats .. events.add_cat(groupCat, wkt)
    	end
    	local res, evt = events.add("catGroup", groupCat, cats) -- Add an event to a group.
    	evt.trc = evt.trc .. viewers.form9user("\n* add_cat evt.typ=%1, evt.key=%2, ", evt.typ, evt.key)
    	return res, evt
    end -- function events.add_cat_group(groupCat, groupList)
    
    function events.select_typ(typ) -- Select events by one type
    	local is = {}
    	for i, evt in pairs(events.test_group) do
    		if evt.typ == typ then table.insert( is, evt.idargs ) end
    	end
    	return is
    end
    
    function events.sort_typ() -- Sort events by type in wng, err, cat.
    	local wng, err, cat = {}, {}, {}
    	for i, evt in pairs(events.test_group) do
    		if evt.typ == "wng" then table.insert( wng, evt ) end
    		if evt.typ == "err" then table.insert( err, evt ) end
    		if evt.typ == "cat" then table.insert( cat, evt ) end
    	end
    	return wng, err, cat
    end -- function events.sort_typ()
    
    function events.selector( tab_view, evt )
    	if type(evt) ~= "table" then
    		evt = { -- options for tableview.new() -- Formats a table with lines and columns.
    			headers = "typ;key;selector-name;wkt",
    			style = "",
    			typ = "err",
    			rowGroup = {},
    		}
    	else
    		evt.headers = evt.headers or "typ;key;else-name;wkt"
    		evt.tableStyle = evt.tableStyle or ""
    		evt.name = evt.name or "_"
    		evt.typ = evt.typ or "nil"
    	end
    	if	   (type(tab_view) == "table") and (type(tab_view.typ) == "string") and (tab_view.typ == evt.typ) then
    		table.insert( tab_view.test_group, { evt.typ, evt.key, evt.name, evt.wkt } )
    	elseif (type(tab_view) == "table") and (type(tab_view.typ) == "string") and (tab_view.typ == "v") then
    		table.insert( tab_view.test_group, { evt.typ, evt.key, evt.name, evt.wkt } )
    	else
    		tab_view = {}
    		table.insert( tab_view.test_group, { evt.typ, evt.key, evt.name, evt.wkt } )
    	end
    end -- function events.selector( tab_view, evt )
    
    function events.all_kinds_test_test(t) -- Test: all kinds of events (err, wng, cat)
    	local memo = viewers.save_configs("events.all_categories_test") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>events.all_kinds_test()</b> Test: all kinds of events (err, wng, cat)"
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = nil, -- Use default cases.
    		title_memo = "events_all_kinds_tests_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)",
    		headers = "events_all_kinds_tests_headers", -- "typ;key;idargs;result",
    	}
    	function tab_view.form_one_case(evt) -- Convert a case from test_group to rowGroup.
    		return { evt.typ, evt.key, evt.idargs, evt.res }
    	end
    	t = t .. tableview.new(tab_view) -- Form a table view with lines and columns.
    	viewers.restore_configs(memo, "events.all_kinds_test_test") -- Restore global configurations after eventual changes.
    	return t --, errors -- langs_missing_translations_title
    end -- function events.all_kinds_test_test(t)
    
    events.errors_list = {} -- Deprecated: Table to collect errors and warnings
    events.erron = true -- Activated or not errors. Errores activado o no. Erreurs activées ou non.
    events.categories_list = {} -- Table to collect all categories to generate in wikitext
    
    function events.errors_lister(title, v1, v2, v3, v4, v5, v6, v7, v8, v9)
    	local res, msgref = "", ""
    	local mwtitle = mw.title.getCurrentTitle()
    	local page = tostring(mwtitle.nsText) .. ":" .. tostring(mwtitle.text)
    	if type(title) ~= "string" then title = "modes_error_list_header_err" end
    	res = res .. '\n*' .. viewers.form9user(title, page, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- .. ' - ' .. page
    	local n = 0
    	for k, wng in ipairs(events.errors_list) do
    		msgref = viewers.form9user(wng.ref, wng.v1, wng.v2, wng.v3, wng.v4, wng.v5, wng.v6, wng.v7, wng.v8, wng.v9) -- texte traduit ou direct
    		if wng.typ == "wng" then
    			res = res .. '<br>⦁ ' .. viewers.styles_color_warning(msgref)
    		end
    	end
    	for k, wng in ipairs(events.errors_list) do
    		msgref = viewers.form9user(wng.ref, wng.v1, wng.v2, wng.v3, wng.v4, wng.v5, wng.v6, wng.v7, wng.v8, wng.v9) -- texte traduit ou direct
    		if wng.typ == "err" then
    			res = res .. '<br>⦁ ' .. viewers.styles_color_error(msgref)
    			n = n + 1
    		end
    	end
    	if n > 0 then
    		events.add_cat("versions_module_with_error_err")
    	end
    	return res
    end -- function events.errors_lister(title, v1, v2, v3, v4, v5, v6, v7, v8, v9)
    
    function events.gener_categories() -- Only for this library, form categories without activate them
    --	events.gener_categories Only display categories, as a text line, using function events.categories_lister
    --	function events.form(evt, c) -- Format an event as an error, warning or category.
    	local gener = {}
    	modes.options_to_cat_view()
    	-- c can replace cat_view to enforce the documentation or the categorisation
    	c = c or modes.cat_view or ""
    	for k, evt in pairs(events.list_all_events) do
    		evt = events.form(evt, c) -- Format an event as an error, warning or category.
    		table.insert(gener, evt ) -- Build a table with translations counts.
    	end
    	return gener
    end -- function events.gener_categories(args_final)
    
    function events.categories_lister(c) -- Categorize categories, or view categories if c=":".
    	local res = ""
    	modes.options_to_cat_view()
    	-- c can replace cat_view to enforce the documentation or the categorisation
    	c = c or modes.cat_view or ""
    	for k, evt in pairs(events.list_all_events) do
    		if (evt.typ == "cat") then
    			local keyuser = viewers.form9user(evt.key)
    			local keycontent = viewers.form9content(evt.key)
    			res = res .. events.form_cat(evt, keyuser, keycontent, c)
    		end
    	end
    	return res
    end -- function events.categories_lister(c)
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:langs supports i18n translations.
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	The Module:Centralizer/I18N translations for langs library update and complete Module:Centralizer translations.
    langs.i18n = {} -- Translations for Library:langs
    langs.i18n.br = {
    	language								= 'langue',
    	langs_translations_counts_title			= "langs.translations_counts() Comptages des traductions en tables",
    	langs_translations_stats_report_title	= "Traductions: nombres par langues et par librairies ou modules.",
    	langs_translations_stats_report_headers = "En-têtes calculés",
    	langs_form9user_tests_title				= "viewers.form9user() Test: Remplacer <b>%1</b> à %9 par tostring( argN ) à partir des arguments",
    	langs_form9user_all_types_values		= "Résultats de test: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "viewers.form99user() Test: Remplacer %01 à %99 par tostring( argN ) à partir des arguments",
    	langs_form99user_all_types_values		= "en viewers.form99user() Valeurs de tous types : <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_translations_key_missing			= "Erreur interne: Clé de traduction manquante ou anormale dans viewers.trans9vars()",
    	langs_form99user_no_tranlation			= "en viewers.form99user() Manque de traduction.",
    	langs_form99user_a_value_is_table		= "en viewers.form99user() Une valeur est une table.",
    	langs_lang_not_exist_err				= "Erreur : La langue <b>%1</b> n'est pas disponible.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Test: Détecter les caractères anormaux dans un texte unilingue.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Liste de toutes les langues de MediaWiki.",
    	-- Principaux textes, erreurs et catégories des outils
    	langs_first_tests_languages				= "Documentation des premières langues",
    	langs_content_page_user_lang_msg		= "Langues : content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Argument connu, mais non traduit : <b>%1</b>.",
    	langs_without_translation_N_err			= "Il y a <b>%1</b> arguments non traduits.",
    	langs_main_i18n_languages_count			= "Ce module peut traduire <b>%1</b> phrases en <b>%2</b> langues : ",
    	langs_table_can_translate_counts		= "La table <b>%1</b> peut traduire <b>%2</b> phrases en <b>%3</b> langues.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(%2=%3), ",
    	langs_counts_translations_headers		= "*; Nom de la table; Textes; Tables; Commentaire",
    	langs_i18n_list_all_string				= "Cette liste montre tous les textes, mais ne peut remplacer les déclarations originales.",
    	langs_languages_nbr_and_list			= "\n* Il y a <b>%1</b> tables de traductions dans ces langues : <b>%2</b> <br>",
    	langs_string_translated_in_langs		= "Il y a <b>%1</b> textes traduits en <b>%2</b> langues.",
    	langs_no_wiki_translations_err			= "Erreur interne : Module sans table d'arguments traduits.",
    	langs_list_in_translated_lang			= "<b>%1</b> traductions en langage <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_changing_translations_title		= "langs.changing_translations() Changements de traduction dans les tables i18n",
    	langs_changing_translations_headers		= "Module; Langue; Clé i18n; Traduction précédente; Traduction changeante",
    	langs_missing_translations_title		= "langs.missing_translations() Traductions manquantes dans les tables i18n.",
    	langs_missing_translations_headers		= "Langue; clé i18n; Traduction précédente; Nouvelle traduction; Module",
    	langs_changing_translations_help		= "Voir aussi <b>%1</b> pour demander de l'aide pour traduire.",
    	langs_mixed_translations_title			= "Tables de traductions i18n combinées :",
    	langs_dummy_languages_title				= "langs.dummy_languages() Caractéristiques de quelques langues:",
    	langs_Module_Central_version			= "Central-w-fr",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module avec erreur interne",
    	langs_missing_one_translation_err		= "Traduction manquante, clé <b>%1</b> en langue <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Traduction manquante, au moins une", -- + "Module with internal error",
    } -- langs.i18n.br
    langs.i18n.de = {
    	language								= 'Sprache',
    	langs_translations_counts_title			= "langs.translations_counts() Übersetzungen in Tabellen zählen",
    	langs_translations_stats_report_title	= "Übersetzungen: Zahlen nach Sprachen und nach Bibliotheken oder Modulen.",
    	langs_translations_stats_report_headers = "Berechnete Kopfzeilen",
    	langs_form9user_tests_title				= "viewers.form9user() Test: Ersetzen Sie <b>%1</b> bis %9 durch tostring(argN) von den Argumenten",
    	langs_form9user_all_types_values		= "Testergebnisse: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "viewers.form99user() Test: Ersetzen Sie %01 bis %99 durch tostring(argN) von den Argumenten",
    	langs_form99user_all_types_values		= "en viewers.form99user() Werte aller Arten: <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_translations_key_missing			= "Interner Fehler: Fehlender oder abnormaler Übersetzungsschlüssel viewers.trans9vars()",
    	langs_form99user_no_tranlation			= "in viewers.form99user() Mangel an Übersetzung.",
    	langs_form99user_a_value_is_table		= "in viewers.form99user() Ein Wert ist eine Tabelle.",
    	langs_lang_not_exist_err				= "Fehler: <b>%1</b> Sprache ist nicht verfügbar.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Test: Ermitteln Sie abnormale Zeichen in einem einsprachigen Text.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Liste aller MediaWiki-Sprachen.",
    	-- Haupttexte, Fehler und Kategorien von Werkzeugen
    	langs_first_tests_languages				= "Dokumentation der ersten Sprachen",
    	langs_content_page_user_lang_msg		= "Sprachen: content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Bekannt, aber nicht übersetzt: <b>%1</b>.",
    	langs_without_translation_N_err			= "Es gibt <b>%1</b> nicht übersetzte Argumente.",
    	langs_main_i18n_languages_count			= "Dieses Modul kann <b>%1</b> Sätze in <b>%2</b> Sprachen übersetzen.",
    	langs_table_can_translate_counts		= "LaDie Tabelle <b>%1</b> kann <b>%2</b> Sätze in <b>%3</b> Sprachen übersetzen.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(<b>%2</b>=<b>%3</b>), ",
    	langs_counts_translations_headers		= "*; Name der Tabelle; Texte; Tabellen; Kommentar",
    	langs_i18n_list_all_string				= "Diese Liste zeigt alle Texte, kann aber die ursprünglichen Aussagen nicht ersetzen.",
    	langs_languages_nbr_and_list			= "\n* Es gibt <b>%1</b> Übersetzungstabellen in diesen Sprachen: <b>%2</b> <br>",
    	langs_string_translated_in_langs		= "Es sind <b>%1</b> Texte in <b>%2</b> Sprachen übersetzt.",
    	langs_no_wiki_translations_err			= "Interner Fehler: Modul ohne übersetzte Argumententabelle.",
    	langs_list_in_translated_lang			= "<b>%1</b> Sprachübersetzungen <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_changing_translations_title		= "langs.changing_translations() Übersetzungsänderungen in i18n-Tabellen",
    	langs_changing_translations_headers		= "Modul; Sprache; Schlüssel i18n; Vorherige Übersetzung; Ändern der Übersetzung",
    	langs_missing_translations_title		= "langs.missing_translations() Fehlende Übersetzungen in i18n-Tabellen.",
    	langs_missing_translations_headers		= "Sprache; i18n Schlüssel; Vorherige Übersetzung Neue Übersetzung Modul",
    	langs_changing_translations_help		= "Siehe auch <b>%1</b> für die Hilfe beim Übersetzen.",
    	langs_mixed_translations_title			= "i18n Übersetzungstabellen kombiniert:",
    	langs_dummy_languages_title				= "langs.dummy_languages() Eigenschaften einiger Sprachen:",
    	langs_Module_Central_version			= "Central-w-de",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Wählen Sie eine Sprache für Tests oder andere Tests aus",
    	langs_selectLang_test_headers			= "Wiki-Sprache; Benutzersprache; Gesuchte Sprache; Ausgewählte Sprache; Beispiel",
    	langs_selectLang_test_example			= "Sprache: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has hat keine Testtabelle.",
    	langs_selectLang_test_cat				= "Modul mit internem Fehler",
    	langs_missing_one_translation_err		= "Fehlende Übersetzung, Schlüssel <b>%1</b> in Sprache <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Fehlende Übersetzung, mindestens eine", -- + "Module with internal error",
    } -- langs.i18n.de
    langs.i18n.en = {
    	language								= 'language',
    	langs_translations_counts_title			= "langs.translations_counts() Counts of translations into tables",
    	langs_translations_stats_report_title	= "Translations: numbers by language and by libraries or modules.",
    	langs_translations_stats_report_headers = "Computed headers",
    	langs_form9user_tests_title				= "viewers.form9user() Test: Replace <b>%1</b> to %9 by tostring( argN ) from arguments",
    	langs_form9user_all_types_values		= "Résultats de test: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "in viewers.form99user() Test: Replace %01 to %99 by tostring( argN ) from arguments",
    	langs_form99user_all_types_values		= "in viewers.form99user() Values of all types: <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_form99user_no_tranlation			= "in viewers.form99user() Lack of translation.",
    	langs_form99user_a_value_is_table		= "in viewers.form99user() A value is a table.",
    	langs_translations_key_missing			= "Internal error: Translations key missing or abnormal in viewers.trans9vars()",
    	langs_lang_not_exist_err				= "Error: The language <b>%1</b> is not available.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Test: Detect abnormal characters in an unilingual text.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() List all MediaWiki languages.",
    	-- Main string, errors and categories of tools
    	langs_first_tests_languages				= "Documentation of first languages",
    	langs_content_page_user_lang_msg		= "Languages: content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Known argument, but not translated: <b>%1</b>.",
    	langs_without_translation_N_err			= "There are <b>%1</b> arguments untranslated.",
    	langs_main_i18n_languages_count			= "This module can translate <b>%1</b> sentences into <b>%2</b> languages: ",
    	langs_table_can_translate_counts		= "The table <b>%1</b> can translate <b>%2</b> sentences into <b>%3</b> languages.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(%2=%3), ",
    	langs_counts_translations_headers		= "*; Table name; Texts; Tables; Comment",
    	langs_i18n_list_all_string				= "This list show all the string, but cannot replace the original declarations.",
    	langs_languages_nbr_and_list			= "\n* There are <b>%1</b> tables of translations in these languages : <b>%2</b> <br>",
    	-- Miscellaneous warnings and errors
    	langs_string_translated_in_langs		= "There are <b>%1</b> string translated in <b>%2</b> languages.",
    	langs_no_wiki_translations_err			= "Error: Module without translated arguments table.",
    	langs_list_in_translated_lang			= "<b>%1</b> translations in language <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_transdiff_wanted_error_err		= "Wanted error for minimal test of langs.missing_translations().",
    	langs_missing_translations_title		= "langs.missing_translations() Missing translations in i18n tables.",
    	langs_missing_translations_headers		= "Language; i18n Key; Previous translation; New translation; Module",
    	langs_changing_translations_headers		= "Language; i18n Key; Previous translation; New translation; Module",
    	langs_changing_translations_help		= "See also <b>%1</b> to ask for help to langs.",
    	langs_mixed_translations_title			= "langs.i18n_lister() Combined i18n translations tables:",
    	langs_dummy_languages_title				= "langs.dummy_languages() Characteristics of some languages:",
    	langs_Module_Central_version			= "Central-w-en",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module with internal error",
    	langs_missing_one_translation_err		= "Missing translation key <b>%1</b> in <b>%2</b> language",
    	langs_missing_one_translation_i_cat		= "Missing at least one translation", -- + "Module with internal error",
    } -- langs.i18n.en
    langs.i18n.es = { -- ¿Quién es?
    	language								= 'lenguaje',
    	langs_translations_counts_title			= "langs.translations_counts() Condes des traducciones en tablas",
    	langs_translations_stats_report_title	= "Traducciones: números por idioma y por bibliotecas o módulos.",
    	langs_translations_stats_report_headers = "Encabezados calculados",
    	langs_form9user_tests_title				= "viewers.form9user() Prueba: Reemplazar <b>%1</b> a %9 por tostring( argN ) a partir de argumentos",
    	langs_form9user_all_types_values		= "Résultats de test: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "en viewers.form99user() Prueba: Reemplazar %01 a %99 por tostring( argN ) a partir de argumentos",
    	langs_form99user_all_types_values		= "en viewers.form99user() Valores de todos los tipos: <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_form99user_no_tranlation			= "en viewers.form99user() Falta de traducción.",
    	langs_form99user_a_value_is_table		= "en viewers.form99user() Un valor es una tabla.",
    	langs_translations_key_missing			= "Error interno: Traducciones clave que falta o anormal en viewers.trans9vars()",
    	langs_lang_not_exist_err				= "Error: El lenguaje <b>%1</b> no está disponible.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Prueba: Detectar caracteres anormales en un texto monolingüe.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Lista de todos los idiomas de MediaWiki.",
    	-- Textos principales, errores y categorías de instrumentos
    	langs_first_tests_languages				= "Documentación de las primeras idiomas",
    	langs_content_page_user_lang_msg		= "Idiomas: content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Argumento conocido, pero no traducido: <b>%1</b>.",
    	langs_without_translation_N_err			= "Hay <b>%1</b> argumentos no traducidos.",
    	-- Diversos mensajes y errores
    	langs_main_i18n_languages_count			= "Este módulo puede traducir <b>%1</b> frases en <b>%2</b> idiomas: ",
    	langs_table_can_translate_counts		= "Tabla <b>%1</b> puede traducir <b>%2</b> frases en <b>%3</b> idiomas.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>( <b>%2</b> = <b>%3</b> ), ",
    	langs_counts_translations_headers		= "*; Nombre de la tabla; Textos; Mesas; Comentario",
    	langs_languages_nbr_and_list			= "\n* Hay <b>%1</b> mesas de traducciones en estas idiomas: <b>%2</b> <br>",
    	langs_string_translated_in_langs		= "Hay <b>%1</b> textos traducidos en <b>%2</b> idiomas.",
    	langs_no_wiki_translations_err			= "Error: Módulo sin argumentos traducidos tabla.",
    	langs_i18n_list_all_string				= "Esta lista muestra todos los textos, pero no puede sustituir a las declaraciones originales.",
    	langs_list_in_translated_lang			= "<b>%1</b> traducciones en idioma <b>%1</b>:<b>%2</b>:<b>%3</b> <b>%4</b> ",
    	langs_missing_translations_title		= "langs.missing_translations() Faltan traducciones en las tablas i18n.",
    	langs_missing_translations_headers		= "Idioma; llave i18n; Traducción previa; Nueva traducción; Módulo",
    	langs_changing_translations_title		= "langs.changing_translations() Changing (or missing) translations in i18n tables.",
    	langs_changing_translations_title		= "langs.changing_translations() Traducciones que cambian (o falta de) en las tablas i18n.",
    	langs_changing_translations_headers		= "Idioma; Clave i18n; Traducción anterior; Nueva traducción; Módulo",
    	langs_changing_translations_help		= "Consulte también <b>%1</b> para solicitar ayuda para traducir.",
    	langs_mixed_translations_title			= "Tablas traducciones i18n combinadas:",
    	langs_dummy_languages_title				= "langs.dummy_languages() Características de algunos idiomas:",
    	langs_Module_Central_version			= "Central-w-es",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module with internal error",
    	langs_missing_one_translation_err		= "Falta traducción, clave <b>%1</b> en el idioma <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Falta la traducción, al menos uno", -- + "Module with internal error",
    } -- langs.i18n.es
    langs.i18n.fr = {
    	language								= 'langue',
    	langs_translations_counts_title			= "langs.translations_counts() Comptages des traductions en tables",
    	langs_translations_stats_report_title	= "Traductions: nombres par langues et par librairies ou modules.",
    	langs_translations_stats_report_headers = "En-têtes calculés",
    	langs_form9user_tests_title				= "viewers.form9user() Test: Remplacer <b>%1</b> à %9 par tostring( argN ) à partir des arguments",
    	langs_form9user_all_types_values		= "Résultats de test: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "viewers.form99user() Test: Remplacer %01 à %99 par tostring( argN ) à partir des arguments",
    	langs_form99user_all_types_values		= "en viewers.form99user() Valeurs de tous types : <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_translations_key_missing			= "Erreur interne: Clé de traduction manquante ou anormale dans viewers.trans9vars()",
    	langs_form99user_no_tranlation			= "en viewers.form99user() Manque de traduction.",
    	langs_form99user_a_value_is_table		= "en viewers.form99user() Une valeur est une table.",
    	langs_lang_not_exist_err				= "Erreur : La langue <b>%1</b> n'est pas disponible.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Test: Détecter les caractères anormaux dans un texte unilingue.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Liste de toutes les langues de MediaWiki.",
    	-- Principaux textes, erreurs et catégories des outils
    	langs_first_tests_languages				= "Documentation des premières langues",
    	langs_content_page_user_lang_msg		= "Langues : content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Argument connu, mais non traduit : <b>%1</b>.",
    	langs_without_translation_N_err			= "Il y a <b>%1</b> arguments non traduits.",
    	langs_main_i18n_languages_count			= "Ce module peut traduire <b>%1</b> phrases en <b>%2</b> langues : ",
    	langs_table_can_translate_counts		= "La table <b>%1</b> peut traduire <b>%2</b> phrases en <b>%3</b> langues.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(%2=%3), ",
    	langs_counts_translations_headers		= "*; Nom de la table; Textes; Tables; Commentaire",
    	langs_i18n_list_all_string				= "Cette liste montre tous les textes, mais ne peut remplacer les déclarations originales.",
    	langs_languages_nbr_and_list			= "\n* Il y a <b>%1</b> tables de traductions dans ces langues : <b>%2</b> <br>",
    	langs_string_translated_in_langs		= "Il y a <b>%1</b> textes traduits en <b>%2</b> langues.",
    	langs_no_wiki_translations_err			= "Erreur interne : Module sans table d'arguments traduits.",
    	langs_list_in_translated_lang			= "<b>%1</b> traductions en langage <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_changing_translations_title		= "langs.changing_translations() Changements de traduction dans les tables i18n",
    	langs_changing_translations_headers		= "Module; Langue; Clé i18n; Traduction précédente; Traduction changeante",
    	langs_missing_translations_title		= "langs.missing_translations() Traductions manquantes dans les tables i18n.",
    	langs_missing_translations_headers		= "Langue; clé i18n; Traduction précédente; Nouvelle traduction; Module",
    	langs_changing_translations_help		= "Voir aussi <b>%1</b> pour demander de l'aide pour traduire.",
    	langs_mixed_translations_title			= "Tables de traductions i18n combinées :",
    	langs_dummy_languages_title				= "langs.dummy_languages() Caractéristiques de quelques langues:",
    	langs_Module_Central_version			= "Central-w-fr",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module avec erreur interne",
    	langs_missing_one_translation_err		= "Traduction manquante, clé <b>%1</b> en langue <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Traduction manquante, au moins une", -- + "Module with internal error",
    } -- langs.i18n.fr
    langs.i18n.hu = {
    	language								= 'nyelv',
    	langs_translations_counts_title			= "langs.translations_counts() Fordítások a táblázatokba",
    	langs_translations_stats_report_title	= "Fordítások: számok nyelv és könyvtárak vagy modulok szerint.",
    	langs_translations_stats_report_headers = "Számított fejlécek",
    	langs_form9user_tests_title				= "viewers.form9user() Teszt: Az argumentumokból tostring(argN) helyett <b>%1</b> - %9 helyettesítse",
    	langs_form9user_all_types_values		= "Teszt: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "viewers.form99user() Teszt: Az argumentumokból tostring(argN) helyett %01 - %99 helyettesítse",
    	langs_form99user_all_types_values		= "Teszt: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_all_types_values		= "xx-ben minden típusú értékek: <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_translations_key_missing			= "Belső hiba: hiányzik vagy abnormális fordítási kulcs van viewers.trans9vars()",
    	langs_form99user_no_tranlation			= "in viewers.form99user() A fordítás hiánya.",
    	langs_form99user_a_value_is_table		= "in viewers.form99user() Az érték egy táblázat.",
    	langs_lang_not_exist_err				= "Hiba: A (z) <b>%1</b> nyelv nem érhető el.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Teszt: A kóros karaktereket egynyelvű szövegben ismeri fel.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Az összes MediaWiki nyelv listája.",
    	-- Fő szövegek, hibák és eszközök kategóriái
    	langs_first_tests_languages				= "Az első nyelvek dokumentálása",
    	langs_content_page_user_lang_msg		= "Nyelveken: content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Ismert, de nem lefordított: <b>%1</b>.",
    	langs_without_translation_N_err			= "<b>%1</b> nem fordított argumentum van.",
    	langs_main_i18n_languages_count			= "Ez a modul lefordíthat <b>%1</b> mondatokat <b>%2</b> nyelvekre: ",
    	langs_table_can_translate_counts		= "A <b>%1</b> táblázat <b>%2</b> mondatokat lefordíthat <b>%3</b> nyelvekre.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(%2=%3), ",
    	langs_counts_translations_headers		= "*; A táblázat neve; szövegek; asztalok; megjegyzés",
    	langs_i18n_list_all_string				= "Ez a lista az összes szöveget mutatja, de nem helyettesítheti az eredeti állításokat.",
    	langs_languages_nbr_and_list			= "\n* Ezek a nyelvek <b>%1</b> fordítási táblázatok vannak: <b>%2</b> ",
    	langs_string_translated_in_langs		= "<b>%1</b> szövegek <b>%2</b> nyelvre lettek lefordítva.",
    	langs_no_wiki_translations_err			= "Belső hiba: Modul fordítás nélküli táblázat nélkül.",
    	langs_list_in_translated_lang			= "<b>%1</b> nyelvi fordítások <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_changing_translations_title		= "langs.changing_translations() Fordítások a táblázatokban i18n",
    	langs_changing_translations_headers		= "modul; nyelv; I18n kulcs; Korábbi fordítás; A fordítás megváltoztatása",
    	langs_missing_translations_title		= "langs.missing_translations() A táblázatokban hiányzik a fordítás i18n.",
    	langs_missing_translations_headers		= "nyelv; i18n kulcs; Korábbi fordítás; Új fordítás modul",
    	langs_changing_translations_help		= "Voir aussi <b>%1</b> pour demander de l'aide pour traduire.",
    	langs_mixed_translations_title			= "Tables de traductions i18n combinées :",
    	langs_dummy_languages_title				= "langs.dummy_languages() Caractéristiques de quelques langues:",
    	langs_Module_Central_version			= "Central-w-fr",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module avec erreur interne",
    	langs_missing_one_translation_err		= "Traduction manquante, clé <b>%1</b> en langue <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Traduction manquante, au moins une", -- + "Module with internal error",
    } -- langs.i18n.hu
    langs.i18n.vi = {
    	language								= 'langue',
    	langs_translations_counts_title			= "langs.translations_counts() Số bản dịch vào các bảng",
    	langs_translations_stats_report_title	= "Bản dịch: số theo ngôn ngữ và theo thư viện hoặc mô-đun.",
    	langs_translations_stats_report_headers = "Tiêu đề được tính toán",
    	langs_form9user_tests_title				= "viewers.form9user() Test: Remplacer <b>%1</b> à %9 par tostring( argN ) à partir des arguments",
    	langs_form9user_all_types_values		= "Test: string=<b>%1</b> number=<b>%2</b> nil=<b>%3</b> function=<b>%4</b> table=%5.",
    	langs_form99user_tests_title			= "viewers.form99user() Test: Remplacer %01 à %99 par tostring( argN ) à partir des arguments",
    	langs_form99user_all_types_values		= "en viewers.form99user() Valeurs de tous types : <b>%1</b>, <b>%2</b>, <b>%3</b>, <b>%4</b>, %5.",
    	langs_translations_key_missing			= "Erreur interne: Clé de traduction manquante ou anormale dans viewers.trans9vars()",
    	langs_form99user_no_tranlation			= "en viewers.form99user() Manque de traduction.",
    	langs_form99user_a_value_is_table		= "en viewers.form99user() Une valeur est une table.",
    	langs_lang_not_exist_err				= "Erreur : La langue <b>%1</b> n'est pas disponible.",
    	langs_abnormal_char_in_text_title		= "langs.abnormal_char_in_text() Test: Détecter les caractères anormaux dans un texte unilingue.",
    	langs_abnormal_char_in_alphabet			= "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?",
    	langs_list_MediaWiki_languages_title	= "langs.list_MediaWiki_languages() Liste de toutes les langues de MediaWiki.",
    	-- Principaux textes, erreurs et catégories des outils
    	langs_first_tests_languages				= "Documentation des premières langues",
    	langs_content_page_user_lang_msg		= "Langues : content: <b>%1</b>, page: <b>%2</b>, user: <b>%3</b>.",
    	langs_without_translation_err			= "Argument connu, mais non traduit : <b>%1</b>.",
    	langs_without_translation_N_err			= "Il y a <b>%1</b> arguments non traduits.",
    	langs_main_i18n_languages_count			= "Ce module peut traduire <b>%1</b> phrases en <b>%2</b> langues : ",
    	langs_i18n_list_all_string				= "Cette liste montre tous les textes, mais ne peut remplacer les déclarations originales.",
    	langs_languages_nbr_and_list			= "\n* Il y a <b>%1</b> tables de traductions dans ces langues : <b>%2</b> <br>",
    	langs_string_translated_in_langs		= "Il y a <b>%1</b> textes traduits en <b>%2</b> langues.",
    	langs_no_wiki_translations_err			= "Erreur interne : Module sans table d'arguments traduits.",
    	langs_list_in_translated_lang			= "<b>%1</b> traductions en langage <b>%2</b> : <b>%3</b> : <b>%4</b>",
    	langs_changing_translations_help		= "Voir aussi <b>%1</b> pour demander de l'aide pour traduire.",
    	langs_mixed_translations_title			= "Tables de traductions i18n combinées :",
    	langs_dummy_languages_title				= "langs.dummy_languages() Caractéristiques de quelques langues:",
    	langs_Module_Central_version			= "Central-w-fr",
    	langs_selectLang_tests_title			= "langs.select_lang() Tests: Select a language for tests or other",
    	langs_selectLang_test_headers			= "Wiki language; User language; Sought language; Selected language; Example",
    	langs_selectLang_test_example			= "Language: content = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.",
    	langs_selectLang_test_err				= "Internal error : langs.select_lang(lang) has no tests table.",
    	langs_selectLang_test_cat				= "Module avec erreur interne",
    	langs_missing_one_translation_err		= "Traduction manquante, clé <b>%1</b> en langue <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Traduction manquante, au moins une", -- + "Module with internal error",
    	--
    	langs_counts_translations_headers		= "*; Tên bảng; Văn bản; Những cái bàn; Bình luận",
    	langs_table_can_translate_counts		= "Bảng <b>%1</b> có thể dịch thành <b>%2</b> câu <b>%3</b> ngôn ngữ.",
    	langs_mw_language_fetchLanguageName		= "<b>%1</b>(%2=%3), ",
    	langs_changing_translations_title		= "langs.changing_translations() Các bản dịch trong i18n tables",
    	langs_changing_translations_headers		= "Mô đun; Ngôn ngữ;, Khóa i18n; Bản dịch trước; Thay đổi bản dịch",
    	langs_missing_translations_title		= "langs.missing_translations() Thiếu bản dịch trong bảng i18n.",
    	langs_missing_translations_headers		= "Ngôn ngữ; i18n Key; Bản dịch trước; Bản dịch mới; Mô-đun",
    	langs_missing_one_translation_err		= "Thiếu phím dịch <b>%1</b> bằng ngôn ngữ <b>%2</b>",
    	langs_missing_one_translation_i_cat		= "Thiếu bản dịch, ít nhất một", -- + "Module with internal error",
    } -- langs.i18n.vi
    
    langs.MetaSupportedLanguages = { "ja", "es", "ru", "de", "nl", "tr", "fr", "pt", "ko", "en", "it", "oc",
    	"pl", "fa", "ar", "vi", "arz", "hi", "sv", "diq", "pt-br", "zh", "th", "bg", "hu", "uk", "en-gb",
    	"sh", "id", "bn", "az", "fi", "be", "he", "eo", "el", "sd", "kn", "ro", "yue", "sr", "mk", "ta",
    	"pa", "hy", "lb", "tt", "si", "yi", "ne", "cs", "sk", "ms", "eu", "mr", "sa", "tl", "eml",
    	-- https://meta.wikimedia.org/wiki/Special:SupportedLanguages on 20170629 Rical
    } --  58 languages in total.
    
    function langs.i18n_sub_counts(subnames_in, key_form, lang) -- Count i18n in the last sub-table from its sub-names.
    --	local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(subnames_in, key_form, lang)
    	local subnames_in, key_form, lang = subnames_in, key_form, lang
    	if (type(subnames_in) ~= "string") then subnames_in = "" end
    	local t, strings_c, tables_c, strs_on_tabs, subnames = "", 0, 0, 0, ""
    	local sub_names = mw.text.split(subnames_in, '%.') -- table of words
    	local in_i18n, i18n_i, subnames_, sub_tab, all_strings, strs_on_tabs, separ
    	local i18n_counts, i18n_strings_c, i18n_tables_c
    	local lang_counts, lang_strings_c, lang_tables_c = {}
    	if (type(sub_names) == "table") then
    		subnames_ = ""
    		separ = ""
    		in_i18n = nil
    		i18n_i = 0
    		for i, sub_name in ipairs(sub_names) do
    			subnames_ = subnames_ .. separ .. sub_name
    			separ = "."
    			subnames = subnames_ -- string.sub(subnames_, 2, -1) -- like modes.i16n.fr
    			if viewers.is_in("i18n", sub_name) then -- In a i18n table
    				i18n_i = i
    				sub_tab = lua_table.from_subnames_table(subnames) -- Get the last sub-table from its sub-names.
    				i18n_counts = lua_table.count_types(sub_tab)
    				i18n_strings_c = i18n_counts.string or "0"
    				i18n_tables_c = i18n_counts.table or 0
    				tables_c = i18n_tables_c
    				all_strings = 0
    				if (type(sub_tab) == "table") then -- until last subname
    					for key, val in pairs(sub_tab) do
    						if (type(val) == "table") then
    							all_strings = all_strings + lua_table.count_all(val) -- Actual count
    						end
    					end
    				end
    				strs_on_tabs = math.floor( (all_strings + 0.49) / math.min(tables_c, 1) )
    				strings_c = strs_on_tabs
    			elseif i > i18n_i then -- In a language sub-table
    				sub_tab = lua_table.from_subnames_table(subnames) -- Get the last sub-table from its sub-names.
    				lang_counts = lua_table.count_types(sub_tab)
    				lang_strings_c = lang_counts.string
    				lang_tables_c = lang_counts.table
    				strings_c = lang_strings_c
    				tables_c = 1
    			end
    		end
    	end
    	-- This module can translate... = langs_main_i18n_languages_count
    	local strings_c = strings_c or 0 --	 or lang_counts.strings_c
    	local tables_c = tables_c or 0 -- or i18n_tables_c.tables_c
    	local strs_on_tabs = strs_on_tabs or 0
    	-- Formats resulting text
    	if (type(lang) ~= "string") then lang = "user"
    	elseif lang == "c" then lang = "content"
    	elseif lang == "p" then lang = "page"
    	elseif lang == "u" then lang = "user" end
    	if (type(key_form) ~= "string") then key_form = "langs_table_can_translate_counts" end
    	local t = viewers.form9user(key_form, subnames, strings_c, tables_c)
    	if lang == "page" then t = viewers.form9page(key_form, subnames, strings_c, tables_c) end
    	if lang == "content" then t = viewers.form9content(key_form, subnames, strings_c, tables_c) end
    	return t, strings_c, tables_c, strs_on_tabs, subnames
    --	local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(subnames_in, key_form, lang)
    end -- function langs.i18n_sub_counts(subnames_in, key_form, lang)
    
    function langs.translations_counts(t) -- Counts of contents of some tables, from their names. -- S170618ltc
    	local memo = viewers.save_configs("langs.translations_counts") -- Save global configuration before eventual changes.
    	local t = t or '\n* langs.translations_counts("activity.i18n") Counts of contents of some tables, from their names: '
    	local selector = "br;es;vi;modes;begin;translate;" -- Select a reduces table view.
    	local object_loaded, counts, pre_counts, tables_c, sub_string_count
    	local tabname, subnames, tt, lang
    	local trans_Group, trans_counts = {}, {}
    	local libname_total = 0
    	local select_track = "-" -- nil
    	local trans_counts = {}
    	for libname, library in pairs(package.loaded) do
    		if (type(library.i18n) == "table") then -- Select all libraries with i18n tables.
    			tabname = libname .. ".i18n"
    			table.insert(trans_Group, { tabname } ) -- Build a table with translations counts.
    		end
    	end
    	table.sort(trans_counts, function (row_x, row_y) return ( row_x[1] < row_x[1] ) end ) -- Sort based on [1]=tabname
    	local test_tables = "versions.memo_i18n;begin.i18n.de;begin.i18n.hu;begin.i18n.vi;modes.i18n.fr" -- Select a reduces table view.
    	local test_tables_tab = mw.text.split(test_tables, ';') -- table of words
    	for i, subnames_in in ipairs(test_tables_tab) do -- list all used names, only one each, in alphabetic order
    		table.insert(trans_Group, { ["subnames_in"] = subnames_in, ["i"] = i } ) -- Build a table with translations counts.
    	end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    --		test_group = trans_Group,
    		test_group = {
    			{ i = 1, subnames_in = "activity.i18n.hu", },
    			{ i = 2, subnames_in = "versions.i18n.hu", },
    			{ i = 3, subnames_in = "versions.i18n.en", },
    			{ i = 4, subnames_in = "versions.memo_i18n.en", },
    			{ i = 5, subnames_in = "versions.memo_i18n.hu", },
    			{ i = 6, subnames_in = "versions.memo_i18n.vi", },
    			{ i = 7, subnames_in = "versions.memo_i18n", },
    		},
    		title_memo = "langs_translations_counts_title", -- "langs.translations_counts() Counts of translations in tables",
    		headers = "langs_counts_translations_headers", -- "*; Table name; Texts; Tables; Comment",en
    		headers_class = "wikitable alternative center sortable",
    		rowselect = selector,
    		rowGroup = {}, -- tests or tab_view.test_group or
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		case.subnames_in = case.subnames_in or "subnames_in"
    		case.sub_names = lua_table.from_subnames_table(case.subnames_in, case.base_table) -- Get the last sub-table from its sub-names.
    		case.i = case.i or 33
    		case.t, case.strings_c, case.tables_c, case.strs_on_tabs, case.subnames = langs.i18n_sub_counts(case.subnames_in, "langs_table_can_translate_counts", "user")
    		case.comment = viewers.form9user("langs_table_can_translate_counts", case.subnames, case.strings_c, case.tables_c)
    		return { case.i, case.subnames_in, case.strings_c, case.tables_c, case.t, } -- .. comment .. trk
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "langs.translations_counts") -- Restore global configurations after eventual changes.
    	return t
    end --	t = function langs.translations_counts(t)
    
    function langs.translations_statistics_report(t) -- Reports statistics on translations.
    	local memo = viewers.save_configs("langs.translations_statistics_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>langs.translations_statistics_report(t)</b> Statistical report on translations by languages and libraries."
    	t = t .. "\n* Guideline for this stat : Count lists of translations by languages and libraries, then convert in a 2D table, then format and report them."
    	t = t .. "\n* <b>Normal result: Counts are similar in all languages.</b>"
    	local args_known = args_known or modes.args_known or p.args_known or {} -- modes.args_known = { -- p.args_known = { -- }
    	local translate_i18n = versions.memo_i18n
    	local all_stats = {} -- all_stats + Total
    	local trans_count, case, i18n_group, total_stat, total_stats = 0
    --	Guideline for this stat : Collect counts of translations by languages and libraries, then put them in a 2D table, then format and report them.RIC
    	for libname, vers in pairs(package.loaded) do -- in reverse order bind_libra
    		total_stat = { ["libr"] = tostring(vers.libname),	["code"] = "en", ["content"] = 0, ["page"] = 0, ["user"] = 0, ["n_langs"] = 0, ["total"] = 0, }
    		if (type(vers) == "table") and (type(vers.i18n) == "table") then
    			local case = { ["libr"] = tostring(vers.libname),	["code"] = "en", ["content"] = 0, ["page"] = 0, ["user"] = 0, ["n_langs"] = 0, ["total"] = 0, }
    			for code_lang, available_translations in pairs(vers.i18n) do -- import and mix known args and properties
    				case.code = code_lang
    				case.count = lua_table.level_count(available_translations)
    			--	case.i18n = vers.i18n
    				case.total_stat = { ["libr"] = tostring(vers.libname),	["code"] = "en", ["content"] = 0, ["page"] = 0, ["user"] = 0, ["n_langs"] = 0, ["total"] = 0, }
    				if case.code == langs.content_lang then case.content = case.count ; total_stat.content = total_stat.content + case.count end
    				if case.code == langs.page_lang then case.page = case.count ; total_stat.page = total_stat.page + case.count end
    				if case.code == langs.user_lang then case.user = case.count ; total_stat.user = total_stat.user + case.count end
    			--	total_stat.code = (total_stat.code or 0) + 1
    				total_stat.n_langs = (total_stat.n_langs or 0) + 1
    				case = { ["libr"] = tostring(vers.libname), ["code"] = case.code,
    					["content"] = case.content or 0, ["page"] = case.page or 0, ["user"] = case.user or 0, ["n_langs"] = 1, ["total"] = 0, }
    			end
    			table.insert( all_stats, case )
    		end
    	end
    	local list_case_libname = {} -- list of libnames
    	langs.list_case_libname = list_case_libname
    	for i, case in pairs(all_stats) do table.insert(langs.list_case_libname, case.libr) end
    	table.sort(langs.list_case_libname, function (a, b) return ( tostring(a) < tostring(b) ) end ) -- sort found langcodes
    	local headers = "langcode" -- and add list of libnames
    	for x, libname in pairs(langs.list_case_libname) do headers = headers .. ";" .. tostring(libname) end
    	headers = string.gsub(headers, versions.ModuleNS, "")
    	local libraries = {}
    	local langcodes = {} -- langcodes collection
    	local libnames = { "langcode" } -- libnames collection
    	for title, obj in pairs(package.loaded) do -- Get all libraries and libnames names.
    		local get = versions.bind_main_and_sub_modules_get[title]
    		if get and get.is_library and (type(get.i18n) == "table") then -- select libraries only
    			local libname = tostring(get.title)
    			table.insert( libnames, libname )
    		end
    	end
    	for i, libname in pairs(libnames) do -- for all objects
    		local get = versions.bind_main_and_sub_modules_get[libname]
    		if get and get.is_library and (type(get.module) == "table") and (type(get.title) == "string") then -- select libraries only
    			libname = get.title -- for all libraries
    			local lib = get.module
    			for langcode, trans_tab in pairs(lib.i18n) do -- To collect all langcode
    				if type(langcode) == "string" then langcodes[langcode] = langcode end -- add the langcode
    			end
    		end
    	end
    	local list_case_langcode = {} -- list of found langcodes
    	langs.list_case_langcode = list_case_langcode
    	for x, langcode in pairs(langcodes) do table.insert(list_case_langcode, langcode) end
    	table.sort(list_case_langcode, function (a, b) return ( tostring(a) < tostring(b) ) end ) -- sort found langcodes
    	local langcode_libname_2D = {}
    	local list_trans = {} -- list of number of translations in one library.
    	for i, langcode in pairs(list_case_langcode) do -- Structure a 2D table : libraries in langcodes.
    		local lib_tab = { langcode }
    		for j, libname in pairs(list_case_libname) do -- List all package.loaded objects.
    			local lib = package.loaded[tostring(libname)]
    			table.insert( lib_tab, lua_table.level_count(lib.i18n[tostring(langcode)]) )
    		end
    		table.insert(langcode_libname_2D, lib_tab)
    	end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = langcode_libname_2D,
    		title_memo = "langs_translations_stats_report_title",
    		form_one_case = function(case) -- Convert a case from test_group to row_group.
    			return case
    		end,
    		["headers"] = headers, -- ~= "Lang;activity;datas;langs;events;lua_table;mathroman;modes",
    		row_group = {},
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "langs.translations_statistics_report") -- Restore global configurations after eventual changes.
    	return t
    end -- res = res .. langs.translations_statistics_report(t)
    
    function langs.key(key, lang) -- Translate the key in user, wiki and content languages.
    	if (type(key) ~= "string") then key = "translate_missing_key_err" end
    	if (type(lang) ~= "string") then lang = nil end
    	local translate_i18n = versions.memo_i18n
    	function translate_one_key(translate_i18n, key, lang)
    		if lang and (type(translate_i18n) == "table") then translate_i18n = translate_i18n[lang] end
    		if key and (type(translate_i18n) == "table") then translate_i18n = translate_i18n[key] end
    		return translate_i18n
    	end
    	translate_i18n = translate_one_key(translate_i18n, key, lang)
    	if (type(lang) == "string") then -- Only the selected language
    		return translate_i18n
    	else
    		return	translate_one_key(translate_i18n, key, langs.user_lang),
    				translate_one_key(translate_i18n, key, langs.content_lang),
    				translate_one_key(translate_i18n, key, langs.page_lang)
    	end
    --	local user, wiki, page = langs.key(key, lang) --	Examples of uses
    end -- function langs.key(key, lang)
    
    function langs.main_i18n_languages_list() -- List available translations and languages
    	local main_i18n = versions.memo_i18n or {}
    	local xxx, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("versions.memo_i18n", "langs_main_i18n_languages_count", "user")
    	local tab_to_sort = {}
    	for lang, modname in pairs(main_i18n) do
    		table.insert(tab_to_sort, lang) -- build a table with only languages codes
    	end
    	table.sort(tab_to_sort, function (a, b) -- sort the languages codes in stable alphabetic order
    		return	( a < b )
    	end )
    	strs_on_tabs = math.floor(strs_on_tabs / tables_c)
    	local t = viewers.form9user("langs_main_i18n_languages_count", strs_on_tabs, tables_c)
    	for i, lang in pairs(tab_to_sort) do -- Name and count translations in each language
    		local langi18n = "langs.main_i18n." .. lang
    		local xxx, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(langi18n, "langs_main_i18n_languages_count", "user")
    		t = t .. "<b>" .. strings_c .. "</b>-"
    		local nativename = mw.language.fetchLanguageName(lang)
    		local englishname = mw.language.fetchLanguageName(lang, "en")
    		local englishname = mw.language.fetchLanguageName(lang, "en")
    		t = t .. viewers.form9user("langs_mw_language_fetchLanguageName", nativename, lang, englishname) -- "<b>%1</b>(%2=%3), "
    		if i > 12 then t = t .. "<b> ...</b>" ; break end
    	end -- see langs.select_lang
    	return t
    end -- function langs.main_i18n_languages_list()
    
    langs.Central_version = "Central-s-fr" -- To adapt the version of Module:Centralizer in any translated text.
    langs.default_user_lang = "en" -- To adapt the version of Module:Centralizer in any translated text.
    --	waiting T68051 Central modules need the user language to display errors and category names
    
    function langs.init_content_page_user_lang(content_lang, page_lang, user_lang)
    	-- Initialize or change the content, the page and the user languages and their translations tables.
    	-- Guide line: decreasing priority, for each of these 3 languages, is : argument, else MediaWiki, else default values.
    	-- See also https://meta.wikimedia.org/wiki/Translate_extension and [[Special:PageLanguage]] 2016-12-19
    	local main_i18n = versions.memo_i18n or langs.main_i18n or versions.main_i18n
    	local t = "" -- internal track
    	local lg = {}
    	local modesCont, modesPage, modesUser = nil, nil, nil
    	if modes.args_source then --  and modes.args_source.userlang Does module arguments ask a content_lang?
    		local modes_args = modes.args_final or modes.args_source -- work after full init or before
    		modesCont = modes_args.contentlang
    		modesPage = modes_args.pagelang
    		modesUser = modes_args.userlang
    	end
    	modes.frame = mw.getCurrentFrame()
    	local get_content_lang = mw.getContentLanguage().code -- Returns the default content language.
    	local get_page_lang = modes.frame:preprocess("{{PAGELANGUAGE}}") -- Returns the default page language.
    	local get_user_lang = modes.frame:preprocess( "{{int:Lang}}" )
    --	waiting T68051 Central modules need the user language to display errors and category names
    	-- Activate these languages for all uses.
    	if type(main_i18n) ~= "table" then main_i18n = {} end -- default empty main_i18n. Only for languages
    	langs.content_lang = content_lang or get_content_lang or "en"
    	langs.content_translations = main_i18n[langs.content_lang]
    	langs.page_lang = page_lang or get_page_lang or "en"
    	langs.page_translations = main_i18n[langs.page_lang]
    	langs.user_lang = user_lang or get_user_lang or langs.default_user_lang or "en"
    	langs.user_translations = main_i18n[langs.user_lang]
    	langs.main_i18n = main_i18n
    	versions.main_i18n = main_i18n
    	return t
    end -- function langs.init_content_page_user_lang(content_lang, page_lang, user_lang) -- _new
    
    function langs.select_lang( lang ) -- Select a language for tests or other purpose.
    	if type(lang) ~= "string" then lang = "user_lang" end -- default is user language
    	-- Select between : user_lang content_lang tests en es fr or any available in i18n.
    	if lang == "tests" then lang = "tests"
    	elseif versions.memo_i18n and versions.memo_i18n[lang] then lang = lang -- available in i18n
    	elseif lang == "user_lang" then lang = langs.user_lang
    	elseif lang == "content_lang" then lang = langs.content_lang
    	else lang = langs.user_lang end -- default is user language
    	return lang
    end -- function langs.select_lang( lang )
    
    function langs.select_lang_test(t) -- Tests: Select a language for tests or other purpose.
    	local memo = viewers.save_configs("langs.select_lang_test") -- Save global configuration before eventual changes.
    	local t = t or "\n* Test <b>langs.select_lang()</b> :" -- langs_selectLang_tests_title
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = { -- events.test_group
    			{ content_lang = "en", user_lang = "fr",	sought = "content_lang", },
    			{ content_lang = "en", user_lang = "es",	sought = "user_lang", },
    			{ content_lang = "en", user_lang = nil ,	sought = "content_lang", },
    			{ content_lang = nil , user_lang = "es",	sought = "user_lang", },
    			{ content_lang = "fr", user_lang = "es",	sought = "tests", },
    		},
    		headers = "langs_selectLang_test_headers"
    	--	headers = "Wiki language; User language; Sought language; Selected language; Example",
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local selected = langs.select_lang( lang )
    		local example = viewers.form9user("langs_selectLang_test_example")
    		if selected == "tests" then example = viewers.form9tests("selectLang", case.content_lang, case.user_lang, case.sought) end
    		return { tostring(case.content_lang), tostring(case.user_lang), tostring(case.sought), tostring(selected), tostring(example), }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "langs.select_lang_test") -- Restore global configurations after eventual changes.
    	return t
    end -- langs.select_lang_test(t)
    
    function langs.list_MediaWiki_languages(t, lang) -- List all MediaWiki languages.
    	local memo = viewers.save_configs("langs.list_MediaWiki_languages") -- Save global configuration before eventual changes.
    	if type(t) ~= "string" then t = "\n* <b>langs.list_MediaWiki_languages()</b> List all known MediaWiki languages:" end
    	local interwikiMap = mw.site.interwikiMap("local")	local lang = mw.language.new( langs.user_lang or "en" )
    	local LangCode = lang:getFallbackLanguages()
    	local lang_code_name = mw.language.fetchLanguageNames() -- inLanguage, 'mwfile' )
    	local toSort, t2 = {}, ""
    	local t = (t or "") .. "\n* Infos lang_code_name: " .. viewers.ta("#lang_code_name", lua_table.level_count(lang_code_name) )
    	for code, name in pairs(lang_code_name) do -- make a true table in rough order
    		table.insert(toSort, { code,	 name } )
    		-- insert detail { [1]=code, [2]=name } )
    	end
    	table.sort(toSort, function (row_x, row_y) return ( row_x[1] < row_x[1] ) end ) -- Sort based on [1]=code
    	table.sort(toSort, function (row_x, row_y) return ( row_x[2] < row_x[2] ) end ) -- Sort based on [2]=name
    	t = t .. "\n* List of <b>known</b> languages of MediaWiki lang_code_name: <br/>" .. t2
    	t = t .. "\n* Infos: " .. viewers.ta("#lang_code_name", lua_table.level_count(lang_code_name) ) .. viewers.ta("#toSort", lua_table.level_count(toSort) ) .. viewers.ta("user_lang", langs.user_lang)
    	t2 = ""
    	for i, lang in pairs(toSort) do
    		local ok = 1 or langs.abnormal_char_in_text(lang[2], langs.user_lang) -- Detect abnormal characters in an unilingual text.
    		local lang_2 = lang[2]
    		if not ok then lang_2 = viewers.styles_color_error(lang_2) end
    		t2 = t2 .. viewers.ta( lang[1], lang_2 ) -- .. "\n* "
    	end
    	t = t .. "\n* List of <b>known</b> languages of MediaWiki: <br/>" .. t2
    	viewers.restore_configs(memo, "langs.list_MediaWiki_languages") -- Restore global configurations after eventual changes.
    	return t
    end -- function langs.list_MediaWiki_languages(t, lang)
    
    function langs.abnormal_char_in_text(t) -- Test: Detect abnormal characters in an unilingual text.
    	if type(t) ~= "string" then return false end -- langs_abnormal_char_in_text_title
    --	local ok, normal = true, "ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 abcdefghabklmnopqrstuvwxyz àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?"
    	local ok, normal = true, viewers.form9user("langs_abnormal_char_in_alphabet")
    	local letter, nn = "x", string.len(t .. " abcdef") - 3
    	for i = 1, nn do -- for all chars in t
    		letter = string.byte(t, i)
    		if not viewers.is_in(letter, normal) then ok = false ; break end
    	end
    	return ok
    end -- function langs.abnormal_char_in_text(t)
    
    function langs.changing_translations(t) -- List all changing translations
    	local memo = viewers.save_configs("langs.changing_translations") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>langs.changing_translations()</b>: List all changing translations:"
    	local i18n = versions.memo_i18n
    	langs.translations_differences = langs.translations_differences or {}
    	local nerr, errors, trans, err = 0, "*", "", ""
    	local nbr, nbr_in_lang, list = 0, 0, ""
    	local nbr_in_lang_limit = 4
    	local prev_i18n, next_i18n, prev_table, next_table, max, nkeys = {}, {}, {}, {}, 0, 0
    	local strnew, lang, prev_lang, refer_lang, cats = "strnew", "", "", "", "", ""
    	-- change means a different text in the main module relative to the text inside each central library, based on the same keyi18n.
    	local changingGroup, libraries = {}, {}
    	for title, obj in pairs(package.loaded) do -- For libraries only
    		local get = versions.bind_main_and_sub_modules_get[title]
    		if get and get.is_library and (type(get.i18n) == "table") then
    			prev_lang = refer_lang
    			prev_i18n = get.i18n
    			next_i18n = i18n
    			table.insert(libraries, get.module)
    		end
    	end
    	local lib_langs_keys = {} -- To mix libraries their langs and keys and vals
    	for title, onelibrary in pairs(libraries) do -- For all libraries only
    		for onelang, lang_table in pairs(onelibrary.i18n) do -- For all languages in each library
    			lib_langs_keys[onelang] = lib_langs_keys[onelang] or {}
    			for key, val in pairs(lang_table) do -- For all keys in each language
    				lib_langs_keys[onelang][key] = val
    			end
    		end
    	end
    	for refer_lang, next_table in pairs(libraries) do -- For all languages and texts to translate
    		list = list .. refer_lang .. ", "
    		nbr = nbr + 1
    		if type(next_table) == "table" then -- For each pair of languages to compare
    			nkeys = 0
    			nbr_in_lang = 0
    			local all_txts = {}
    			if type(next_table) == "table" then -- For each language to compare
    				for keyi18n, stri18n in pairs(next_table) do -- List all texts translated in at least one language
    					all_txts[keyi18n] = stri18n
    				end
    				for keyi18n, stri18n in pairs(all_txts) do -- Look at all translations in one language, but check them only from 1 to nbr_in_lang_limit.
    					nbr_in_lang = nbr_in_lang + 1
    					nkeys = nkeys + 1
    					if (type(keyi18n) == "string") then -- only translations, not positional arguments
    						keyi18n, stri18n = tostring(keyi18n), tostring(stri18n)
    						local cut = string.find(tostring(keyi18n) .. "_", "_")
    						local modul = string.sub(keyi18n, 1, cut - 1)
    						if (nbr_in_lang == nbr_in_lang_limit) then -- for the last changing
    						--	local strnew = i18n[refer_lang][keyi18n] or "strnew"
    							if i18n[refer_lang] then
    								strnew = i18n[refer_lang][keyi18n] or "strnew"
    							end
    							table.insert( changingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["stri18n"] = stri18n, ["strnew"] = strnew,
    							["counts"] = viewers.styles_color_error("changing limit = " .. nbr_in_lang_limit), ["modul"] = modul} )
    						--	nerr = nerr + 1
    						elseif (nbr_in_lang < nbr_in_lang_limit) then -- for changing before the last
    					--		headers = "Language; i18n Key; Previous translation; New translation; Module",
    							if i18n[refer_lang] then
    								strnew = i18n[refer_lang][keyi18n] or "strnew"
    							end
    							table.insert( changingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["stri18n"] = stri18n, ["strnew"] = strnew,
    							["counts"] = "changing: " .. nkeys .. " / " .. nerr, ["modul"] = modul} )
    							nerr = nerr + 1
    						end
    					end
    				end
    			end
    			if nkeys > max then max = nkeys end
    		end
    		prev_lang = refer_lang
    		prev_table = next_table
    	end
    	if nerr > 0 then
    		err = events.add_err("versions_module_miss_i18n_count_err", nerr, max)
    		t = t .. "<br>" .. err .. " "
    		errors = errors .. err
    		cats = cats .. events.add_cat("versions_err_module_miss_i18n_cat")
    	else
    		errors = errors .. " no errors "
    --		err = events.add_wng("versions_module_miss_i18n_none_err")
    	end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = changingGroup,
    	langs_changing_translations_title	= "langs.changing_translations() Changing (or missing) translations in i18n tables.",
    	langs_changing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module",
    		title_memo = "langs_changing_translations_title",
    		headers = "Language; Key; Translation; N errs / N keys, Module",
    		headers = "langs_changing_translations_headers", -- CHANGING headers = "Language; Key; Previous translation; New translation; Module",
    		headers = "Language; i18n Key; Previous translation; New translation; counts; Module",
    		kind = "projects", -- MediaWiki or projects
    		typ = "err",
    		rowGroup = {}, -- tests or tab_view.test_group or
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		return { case.lang, case.keyi18n, case.stri18n, case.strnew, case.counts, case.modul, }-- "Language; Key; Previous translation; New translation; Module"
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	errors = errors or " no errors "
    	if errors ~= "" then errors = viewers.styles_color_error(errors) end
    	t = t .. viewers.ta("#tab_view.rowGroup", lua_table.level_count(tab_view.rowGroup) ) -- Formats a table with lines and columns.
    	viewers.restore_configs(memo, "langs.changing_translations") -- Close a cats and errors table. For one test or main module.
    	return t --, errors -- translate_missing_translations_title
    end -- function langs.changing_translations(t)
    
    function langs.missing_translations_init(t) -- Initialize the list of known translations, and their counts.
    	local t = t or ""
    	langs.known_translations = langs.known_translations or {}
    	local i18n = versions.memo_i18n
    	langs.known_langs = i18n
    	langs.known_texts = {}
    	langs.known_langs_maxi = 0
    	langs.known_texts_maxi = 0
    	for refer_lang, next_table in pairs(i18n) do -- For all languages and texts to translate
    		if (type(other_trans) == "table") then
    			langs.known_langs[refer_lang] = refer_lang
    			t = t .. "\n* for refer_lang : " .. viewers.ta("refer_lang", refer_lang) .. viewers.ta("#next_table", lua_table.level_count(next_table) )
    			for name, txt in pairs(next_table) do -- mix translations for 1 language in 1 library
    			--	table.insert( langs.known_texts, { name = txt } )
    				langs.known_texts[name] = txt
    			end
    			t = t .. " end for : " .. viewers.ta("#langs.known_texts", lua_table.level_count(langs.known_texts) )
    		end
    	end
    	t = t .. "\n* i18n end: " .. viewers.ta("#langs.known_langs", lua_table.level_count(langs.known_langs) ) .. viewers.ta("#langs.known_texts", lua_table.level_count(langs.known_texts) )
    	if (langs.known_langs_maxi < lua_table.level_count(i18n) ) then langs.known_langs_maxi = lua_table.level_count(i18n) end -- Maximum number of languages
    	return t
    end
    
    function langs.missing_translations(t) -- List all missing translations
    	local memo = viewers.save_configs("langs.missing_translations") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>langs.missing_translations()</b>: List all missing translations: "
    	local i18n = versions.memo_i18n
    	local errors = "*"
    	local changingGroup = {}
    	local missingGroup = {}
    	langs.translations_differences = langs.translations_differences or {}
    	local nerr, trans, err = 0, "", ""
    	local nbr, nbr_in_lang, list = 0, 1, ""
    	local nbr_in_lang_limit = 4
    	local prev_table, next_table, max, nkeys = {}, {}, 0, 0
    	local lang, prev_lang, refer_lang, cats = "", "", "", ""
    	local refer_stri18n, other_stri18n = "-"
    	local count_known_texts = lua_table.level_count(langs.known_texts)
    	local count_changingGroup = lua_table.level_count(changingGroup)
    	local count_missingGroup
    	t = t .. langs.missing_translations_init(t) -- Initialize the list of known translations, and their counts.
    	t = t .. "\n* Insure next_table is OK: "
    	nkeys = 0
    	local err_in_refer_lang, err_in_other_lang, err_in_refer_lang_limit = 0, 0, 5
    	for refer_lang, refer_trans in pairs(langs.known_langs) do -- for all languages
    if not ( (refer_lang == "en") or (refer_lang == "es") or (refer_lang == "fr") ) then -- small langs for tests debug
    		t = t .. ", L=" .. refer_lang ..": n=".. lua_table.level_count(refer_trans)
    		refer_trans = i18n[refer_lang]
    		for other_lang, other_trans in pairs(langs.known_langs) do -- Look at all translations in one language, but check them only from 1 to nbr_in_lang_limit.
    if not ( (other_lang == "en") or (other_lang == "es") or (other_lang == "fr") ) then -- small langs for tests debug
    			t = t .. ", O=" .. other_lang ..": n=".. lua_table.level_count(other_trans)
    			if (type(other_trans) == "table") then -- if the translations in the alternate language is ok
    				t = t .. ", nlt=" .. refer_lang
    				for keyi18n, stri18n in pairs(refer_trans) do -- Look at all translations
    					local cut = string.find(tostring(keyi18n) .. "_", "_")
    					local modul = string.sub(keyi18n, 1, cut - 1)
    					refer_stri18n = i18n[refer_lang][keyi18n]
    					other_stri18n = i18n[other_lang][keyi18n]
    					count_known_texts = lua_table.level_count(langs.known_texts)
    					count_changingGroup = lua_table.level_count(changingGroup)
    					if (not other_stri18n) and (err_in_refer_lang < err_in_refer_lang_limit) then -- if missing
    						err_in_refer_lang = err_in_refer_lang + 1
    						count_missingGroup = lua_table.level_count(missingGroup) + 1
    						local missing_case = { ["refer_lang"] = refer_lang, ["other_lang"] = other_lang, ["keyi18n"] = keyi18n,
    							["refer_stri18n"] = refer_stri18n, ["counts"] = viewers.form9user("counts missing=%1 / changing=%2 (err n=%3)",
    							count_missingGroup, count_changingGroup, count_known_texts, err_in_refer_lang), ["modul"] = modul, }
    						table.insert( missingGroup, missing_case )
    						t = t .. viewers.form9user(
    							"\n* missing err: refer_lang=%1, other_lang=%2, missing=%3 / changing=%4, keyi18n=%5",
    											refer_lang, other_lang, count_missingGroup, count_changingGroup, keyi18n)
    					elseif (other_stri18n ~= refer_stri18n) and (err_in_other_lang < err_in_refer_lang_limit) then -- if changing
    						err_in_other_lang = err_in_other_lang + 1
    						count_changingGroup = lua_table.level_count(changingGroup) + 1
    						local counts = viewers.form9user("refer_lang=%1, other_lang=%2, counts changing=%1 / missing=%2, texts=%3",
    							refer_lang, other_lang, count_changingGroup, count_missingGroup, count_known_texts, err_in_other_lang)
    						local changing_case = { ["refer_lang"] = refer_lang, ["other_lang"] = other_lang, ["keyi18n"] = keyi18n,
    							["refer_stri18n"] = refer_stri18n, ["other_stri18n"] = other_stri18n, ["counts"] = counts, ["modul"] = modul, }
    						table.insert( changingGroup, changing_case )
    						t = t .. viewers.form9user(
    							"\n* changing err: refer_lang=%1, other_lang=%2, changing=%3 / missing=%4, keyi18n=%5",
    											refer_lang, other_lang, count_changingGroup, count_missingGroup, keyi18n)
    					end
    				end
    			end
    end -- small langs for tests debug
    		end
    end -- small langs for tests debug
    	end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = missingGroup,
    	langs_missing_translations_title	= "langs.missing_translations() Missing translations in i18n tables.",
    	langs_missing_translations_headers	= "Language; i18n Key; Previous translation; New translation; Module",
    		title_memo = "langs_missing_translations_title",
    		headers = "langs_missing_translations_headers", -- MISSING "Language; i18n Key; Previous translation; New translation; Module",
    		headers = "Languages; missing Key; Previous translation; New translation; Module",
    		kind = "projects", -- MediaWiki or projects
    		typ = "err",
    		rowGroup = {}, -- tests or tab_view.test_group or
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		return { (case.modul or "modul") .." : ".. (case.refer_lang or "lang") .."/".. (case.other_lang or "lang"),
    		case.keyi18n, case.refer_stri18n, case.other_stri18n, (case.counts or "counts"), }
    	--	headers = "Language; missing Key; Previous translation; New translation; Counts Module",
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	tab_view.test_group = changingGroup
    	tab_view.rowGroup = {}
    	tab_view.headers = "Language; changing Key; Previous translation; New translation; Counts Module"
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local modul_refer_other = (case.modul or "modul") .." : ".. (case.refer_lang or "refer_lang") .."/".. (case.other_lang or "other_lang")
    		return { modul_refer_other, case.keyi18n, case.other_stri18n, case.refer_stri18n, (case.counts or "counts"), }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "langs.missing_translations") -- Restore global configurations after eventual changes.
    	return t --, errors -- langs_missing_translations_title
    end -- function langs.missing_translations(t)
    
    function langs.i18n_lister(t, i18n_tables)
    	if type(i18n_tables) ~= "table" then i18n_tables = versions.memo_i18n end
    	local t = t or "\n* <b>i18n_lister</b> :"
    	t = t .. viewers.styles_color_error("\n* <b>This list show all the string, but cannot replace the original declarations.</b> ")
    	t = t .. viewers.styles_color_error("\n* <b>" .. viewers.form9user("langs_i18n_list_all_string") .. " </b> " )
    	for lang, lang_table in pairs(i18n_tables) do
    		t = t .. "\np.i18n." .. lang .. ' = { '
    		if type(lang_table) == "table" then
    			for key, text in pairs(lang_table) do
    				if key and text then
    					t = t .. "\n:" .. key .. ' = "' .. text .. '",'
    				end
    			end
    		end
    		t = t .. "\n}\n"
    	end
    	return t
    end -- function langs.i18n_lister(t, i18n_tables)
    
    -- - - - ------------------ - - - - ---------------------------------
    -- Manage translations of arguments and warnings
    -- Gestione traducciones de argumentos y advertencias
    -- Gérer les traductions des arguments et warnings
    -- - - - ------------------ - - - - ---------------------------------
    
    function langs.dummy_languages() -- Test dummy languages S170614tva
    	-- https://fr.wikipedia.org/wiki/%C3%89tiquette_d%27identification_de_langues_IETF
    	-- https://fr.wikipedia.org/wiki/Module:Langue/Data
    	--	pour convertir en code de langue IETF les noms français de langues
    	-- https://www.MediaWiki.org/wiki/Manual:$wgDummyLanguageCodes
    	--	List of language codes that have been renamed to new (correct) codes, or don't correspond to an actual interface language.
    	--	array( 'als' => 'gsw', 'bat-smg' => 'sgs', 'be-x-old' => 'be-tarask', 'bh' => 'bho'...
    	langs.MetaSupportedLanguages = { "ja", "es", "ru", "de", "nl", "tr", "fr", "pt", "ko", "en", "it", "oc",
    		"pl", "fa", "ar", "vi", "arz", "hi", "sv", "diq", "pt-br", "zh", "th", "bg", "hu", "uk", "en-gb",
    		"sh", "id", "bn", "az", "fi", "be", "he", "eo", "el", "sd", "kn", "ro", "yue", "sr", "mk", "ta",
    		"pa", "hy", "lb", "tt", "si", "yi", "ne", "cs", "sk", "ms", "eu", "mr", "sa", "tl", "eml",
    		-- https://meta.wikimedia.org/wiki/Special:SupportedLanguages on 20170629 Rical
    	} --  58 languages in total.
    	local dummy_i18n = {
    		en = "Module:Centralizer/I18N", -- english
    		es = "Modul:Central/I18N", -- spanish
    		fr = "Module:Centralizer/I18N", -- french
    		Fr = "Module:Centralizer/I18N", -- error test
    		als = "Modulen:Central/I18N", -- alemanish
    		gsw = "Mod-gsw:Central/I18N", -- unknown
    		["bat-smg"] = "Mod-bat-smg:Central/I18N", -- alemanish
    		sgs = "Mod-sgs:Central/I18N", -- unknown
    	}
    	local t = '\n* langs.dummy_languages() : ' ..  viewers.ta("isTag", "isKnownLanguageTag(xx)") .. viewers.ta("isLang", "isSupportedLanguage(xx)") .. viewers.ta("isBuilt", "isValidBuiltInCode(xx)")
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ "en", "Module:Centralizer/I18N", }, -- english
    			{ "es", "Modul:Central/I18N", }, -- spanish
    			{ "fr", "Module:Centralizer/I18N", }, -- french
    			{ "Fr", "Module:Centralizer/I18N", }, -- error test
    			{ "als", "Modulen:Central/I18N", }, -- alemanish
    			{ "gsw", "Mod-gsw:Central/I18N", }, -- unknown
    			{ "he", "יחידה:Central/I18N", }, -- hebrew
    			{ "bat-smg", "Mod-bat-smg:Central/I18N", }, -- alemanish
    			{ "sgs", "Mod-sgs:Central/I18N", }, -- unknown
    		},
    		title_memo = "langs_dummy_languages_title", -- "lua_table.to_list() Return a list from a Lua table.",
    		headers = "langs_dummy_languages_headers", --
    		headers = " lang; isTag; isLang; isBuilt; langname; native ", --
    		rowGroup = {},
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local lang, modname = case[1], case[2]
    		if (type(lang) ~= "string") then lang = "-" end
    		local isTag			= mw.language.isKnownLanguageTag(lang)
    		local langname		= mw.language.fetchLanguageName(lang, "en") -- see langs.select_lang
    		local native		= mw.language.fetchLanguageName(lang)
    		local isRTL			= mw.language.fetchLanguageName(lang)
    --		local isLang		= mw.language.isSupportedLanguage(lang)
    		local isBuilt		= mw.language.isValidBuiltInCode(lang)
    		local space_name	= tostring(mw.site.namespaces.Module.name)
    		return { lang, isTag, tostring(isLang), isBuilt, langname, native, space_name, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	return t
    end -- function langs.dummy_languages()
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:lua_table enhances the support of previous table library from Lua.
    --	"lua_table" avoids ambiguities with other kind of tables.
    --	To enhance, we could write here : lua_table = table.
    --	see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    --	lua_table = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    
    --	The Module:Centralizer/I18N translations for lua_table library update and complete Module:Centralizer translations.
    lua_table.i18n = {} -- Translations for lua_table library
    lua_table.i18n.br = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table récursive",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Test: Former un code Lua grossier d'une table",
    	luaTable_structure_level_maxi		= "Limite de niveau recursif = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Limite de longueur max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Lister une table, test avec ou sans limites :",
    	luaTable_toList_tests_title			= "lua_table.to_list() Retourne une liste à partir d'une table Lua.",
    	luaTable_toList_tests_headers		= "Cas testé; Table à lister, vue brute; Liste de sortie",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Test: convertir une phrase en table de mots",
    	luatable_form_subcounts_subtables	= "La table <b>%1</b> compte <b>%2</b> variables, <b>%3</b> sous-tables, <b>%4</b> fonctions.",
    	luaTable_fromsubnames_base_err		= "Erreur interne: dans langs.sub_i18n_counts(), base indisponible pour la table subnames <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Erreur interne: dans langs.sub_i18n_counts(), <b>%1</b> n'est pas une sous-table dans subnames <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "Un <b>%1</b> remplace la table : <b>%2</b>.",
    --	luaTable_fromsubnames_missing_err	= "Erreur interne : in lua_table.form_sub_counts() La recherche de cette sous-table <b>%1</b> n'a trouvé que celle-ci <b>%2</b>.", obsolete
    	luaTable_fromsubnames_tests_headers = "Sous-nom; Table de base; Taille de la table; Entrée lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "La table <b>%1</b> n'existe pas.",
    	luaTable_table_args_source_title	= "lua_table.structure() Table des arguments reçus, args_source :",
    	luaTable_tables_differences_title	= "Signaler les différences entre 2 tables.",
    } -- lua_table.i18n.br
    lua_table.i18n.de = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table rekursive",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Test: Bilden Sie einen groben Lua-Code aus einer Tabelle",
    	luaTable_structure_level_maxi		= "Rekursives Level-Limit = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Längenbegrenzung max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Listen Sie eine Tabelle auf, testen Sie mit oder ohne Grenzen:",
    	luaTable_toList_tests_title			= "lua_table.to_list() Gibt eine Liste aus einer Lua-Tabelle zurück.",
    	luaTable_toList_tests_headers		= "Fall getestet; Tabelle zu Liste, grobe Ansicht; Freigabeliste",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Test: Konvertiere einen Satz in eine Worttabelle",
    	luatable_form_subcounts_subtables	= "Die Tabelle <b>%1</b> zählt <b>%2</b> Variablen, <b>%3</b> Untertabellen, <b>%4</b> Funktionen.",
    	luaTable_fromsubnames_base_err		= "Interner Fehler: in langs.sub_i18n_counts(), Basis für die Tabelle der Unternamen nicht verfügbar <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Interner Fehler: In langs.sub_i18n_counts(), ist <b>%1</b> keine Untertabelle in Unternamen <b>%2</b>.",
    	luaTable_fromsubnames_subtable_err	= "Interner Fehler: In langs.sub_i18n_counts(), <b>%1</b> ist keine Untertabelle in Unternamen <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "Ein <b>%1</b> ersetzt die Tabelle: <b>%2</b>.",
    	luaTable_fromsubnames_tests_headers = "Teilname; Basistabelle; Größe des Tisches; Eintrag lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "Tabelle <b>%1</b> existiert nicht.",
    	luaTable_table_args_source_title	= "lua_table.structure() Tabelle der Argumente erhaltenTabelle der Argumente erhalten, args_source:",
    	luaTable_tables_differences_title	= "Berichten Sie die Unterschiede zwischen 2 Tabellen.",
    } -- lua_table.i18n.de
    lua_table.i18n.en = {
    	luaTable_recursive_luaTable_title	= "MediaWiki recursive lua_table",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Test: Formats a rough Lua code of a table",
    	luaTable_structure_level_maxi		= "Recursive level limit = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Length limit max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() List a table, test with or without limits:",
    	luaTable_toList_tests_title			= "lua_table.to_list() Return a list from a Lua table.",
    	luaTable_toList_tests_headers		= "Tested case; Input table, rough_view; Output list",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Test: convert a string to a table of words",
    	luatable_form_subcounts_subtables	= "The table <b>%1</b> counts <b>%2</b> values, <b>%3</b> sub-tables and <b>%4</b> functions.",
    	luaTable_fromsubnames_base_err		= "Internal error: in langs.sub_i18n_counts(), base unavailable for the subnames table <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Internal error: in langs.sub_i18n_counts(), <b>%1</b> is not a sub-table in subnames <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "A <b>%1</b> replaces the table: <b>%2</b>.",
    --	luaTable_fromsubnames_missing_err	= "Internal error: in lua_table.form_sub_counts() The search for this sub-table <b>%1</b> found only this one <b>%2</b>.", obsolete
    	luaTable_fromsubnames_tests_headers = "Sub name; Base table; Table count; Input lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "The table <b>%1</b> does not exist.",
    	luaTable_table_args_source_title	= "lua_table.structure() Table of received arguments, args_source:",
    	luaTable_tables_differences_title	= "report differences between 2 tables.",
    } -- lua_table.i18n.en
    lua_table.i18n.es = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table recursiva",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Prueba: Formar un código de Lua grueso de una tabla",
    	luaTable_structure_level_maxi		= "Límite de nivel recursivo = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Límite de longitud max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Enumerar una tabla, prueba con o sin límites:",
    	luaTable_toList_tests_title			= "lua_table.to_list() Devolver una lista de una tabla Lua.",
    	luaTable_toList_tests_headers		= "Probados casos; Tabla a listar, ver prima; lista de salida",
    	luaTable_toTable_tests_title		= "Prueba: convertir una cadena en una tabla de palabras",
    	luatable_form_subcounts_subtables	= "La tabla <b>%1</b> cuenta <b>%2</b> valores, <b>%3</b> sub-tablas y <b>%4</b> funciones.",
    	luaTable_fromsubnames_base_err		= "Error interno: en langs.sub_i18n_counts(), base no disponible para la tabla subnames <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Error interno: en langs.sub_i18n_counts(), <b>%1</b> no es una sub-tabla en subnames <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "Un <b>%1</b> reemplaza la tabla: <b>%2</b>.",
    --	luaTable_fromsubnames_missing_err	= "Error interno: in lua_table.form_sub_counts() La búsqueda de este subtabla <b>%1</b> encontró que <b>%2</b>.", obsolete
    	luaTable_fromsubnames_tests_headers = "Sub nombre; Mesa base; Tamaño de la mesa; lua_table.rough_view de entrada",
    	luaTable_table_dont_exists_err		= "La tabla <b>%1</b> no existe.",
    	luaTable_table_args_source_title	= "lua_table.structure() Tabla de argumentos recibido, args_source:",
    	luaTable_tables_differences_title	= "Reportar diferencias entre 2 tablas.",
    } -- lua_table.i18n.es
    lua_table.i18n.fr = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table récursive",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Test: Former un code Lua grossier d'une table",
    	luaTable_structure_level_maxi		= "Limite de niveau recursif = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Limite de longueur max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Lister une table, test avec ou sans limites :",
    	luaTable_toList_tests_title			= "lua_table.to_list() Retourne une liste à partir d'une table Lua.",
    	luaTable_toList_tests_headers		= "Cas testé; Table à lister, vue brute; Liste de sortie",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Test: convertir une phrase en table de mots",
    	luatable_form_subcounts_subtables	= "La table <b>%1</b> compte <b>%2</b> variables, <b>%3</b> sous-tables, <b>%4</b> fonctions.",
    	luaTable_fromsubnames_base_err		= "Erreur interne: dans langs.sub_i18n_counts(), base indisponible pour la table subnames <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Erreur interne: dans langs.sub_i18n_counts(), <b>%1</b> n'est pas une sous-table dans subnames <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "Un <b>%1</b> remplace la table : <b>%2</b>.",
    --	luaTable_fromsubnames_missing_err	= "Erreur interne : in lua_table.form_sub_counts() La recherche de cette sous-table <b>%1</b> n'a trouvé que celle-ci <b>%2</b>.", obsolete
    	luaTable_fromsubnames_tests_headers = "Sous-nom; Table de base; Taille de la table; Entrée lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "La table <b>%1</b> n'existe pas.",
    	luaTable_table_args_source_title	= "lua_table.structure() Table des arguments reçus, args_source :",
    	luaTable_tables_differences_title	= "signaler les différences entre 2 tables.",
    } -- lua_table.i18n.fr
    lua_table.i18n.hu = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table rekurzív",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Teszt: Formázz egy durva Lua kódot egy asztaltól",
    	luaTable_structure_level_maxi		= "Rekurzív szintű határérték = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Hossza határ max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Sorolja fel a táblázatot, próbálkozzon korlátozásokkal vagy anélkül :",
    	luaTable_toList_tests_title			= "lua_table.to_list() Visszaad egy listát egy Lua asztalról.",
    	luaTable_toList_tests_headers		= "Esettanulmány; Táblázat lista, durva nézet; Kiadási lista",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Teszt: egy mondatot egy szótáblára konvertál",
    	luatable_form_subcounts_subtables	= "A <b>%1</b> táblázatok <b>%2</b> változókat, <b>%3</b> al-táblákat, <b>%4</b>.",
    	luaTable_fromsubnames_base_err		= "Belső hiba: be langs.sub_i18n_counts(), alap nem áll rendelkezésre az almenük táblázata számára <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Belső hiba: be langs.sub_i18n_counts(), A <b>%1</b> nem alatti név az almenekben <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "A <b>%1</b> táblázat helyettesíti az asztalt: <b>%2</b>.",
    	luaTable_fromsubnames_tests_headers = "Sub-név; Base asztal; A táblázat mérete; belépés lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "A <b>%1</b> táblázat nem létezik.",
    	luaTable_table_args_source_title	= "lua_table.structure() A kapott érvek táblázata, args_source :",
    	luaTable_tables_differences_title	= "Jelenteni a különbségeket a két táblázat között.",
    } -- lua_table.i18n.hu
    lua_table.i18n.vi = {
    	luaTable_recursive_luaTable_title	= "MediaWiki lua_table đệ quy",
    	luaTable_rough_view_tests_title		= "lua_table.rough_view() Kiểm tra: Tạo thành một mã Lua thô từ một bảng",
    	luaTable_structure_level_maxi		= "Giới hạn mức đệ quy = <b>%1</b> ",
    	luaTable_table_listlimit_max_n		= "Giới hạn độ dài max_n = <b>%1</b> ",
    	lua_table_structure_recursive_report= "lua_table.structure() Liệt kê một bảng, kiểm tra có hoặc không có giới hạn:",
    	luaTable_toList_tests_title			= "lua_table.to_list() Trả về danh sách từ bảng Lua.",
    	luaTable_toList_tests_headers		= "Trường hợp được kiểm tra; Bảng vào danh sách, xem thô; Danh sách phát hành",
    	luaTable_toTable_tests_title		= "lua_table.to_table() Kiểm tra: chuyển đổi một câu thành một bảng từ",
    	luatable_form_subcounts_subtables	= "Bảng <b>%1</b> đếm <b>%2</b> biến, <b>%3</b> bảng phụ, <b>%4</b> chức năng.",
    	luaTable_fromsubnames_base_err		= "Lỗi nội bộ: trong ngôn langs.sub_i18n_counts(), cơ sở không có sẵn cho bảng subnames <b>%1</b>.",
    	luaTable_fromsubnames_subtable_err	= "Lỗi nội bộ: trong ngôn langs.sub_i18n_counts(), <b>%1</b> không phải là một bảng phụ trong subnames <b>%2</b>.",
    	luaTable_form_sub_counts_type_err	= "Một <b>%1</b> thay thế bảng: <b>%2</b>.",
    	luaTable_fromsubnames_tests_headers = "Sub-tên; Bảng cơ sở; Kích thước để bảng; lối vào lua_table.rough_view",
    	luaTable_table_dont_exists_err		= "Bảng <b>%1</b> không tồn tại.",
    	luaTable_table_args_source_title	= "lua_table.structure() Bảng đối số nhận được, args_source:",
    	luaTable_tables_differences_title	= "Báo cáo sự khác biệt giữa 2 bảng.",
    } -- lua_table.i18n.vi
    
    function lua_table.from_subnames_object(sub_names, base_table) -- Get the last sub-object from its sub-names, but not a table.
    	local sub_obj = nil
    	if (type(base_table) ~= "table")then base_table = package.loaded end
    	local sub_names = mw.text.split(sub_names, '%.') -- table of words
    	local sub_tab, sub_obj = base_table, nil
    	for i, sub_name in ipairs(sub_names) do
    		sub_obj = sub_tab[sub_name]
    		if (type(sub_obj) == "table") -- the search continue in sub tables and cannot search a table
    		then sub_tab = sub_obj
    		else break end -- get the last object which is not a table
    	end
    	return sub_obj
    end
    
    function lua_table.from_subnames_table(sub_names, base_table) -- Get the last sub-table from its sub-names.
    -- S170625ste sub_tab is bad, but it run
    	if (type(base_table) ~= "table")then base_table = package.loaded end
    	local sub_names = mw.text.split(sub_names, '%.') -- table of words
    	local sub_tab = base_table
    	for i, sub_name in ipairs(sub_names) do
    		if (type(sub_tab) == "table") and (type(sub_tab[sub_name]) == "table")
    		then sub_tab = sub_tab[sub_name]
    		else sub_tab = nil end
    	end
    	return sub_tab
    end
    
    function lua_table.named_sub_counts(subnames_in, base_table) -- Count all objects of all types in all levels, in the sub-tables from their sub-names.
    	local t = "\n* lua_table.named_sub_counts() Count all objects of all types in all levels"
    	if (type(subnames_in) ~= "string") then subnames_in = "." end
    	-- Default base_table for libraries and modules.
    	local base_table = base_table -- Do not disturb other processes through an external pointer.
    	if (type(base_table) ~= "table") then base_table = package.loaded end
    --	luaTable_fromsubnames_base_err		= "Internal error: in langs.sub_i18n_counts(), base unavailable for the subnames table %1.",
    	local subnames, k = "", ""
    	local count, pre_count, errs = 0, 0, ", errs: "
    	local subnames_tab = mw.text.split(subnames_in, '.', true)
    	local subnames_1 = subnames_tab[1]
    	-- Default base_table for not loaded libraries.
    	if (type(base_table) ~= "table") and (type(subnames_1) == "string") and (type(_G[subnames_1]) == "table") then base_table = _G end
    	local sub_table, object_loaded = base_table, sub_table
    	local obj_typ, count, pre_count = "string", 0, 0
    	local counts, all_counts = {}, {}
    	local pre_counts = nil
    	local functions_c, numbers_c, strings_c, tables_c, last_count, all_strings, sub_tables_count = 0, 0, 0, 0, 0, 0, 0, 0
    	local isi18n, endi18n, to_break = false, false
    	local max_string_count, max_tables_count, missing_trans = 0, 0, 0, 0
    	local loop = 1
    	for i, partname in pairs(subnames_tab) do
    		loop = loop + 1
    		subnames = subnames .. "." .. partname
    		object_loaded = sub_table[partname]
    		obj_typ = type(object_loaded)
    		all_strings = 0
    		functions_c, numbers_c, strings_c, tables_c, sub_tables_count = 0, 0, 0, 0, 0
    		endi18n = string.sub(subnames, -4, -1) -- Is this an i18n table?
    		isi18n = (endi18n == "i18n") -- Is this an i18n table?
    		if (type(object_loaded) == "table") then -- Count languages tables.
    			if isi18n then -- Count languages tables.
    				for key, val in pairs(object_loaded) do
    					if (type(val) == "table") then tables_c = tables_c + 1 end
    					loop = loop + 1
    					if loop > 99 then break end
    				end
    				sub_tables_count = 0
    				for key, val in pairs(object_loaded) do
    					if (type(val) == "table") then
    						sub_tables_count = sub_tables_count + 1
    						all_strings = all_strings + lua_table.count_all(val)
    					end
    				end
    			else -- Count translations in this table.
    				for key, val in pairs(object_loaded) do
    					if (type(val) == "string") then
    						strings_c = strings_c + 1
    						if strings_c > max_string_count then max_string_count = strings_c end
    					elseif (type(val) == "number") then
    						numbers_c = numbers_c + 1
    					elseif (type(val) == "function") then
    						functions_c = functions_c + 1
    					end
    					loop = loop + 1
    					if loop > 99 then break end
    				end
    			end
    		--	local strs_on_tabs = all_strings / tables_c, ["subnames"] = subnames, obj = object_loaded, typ = obj_typ,
    			local strs_on_tabs = math.floor( (all_strings + 0.49) / math.min(sub_tables_count, 1) )
    			-- 1/1 = 1.4/1 = 1		3/3 = 3.4/3 = 1.13 = 1		10/2 = 10.5/2 = 5.25 = 5
    			counts = { ["i"] = i, ["partname"] = partname, ["subnames"] = subnames,
    				["object_loaded"] = object_loaded, ["obj_typ"] = obj_typ, ["isi18n"] = isi18n, ["endi18n"] = endi18n,
    				["tables_c"] = tables_c, ["strings_c"] = strings_c, ["numbers_c"] = numbers_c,
    				["functions_c"] = functions_c, ["booleans_c"] = booleans_c,
    				["all_strings"] = all_strings, ["max_string_count"] = max_string_count,
    				["pre_counts"] = pre_counts, ["all_counts"] = all_counts,
    				-- details:
    				["strs_on_tabs"] = strs_on_tabs, ["missing_trans"] = missing_trans, -- special langs, remove here
    				["sub_tables_count"] = sub_tables_count, -- special langs, remove here, obsolete, replaced by pre_counts
    				["to_break"] = to_break, ["loop"] = loop, -- internal, anticrash and tests only
    			}
    			table.insert(all_counts, counts) -- Build a table with translations counts.
    			if (type(pre_counts) == "table") and (type(counts) == "table") then
    				counts.pre_counts = pre_counts
    				pre_counts.post_counts = counts
    			end
    			pre_counts = counts
    			counts.tt = viewers.form9user( "\n* counts: %1, %2, %3, %4, %5, %6.", counts.i, counts.partname, counts.endi18n, counts.strings_c, counts.tables_c, counts.all_strings)
    			if loop > 99 then break end
    		end
    		t = (t or "t") .. (counts.tt or "counts.tt")
    	end
    	local strs_on_tabs = math.floor( (strings_c + 0.49999) / math.min(tables_c, 1) )
    	counts.t = (t or "t")
    	return strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts, counts.t
    --	local strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts, t = lua_table.named_sub_counts(subnames_in, base_table)
    end -- function lua_table.named_sub_counts(subnames_in, base_table)
    
    function lua_table.count_all(tab) -- Count all objects in the table.
    	local count = 0
    	for key, elem in pairs(tab or {}) do count = count + 1 end
    	return count
    end
    
    function lua_table.count_types(tab) -- Count in the table, for each type, the number of objects of the this type.
    	local types_counts = {} -- S170620csc
    	for key, obj in pairs(tab or {}) do
    		types_counts[type(obj)] = (types_counts[type(obj)] or 0) + 1
    	end
    	return types_counts
    end
    
    function lua_table.count_values(tab) -- Count in the table, for each value, the number of objects of the this value.
    	local values_counts = {}
    	for key, obj in pairs(tab or {}) do
    		values_counts[obj] = (values_counts[obj] or 0) + 1
    	end
    	return values_counts
    end
    
    function lua_table.counts(obj, opt) -- Counts in object types
    	local t = t or "\n* <b>lua_table.counts()</b>: Counts in object types, where, what, how, sort." -- to_debug_on_20170503
    	tab_view.t = tab_view.t or "-"
    	t = t .. viewers.ta("count_done", count_done) .. viewers.ta("count_now", count_now) .. viewers.ta("count_later", count_later)
    	local counts_fields = { -- define counts : caracterize available counts
    		where_to_count = { "string table numbers function", }, -- Detect object type to count. Convert from function.
    		where_to_count = { "tostring totable tonumbers", }, -- Convert asked totable() or tostring() or tonumber()
    		which_part = { "coli coln colname rowi rown rowname", }, -- in which object part to count : column i, named row
    		what_to_count = { "column_i column_n row_i row_n word_i word_n group_i group_n", }, -- count in the column_i. count column_n = the number of columns
    		how_to_count = { "group_i group_n", }, -- group_i = number of objects in which_part
    		how_to_sort = { "nosort 0to9 9to0 atoz ztoa", }, -- sort or no, in alpha or digital, increasing decreasing or none
    		example_1 = { opt = "tostring ztoa", }, -- Count words in a string. Sort in reverse order.
    		example_3 = { opt = "totable column_n", }, -- Convert to table or insure that. Count the number of columns.
    		example_2 = { opt = "totable colname group_n 9to0", }, -- Convert to table. Count in column colname. Count in each group_n of values. Sort decreasing.
    	}
    	return count, t -- count can be a number, a list, a simple table, an array table of counts
    end -- count, t = lua_table.counts(obj, opt) -- Counts in object types
    
    function lua_table.to_list(tab, ...) -- Return a list from any Lua table.
    	-- This function is the reverse of func( ... )
    	if (type(tab) ~= "table") then tab = {} end
    	local tab = mw.clone(tab) -- to not disturb original table
    	local maxn = lua_table.count_all(tab)
    	local function tabN_to_list1(tab, n, ...)
    		local max_tab = lua_table.count_all(tab)
    		local listab = {...}
    		local max_list = lua_table.count_all(listab)
    		local tab_last = tab[n] -- last element, even a table to not delete below
    		local tab_last_string = type(tab_last) -- tostring(tab_last)
    		if (type(tab_last) ~= "nil") and (n <= max_tab) then
    			if (type(tab) == "table") then
    				return tab_last, tabN_to_list1(tab, n + 1, ...)
    			else
    				tab_last = tostring(tab_last)
    			end
    		else return end
    	end
    	return tabN_to_list1(tab, 1, ...)
    end -- function lua_table.to_list(tab, ...)
    
    function lua_table.to_list_tests(t) -- Return a list from a Lua table.
    	local memo = viewers.save_configs("lua_table.to_list_tests") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>events.all_kinds_test()</b> Test: all kinds of events (err, wng, cat)"
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ "Simple table", { 123, "abc", key = "txt" }, },
    			{ "All types transmited", { "name", 111, true, false, { 789, "xyz"}, function()end }, },
    			{ "10 values in the table", { "a", "b", "c", "d", "e", "f", "g", "h", "i9", "j10" }, },
    			{ "Any number of values", {
    				"a", "b", "c", "d", "e", "f", "g", "h", "i09", "j10",
    				"a", "b", "c", "d", "e", "f", "g", "h", "i19", "j20",
    				"a", "b", "c", "d", "e", "f", "g", "h", "i29", "j30",
    				"a", "b", "c", "d", "e", "f", "g", "h", "i39", "j40",
    				"a", "b", "c", "d", "e", "f", "g", "h", "i49", "j50",
    				"a", "b", "c", "d", "e", "f", "g", "h", "i59", "j60" }, },
    		},
    		title_memo = "luaTable_toList_tests_title", -- "lua_table.to_list() Return a list from a Lua table.",
    		headers = "luaTable_toList_tests_headers", -- "Tested case; Input table, rough_view; Output list",
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local descript = case[1]
    		local tabview = lua_table.rough_view( case[2] )
    		local tab_list = { lua_table.to_list( case[2] ) }
    		local t1 = ""
    		for i, elem in ipairs(tab_list) do
    			t1 = t1 .. viewers.ta( "[" .. i .. "]", tostring(elem) )
    		end
    		return { descript, tabview, t1, }
    	end
    	local t = tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "lua_table.to_list_tests") -- Restore global configurations after eventual changes.
    	return t --, errors -- langs_missing_translations_title
    end -- function lua_table.to_list_tests(t)
    
    function lua_table.to_table(stringList, pattern, plain) -- convert a string to a table of words
    	if type(stringList) ~= "string" then stringList = "" end
    	if type(pattern) ~= "string" then pattern = "" end
    	if plain then plain = true else plain = false end
    	local tab = mw.text.split(stringList, pattern, plain)
    	local tab2 = {}
    	for i, word in ipairs(tab) do -- for all names
    		word = mw.text.trim(word) -- clean spaces in each name
    		tab2[word] = word -- not table.insert(tab2, name)
    	end
    	return tab2
    end
    
    function lua_table.to_table_test(t) -- Test: convert a string to a table of words
    	local memo = viewers.save_configs("lua_table.to_table_test") -- Save global configuration before eventual changes.
    	local stringList = ""
    	local t = t or "\n* lua_table.to_table_test(t) -- Test: convert a string to a table of words"
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ stringList = "docview nocatview : tests docline",	 pattern = nil, },
    			{ stringList = "docview nocatview : tests docline",	 pattern = " ", plain = nil, },
    			{ stringList = "docview,nocatview, : ,tests docline",  pattern = ",", plain = true, },
    			{ stringList = "docview docline : tests",  pattern = " ", plain = true, },
    			{ stringList = "docview; nocatview; : tests; docline",	pattern = ";", plain = false, },
    			{ stringList = "abc ; ; def.;ghi;,jkl",	 pattern = ";", },
    		},
    		headers = "langs_selectLang_test_headers", -- "stringList; pattern; plain; result"
    		headers = "stringList; pattern; plain; result",
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local tab = lua_table.to_table(case.stringList, case.pattern, case.plain)
    		local t1 = ""
    		for key, elem in pairs(tab) do
    			t1 = t1 .. viewers.ta("[" .. viewers.value(key) .. "]", elem)
    		end
    		return { case.stringList, case.pattern, case.plain, t1, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "lua_table.to_table_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function lua_table.to_table_test(t)
    
    function lua_table.old_to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed. "20180307", "NOW", "Rical", "S180810lts", "new function
    	local opt = opt or {}
    	if (type(tab) ~= "table") then tab = {} end
    	if (type(sortfield) ~= "string") then sortfield = "" end
    	if (type(sortorder) ~= "string") then sortorder = "" end
    	local sorted, i = {}, 0
    	for key, elem in pairs(tab) do
    		i = i + 1
    		table.insert(sorted, elem)
    	end
    	return sorted
    end -- local sorted = lua_table.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    
    function lua_table.to_sort_tests(t) -- To sort any table and convert in sequence if needed.
    	local t = t or "\n* lua_table.to_sort(tab, sortfield, sortorder) Test to sort any table and convert in sequence if needed."
    	local opt = opt or {}
    	local sorted = lua_table.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    	local sorted, i = {}, 0
    	for key, elem in pairs(tab) do
    		i = i + 1
    		elem[sortfield] = i
    		table.insert(sorted, elem)
    	end
    	t = t .. "\n* " .. viewers.ta("tab count", lua_table.level_count(tab) )
    	t = t .. "\n* " .. viewers.ta("sorted count", lua_table.level_count(sorted) )
    	return t
    end -- local sorted = lua_table.to_sort(tab, sortfield, sortorder) -- To sort any table and convert in sequence if needed.
    
    --	local tot_vars, tot_tabs, tot_func, vr_tb = lua_table.sub_counts(tablebase, tabname, opt, recursiveLevel)
    function lua_table.sub_counts(tablebase, tabname, opt, recursiveLevel) -- In a table, recursive counts of vars, sub-tables and functions.
    	local opt = opt or {}
    	opt.recursiveLevel = recursiveLevel or opt.recursiveLevel
    	opt.recursiveLevel, opt.recursive_limit, opt.recursiveLevel_err = modes.recursive_normal(opt.recursiveLevel, modes.recursive_limit)
    	local isempty = true
    	local tot_vars, tot_tabs, tot_func = opt.tot_vars or 0, opt.tot_tabs or 0, opt.tot_func or 0
    	-- lua_table.sub_counts(get.i18n, get.pagename) -- : attempt to index local 'opt' (a nil value).
    	local nbr_vars, nbr_tabs, nbr_func = 0, 0, 0
    	local txt, vr, tb, fn, vrtb, vr_tb = "", 0, 0, 0, 0, 0
    	local case = ""
    	if (type(tablebase) == "table") and (type(tabname) == "string") then -- for any tables
    		-- normal case OK, do nothing
    		case = " tab+name"
    	elseif (type(tablebase) == "table") and (type(tabname) ~= "string") then -- for abnormal or missing tabname
    		tabname = "tabname=" .. tostring(tablebase) .. "?"
    		tabname = viewers.styles_color_error(tabname)
    		case = " tab+noname"
    	elseif (type(tablebase) ~= "table") and (type(tabname) == "string") then -- for abnormal table
    		tabname = "tabname=" .. tostring(tabname) .. "?"
    		tabname = viewers.styles_color_error(tabname)
    		case = " notab+name"
    	elseif type(tablebase) == "string" then -- for viewers.tables
    		tabname = "package.loaded." .. tablebase
    		case = " tab=name"
    	else
    		tabname = "tabname=" .. tostring(tablebase) .. "?"
    		tabname = viewers.styles_color_error(tabname)
    		case = " notab+noname"
    	end
    	if (type(tablebase) == "table") and (type(tabname) == "string") then -- for normal cases
    		for key, var in pairs(tablebase) do -- List and count vars, functions and sub tables
    			local sub_tabname = tostring(key)
    			if type(var) == "table" then
    			local sub_tablebase = var
    				nbr_tabs = nbr_tabs + 1
    				if (opt.recursiveLevel < opt.recursive_limit) then
    			--	if (opt.recursiveLevel > 0) and (opt.recursiveLevel < opt.recursive_limit) then
    				--	vr, tb, fn, vrtb, opt.recursiveLevel = lua_table.sub_counts(var, tabname, opt)
    					opt.recursiveLevel = opt.recursiveLevel + 111
    					vr, tb, fn, vrtb = lua_table.sub_counts(sub_tablebase, sub_tabname, opt, opt.recursiveLevel)
    					tot_vars = tot_vars + vr
    					tot_tabs = tot_tabs + tb + 1
    					tot_func = tot_func + fn
    				end
    			elseif type(var) == "function" then
    				nbr_func = nbr_func + 1
    				tot_func = tot_func + 1
    				isempty = false
    			else -- type(var) == other
    				nbr_vars = nbr_vars + 1
    				tot_vars = tot_vars + 1
    				isempty = false
    			end
    		end
    	end
    	local vr_tb = 0
    	if tot_tabs == 0 then
    		vr_tb = tot_vars -- string number in all languages
    	else -- How many translations in each language? Approximative if not equal.
    		vr_tb = tot_vars / tot_tabs -- string number in one language, like + 33.49
    		vr_tb = math.floor( vr_tb ) -- digital string number in each language
    	end
    	opt.tot_vars = tot_vars -- total number of variables in the table
    	opt.tot_tabs = tot_tabs -- total number of sub-tables in the table
    	opt.tot_func = tot_func -- total number of functions in the table
    	opt.vr_tb = vr_tb -- digital string number in each language
    	return tot_vars, tot_tabs, tot_func, vr_tb -- , opt.recursiveLevel
    end -- local tot_vars, tot_tabs, tot_func, vr_tb = lua_table.sub_counts(tablebase, tabname, opt, recursiveLevel)
    
    function lua_table.level_count(tab) -- Count all objects in the table, or 0 if tab is not a table.
    	local count = 0
    	if (type(tab) ~= "table") then return count end
    	for k,v in pairs(tab) do
    		count = count + 1
    	end
    	return count
    end -- c = lua_table.level_count(tab)
    
    function lua_table.count(t, n) return viewers.ta(t, lua_table.level_count(n)) end -- Is a Syntactic sugar for lua_table.level_count(tab) -- Count all objects or 0.
    
    function lua_table.level_get(tab, typ) -- Get only the first level of the table. Get only one key type if asked.
    	local level = {}
    	local count = 0
    	if (type(tab) ~= "table") then return level, count end
    	for key, val in pairs(tab) do
    		if (type(typ) == "string") and (type(val) == typ)
    		then level[key] = val ; count = count + 1
    		else level[key] = val ; count = count + 1 end
    	end
    	return level, count
    end -- function lua_table.level_get(tab, typ)
    
    function lua_table.level_list(tab, typ, select, field) -- Collect and count selected or all keys, in the first level of the table -- subtasks S170813lll
    	--	typ = "key;val;keys;vals;sort;boolean;function;number;string;table;"
    	-- Get only the first level of the table. Select only keys containing select. Select the field as key if defined.
    	-- Collects and counts the selected keys, or all, in recording order
    	-- Count the key of the typ type
    	local list, count, level, split, ok = "", 0, {}, {}, false
    	local sort, keyval = typ, ""
    	if (type(tab) ~= "table") then return list, count, level, split end
    	for key, val in pairs(tab) do
    		table.insert(level, val)
    		ok = false
    		if (typ == "key") then -- Count and list keys from select and field.
    			sort, keyval = false, key
    			if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    		elseif (typ == "val") then -- Count and list values...
    			sort, keyval = false, val
    			if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    		elseif (typ == "keys") then -- Count and sort keys...
    			sort, keyval = true, key
    			if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    		elseif (typ == "vals") then -- Count and sort values...
    			sort, keyval = true, val
    			if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    		elseif (typ == "sort") then -- Sort all values...
    			sort, keyval = true, tab[field or 1]
    			if viewers.is_in( tostring(keyval), tostring(select) ) then ok = true end -- Select a value if the val is in select.
    		else -- lua_table.count_values()
    			local typ2 = type(typ) -- To select a type or the type of a variable.
    				if (typ2 == "boolean") or (typ == "boolean") then -- Count only these types.
    				if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    			elseif (typ2 == "function") or (typ == "function") then
    				if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    			elseif (typ2 == "number") or (typ == "number") then
    				if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    			elseif (typ2 == "string") or (typ == "string") then
    				if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    			elseif (typ2 == "table") or (typ == "table") then
    				if viewers.is_in(keyval, select) then ok = true end -- Select a value if the val is in select.
    			end
    		end
    		if ok then
    			table.insert(split, keyval) -- Collect the selected keys, or all, in recording order
    			count = count + 1 -- Count the key of the typ type
    			list = list .. tostring(keyval) .. ", " -- List values
    		end
    	end
    	if (sort == "sort") or (sort == true) then table.sort( split ) end -- in alphabetic order -- , function (a, b) end
    	list = table.concat(split, ", ")
    	return list, count, level, split
    end --	local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests(
    
    function lua_table.count_tests(t) -- Count all objects or types or values in the table
    	local memo = viewers.save_configs("lua_table.count_tests") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>lua_table.count_values()</b> Tests: Count all objects or types or values."
    	local test_table = { "name", 111, "other", function() return 2 end, true, false, { 789, "xyz"}, function() return 1 end }
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ "count_all", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, },
    			{ "count_types", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, },
    			{ "count_values", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, },
    			{ "count_all", { a = "abc", 11, z = "xyz", t = true, false, n = nil, min = 11, 33, nil, 33, max = 55, "abc", }, },
    			{ "count_types", { a = "abc", 11, z = "xyz", t = true, false, n = nil, min = 11, 33, nil, 33, max = 55, "abc", }, },
    			{ "count_values", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, },
    			{ "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "key", "3", },
    			{ "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "val", "3", },
    			{ "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "keys", "3", },
    			{ "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "vals", "bc", },
    			{ "level_list", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, "sort", },
    	--	local list, count, level, split = lua_table.level_list(tab, typ, select, field)
    	--	typ = "key;val;keys;vals;sort;boolean;function;number;string;table;"
    			{ "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "boolean", "bc", },
    			{ "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "function", "bc", },
    			{ "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "number", "bc", },
    			{ "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "string", "bc", },
    			{ "level_list", { "abc", { "bcbc", nil }, "bcd", "xyz", { "tab1", "tab2" }, "abc", }, "table", "bc", },
    			{ "level_list", "abcdefg", "table", "bc", },
    			{ "level_list", 12345, "table", "bc", },
    		},
    		title_memo = "lua_table_count_all_values_title", -- "lua_table.count_values() Count all objects or types or values in the table.",
    		headers = "luaTables_count_all_types_values_headers", -- "Tested case; Input table, rough_view; Output list",
    		headers = "Tested table; Function to count; Kind of count; Resulting counts",
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup RIC05900470
    		local func_name = case[1]
    		local test_table = case[2]
    		local count_kind = case[3]
    		if (type(test_table) ~= "table") then test_table = { test_table } end
    	--	if (type(func_name) ~= "string") then test_table = { test_table } end
    		local values_counts = lua_table[func_name](test_table) -- Select the function to test
    		if (type(values_counts) ~= "table") then values_counts = { values_counts } end
    		local tests_view = ""
    		for key, val in pairs(test_table) do
    			val = tostring(val)
    			tests_view = tests_view .. viewers.ta(key, val)
    		end
    		local counts_view = ""
    		for key, val in pairs(values_counts) do
    			val = tostring(val)
    			counts_view = counts_view .. viewers.ta(key, val)
    		end
    		return { tests_view, func_name, count_kind, counts_view }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "lua_table.count_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function lua_table.count_tests(t)
    
    --	opt = { dropit.dropit = "dropit", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- example of use , {width = "88%", tc1 = "blue"}
    function lua_table.normal_options(opt, recursiveLevel, recursive_limit) -- Normalize lua_table options.
    	if type(opt) ~= "table" then opt = {} end
    	if type(opt.level_maxi) ~= "number" then opt.level_maxi = 111 end
    	if type(opt.max_n) ~= "number" then opt.max_n = 9999 end
    	opt.max_n = opt.max_n or 9999
    	opt.recursiveLevel = recursiveLevel or opt.recursiveLevel or 1
    	opt.recursive_limit = recursive_limit or opt.recursiveLevel or 111
    	opt.exclude1 = opt.exclude1 or ""
    	opt.exclude2 = opt.exclude2 or ""
    	opt.exclude3 = opt.exclude3 or ""
    	opt.countonly = opt.countonly and true
    	return opt
    end
    
    function lua_table.rough_view(table, option, level) -- Formats a string to describe a value like: true, 123.456, "abcd", func(), table{}
    	if type(table) ~= "table" then return viewers.value(table) end
    	local opt = option
    	if type(opt) ~= "table" then opt = {} end
    	opt.level = (opt.level or 1)
    	opt.recursive_limit = tonumber(opt.recursive_limit) or 11111
    	if type(level) == "number" then opt.recursive_limit = level end
    	opt.max_n = tonumber(opt.max_n) or 11111
    	local shift = "\n" .. string.rep(":", opt.level)
    	local t = ""
    	local n = 0
    	local continue = true
    	if opt.level > opt.recursive_limit then -- Limit the number of levels of sub-tables to opt.recursive_limit
    		local col = viewers.styles_color_warning( viewers.form9user( '%1 = %2', "recursive_limit", opt.recursive_limit) )
    		t = t .. viewers.form9user( '{ %1 }', col )
    	else
    		shift = "\n" .. string.rep(":", opt.level)
    		for k, v in pairs(table) do
    			n = n + 1
    			if n > opt.max_n then -- Limit the number of elements in each-subtable to opt.max_n.
    				local col = viewers.styles_color_warning( viewers.form9user( '%1 = %2', "max_n", opt.max_n ) )
    				continue = false
    			end
    			if continue then
    				if (type(k) == "string")
    				then t = t .. viewers.form9user( '["%1"] = %2, ', k, tostring(v), shift )
    				else t = t .. viewers.form9user( '[%1] = %2, ', tostring(k), tostring(v), shift ) end
    			end
    		end
    		for k, v in pairs(table) do
    			n = n + 1
    			if n > opt.max_n then
    				local col = viewers.styles_color_warning( viewers.form9user( '%1 = %2', "max_n", opt.max_n ) )
    				continue = false
    			end
    			if continue then -- Do not list if exclude1, exclude2 or exclude3 are in the table name.
    				if (type(v) == "table") and (k ~= opt.exclude1) and (k ~= opt.exclude2) and (k ~= opt.exclude3) then
    					opt.level = (opt.level or 1) + 1
    					shift = "\n" .. string.rep(":", opt.level)
    					local tt = lua_table.rough_view(v, opt)
    					opt.level = (opt.level or 1) - 1
    					shift = "\n" .. string.rep(":", opt.level)
    					t = t .. viewers.form9user( '%3 ["%1"] = %2 ', k, tt, shift )
    				elseif (type(v) == "function") then
    					t = t .. viewers.form9user( '%3 ["%1"] = %2() ', k, "function", shift )
    				elseif (type(v) == "nil") then
    					t = t .. viewers.form9user( '%3 %1 = %2() ', k, "nil", shift )
    				end
    			end
    		end
    	end
    	t = "{ " .. t .. " }"
    	return t
    end -- t =	lua_table.rough_view(table) -- Formats a string to describe a value like: true, 123.456, "abcd", func(), table{}
    
    function lua_table.rough_view_test(t) -- Formats a rough Lua code of the table structure.
    	local memo = viewers.save_configs("lua_table.rough_view_test") -- Save global configuration before eventual changes.
    	local t = t or "lua_table.rough_view_test(t) : From a Lua table, re-form a string roughly equivalent to the table."
    	local table_key = { "A table used as key.", key = "string", bar = "bartxt", }
    	local table_value = { "A table used as value is expended in the main table.", abc = "ABC", [5] = "five", ghi = "JKL", }
    	local tae_val = "A table used as value is expended in the main table."
    	local function funcView() return "A function result in this string." end
    	local test_table = {
    		key = "string",
    		"string one without key",
    		[12] = "number key twelve",
    		["12"] = "string key twelve in brace",
    		sub_table = { [4] = "four", abc = "ABC", [5] = "five", ghi = "JKL", },
    		func = funcView(),
    		"string two without key",
    		[tonumber] = "A function used as key.",
    		[true] = "A Lua reserved value used as key.",
    	}
    	local t = t .. lua_table.rough_view(test_table)
    	viewers.restore_configs(memo, "lua_table.rough_view_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function lua_table.rough_view_test(t)
    
    function lua_table.sort_onkey(tab, key) -- Sort a table with any types of keys.
    	local key = key or "keyword"
    	return table.sort(tab, function (a, b)
    		if (type(a[key]) == type(b[key])) then return ( a[key] < b[key] ) -- any translated arguments of same types
    		else return ( tostring(a[key]) < tostring(b[key]) ) end -- alphabetic sort of translated arguments
    	end )
    end
    
    function lua_table.sort_types(tab, key, decrease) -- Sort a table, with any types of fields, even of differents types as strings.
    	if (type(tab) ~= "table") then return tab end
    	if (type(key) ~= "string") then key = "keyword" end
    	if decrease == ">" then -- sort in decreasing order
    		table.sort(tab, function (a, b)
    							if ( type(a[key]) == type(b[key]) )
    							then return (		  a[key]  >			 b[key]	 )		-- Sort same types
    							else return (tostring(a[key]) > tostring(b[key]) ) end	-- Sort differents types as strings
    						end )
    	else -- sort in increasing order
    		table.sort(tab, function (a, b)
    							if ( type(a[key]) == type(b[key]) )
    							then return (		  a[key]  <			 b[key]	 )		-- Sort same types
    							else return (tostring(a[key]) < tostring(b[key]) ) end	-- Sort differents types as strings
    						end )
    	end
    end -- function lua_table.sort_types(tab, key, decrease)
    
    function lua_table.structure_recursive(tbl, uppername, name, recursiveLevel, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3)
    	if type(tbl) ~= "table" then tbl = {} end
    	if type(uppername) ~= "string" then name = "uppername" end
    	if type(name) ~= "string" then name = "table" end
    	local res, newname, part, shift = "", "", "", ""
    	local sep, N = ", ", 0
    	local isempty = true
    	local levelname = uppername .. "." .. name
    	local tot_vars, tot_func, tot_tabs = 0, 0, 0
    	local nbr_vars, lst_vars = 0, ""
    	local nbr_func, lst_func = 0, ""
    	local nbr_tabs, lst_tabs = 0, ""
    	local max, lst_subtabs = 0, ""
    	local st, vr, fn, tb = "", 0, 0, 0
    	local list = not opt.countonly
    	if recursiveLevel > opt.level_maxi then -- limit the number of the level of sub-tables
    		local t_levelmaxi = viewers.form9user("luaTable_structure_level_maxi", recursiveLevel)
    		return viewers.styles_color_warning( tostring(t_levelmaxi ) ), tot_vars, tot_func, tot_tabs
    	end
    	opt.max_n = tonumber(opt.max_n) or 11111
    	shift = string.rep("*", recursiveLevel)
    	-- Do not list if exclude1, exclude2 or exclude3 is in the table name.
    	if type(opt.exclude1) == "string" and opt.exclude1 ~= "" and string.find(name, opt.exclude1) ~= nil
    	then return "", tot_vars, tot_func, tot_tabs end
    	if type(opt.exclude2) == "string" and opt.exclude2 ~= "" and string.find(name, opt.exclude2) ~= nil
    	then return "", tot_vars, tot_func, tot_tabs end
    	if type(opt.exclude3) == "string" and opt.exclude3 ~= "" and string.find(name, opt.exclude3) ~= nil
    	then return "", tot_vars, tot_func, tot_tabs end
    	if type(tbl) ~= "table" then -- display table error
    		return '<br>The variable "' .. tostring(name) .. '" is not a table.<br>', tot_vars, tot_func, tot_tabs
    	end
    	for k, v in pairs(tbl) do -- List and count vars, functions and sub tables
    		k = tostring(k)
    		if type(v) == "table" then
    			lst_tabs = lst_tabs .. k .. sep
    			nbr_tabs = nbr_tabs + 1
    			isempty = false
    			newname = tostring(k)
    			max = max + 1
    			if recursiveLevel <= opt.level_maxi then -- List recursively each sub-table
    				st, vr, fn, tb = lua_table.structure_recursive(v, levelname, newname, recursiveLevel + 1, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3)
    				tot_vars = tot_vars + vr
    				tot_func = tot_func + fn
    				tot_tabs = tot_tabs + tb + 1
    				if list then lst_subtabs = lst_subtabs .. st end
    			else
    				local t_levelmaxi = viewers.form9user("luaTable_structure_level_maxi", recursiveLevel)
    				if list then res = res .. " " .. viewers.styles_color_warning( t_levelmaxi ) end
    			end
    			local sep = ""
    			if max == opt.max_n then
    				local luaTable_table_listlimit_max_n = viewers.form9user("luaTable_table_listlimit_max_n", opt.max_n)
    				if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b> " .. viewers.styles_color_warning(luaTable_table_listlimit_max_n) end
    				break
    			end
    		elseif type(v) == "function" then
    			nbr_func = nbr_func + 1
    			tot_func = tot_func + 1
    			isempty = false
    			if list then lst_func = lst_func .. k .. sep end
    		else -- type(v) == other
    			nbr_vars = nbr_vars + 1
    			tot_vars = tot_vars + 1
    			isempty = false
    			if list then lst_vars = lst_vars .. type(v) .. " - <b>" .. tostring(k) .. "</b> = " .. tostring(v) .. " " .. sep end
    		end
    	end
    	if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_vars) .. " vars: " .. lst_vars end
    	if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_func) .. " functions: " .. lst_func end
    	if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_tabs) .. " tables: " .. lst_tabs .. lst_subtabs end
    	return res, tot_vars, tot_func, tot_tabs
    end -- function lua_table.structure_recursive(tbl, uppername, name, recursiveLevel, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3)
    
    -- - - - ------------------ - - - - ---------------------------------
    -- Document the tables and their structures. List a table content, with formating.
    -- Documentar las tablas y sus estructuras. Lista de un contenido de la tabla, con el formateo.
    -- Documenter les tables et leurs structures. Lister un contenu de la table, avec le formatage.
    -- - - - ------------------ - - - - ---------------------------------
    -- Dump and format the content of a table and its sub-tables ; with limits in length, deep and exceptions.
    -- Listar y formatar le contento de una tabla y su sub-tablas.
    -- Lister et formater le contenu d'une table et ses sous-tables ; avec des limites en longueur, profondeur et exceptions.
    -- For each (sub)table, list : in first vars, then functions, then sub-tables list, then sub-tables contents
    
    -- Auto test of limits of the table list.
    -- Auto test des limites de liste de table.
    lua_table.tablim = { "one", "two", max1 = "MAX1", max2 = "MAX2", max3 = "MAX3"}
    lua_table.tablim.life = { animal = "dog", vegetal = { big = "tree", small = "flower"} }
    lua_table.tablim.life.animals = { "turtle"}
    lua_table.tablim.comfort = { "tv", mobile = "car", sub2 = { "phone", fix = "wall", sub3 = { "bed", up = "roof", sub4 = { "ball"} } } }
    lua_table.tablim.house = { "kitcheen", "bedroom"}
    lua_table.tablim.house.garden = { flower = "rose", nature = "river"}
    --	opt = { dropit.dropit = "dropit", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- , {width = "88%", tc1 = "blue"}
    
    function lua_table.structure(table, tablename, opt)
    --	luaTable_structure_limits_title		= "List a table, test with limits:",
    	local memo = viewers.save_configs("lua_table.structure") -- Save global configuration before eventual changes.
    	local recursiveLevel, recursive_limit, recursiveLevel_err = 1, 1111, ""
    	local res = "\n* Content of the <b>" .. tostring(tablename) .. "</b> table, begin:"
    	if not opt then opt = { recursive_limit = 11111 } end
    	local recursiveLevel = opt.recursiveLevel or 1
    	if langs.main_i18n_complete then
    		recursiveLevel, recursive_limit, recursiveLevel_err = modes.recursive_normal(recursiveLevel, modes.recursive_limit)
    	end
    --	local recursiveLevel, recursive_limit, recursiveLevel_err = modes.recursive_normal(recursiveLevel, modes.recursive_limit)
    	if type(opt.level_maxi) ~= "number" then opt.level_maxi = 222 end
    --	opt.level_maxi = opt.level_maxi or 222
    	if type(opt.max_n) ~= "number" then opt.max_n = 3333 end
    	opt.max_n = opt.max_n or 3333
    	opt.recursiveLevel = opt.recursiveLevel or recursiveLevel or 1
    	opt.exclude1 = opt.exclude1 or ""
    	opt.exclude2 = opt.exclude2 or ""
    	opt.exclude3 = opt.exclude3 or ""
    	opt.countonly = opt.countonly and true
    	local tot_vars, tot_func, tot_tabs = 0, 0, 0
    	if recursiveLevel > opt.level_maxi then -- even for abnormal limit -- Erreur Lua dans Module:Centralizer-s-fr à la ligne 7271 : attempt to compare number with nil.
    		return "", tot_vars, tot_func, tot_tabs
    	end
    	local st, vr, fn, tb = lua_table.structure_recursive(table, "", tablename, 1, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3)
    	res = res .. st
    	tot_vars = tot_vars + vr
    	tot_func = tot_func + fn
    	tot_tabs = tot_tabs + tb
    	res = res .. "\n* Content of the <b>" .. tostring(tablename) .. "</b> table, end: "
    	res = res .. viewers.form9user(" %1 variables, %2 functions, %3 sub-tables.\n", vr, fn, tb)
    	viewers.restore_configs(memo, "lua_table.structure") -- Restore global configurations after eventual changes.
    	return res, tot_vars, tot_func, tot_tabs
    end -- function lua_table.structure(table, tablename, opt)
    
    function lua_table.structure_recursive_report(t) -- List the structure of a table, with or without limits
    	local t = t or "\n* <b>lua_table.structure()</b> List the structure of a table, with or without limits"
    	local t = t .. "\n* lua_table.structure() List a table, <b>test with limits</b>:"
    	local opt =	 { ["dropit"] = "dropit", ["level_maxi"] = 3, ["max_n"] = 2, ["exclude1"] = "hou" }
    	local res, tot_vars, tot_func, tot_tabs = lua_table.structure(lua_table.tablim, "lua_table.tablim", opt)
    	local t = t .. res -- luaTable_structure_limits_title
    	local t = t .. "\n* ."
    	local t = t .. "\n* lua_table.structure() List a table, <b>test without limits</b>:"
    	local res, tot_vars, tot_func, tot_tabs = lua_table.structure(lua_table.tablim, "lua_table.tablim", nil)
    	local t = t .. res -- luaTable_structure_nolimits_title
    	return t
    end -- local t = lua_table.structure_recursive_report(t)
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:mathroman is here as an example of very small central library. It becomes central using the central modules system.
    --	function mathroman.roman2int(rm, testcase) -- Convert a roman number to decimal
    --	function mathroman.int2roman(i, testcase) -- Convert a integer number to roman
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	mathroman = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    
    --	The Module:Centralizer/I18N translations for lua_table library update and complete Module:Centralizer translations.
    mathroman.i18n = {} -- Translations for mathroman library
    mathroman.i18n.br = {
    	mathroman_errors_head_err				= "Erreur : ",
    	mathroman_roman_err						= "Erreur de romain : ",
    	mathroman_value_error_err				= "Erreur de valeur : ",
    	mathroman_J_before_end_err				= "Caractère J avant la fin",
    	mathroman_char_X_in_N_err				= "Caractère <b>%1</b> en <b>%2</b>",
    	mathroman_char_increase_err				= "3 caractères croissants",
    	mathroman_greater_4999_err				= "Valeur > 4999",
    	mathroman_null_value_err				= "Valeur nulle",
    	mathroman_rom2dig_value_err				= "Erreur de valeur de nombre romain",
    	mathroman_dig2rom_value_err				= "Erreur de valeur décimale",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Test des nombres romains en nombres décimaux",
    	mathroman_roman2int_tests_headers		= "Nombre romain; Valeur décimale; Correct; Erreur(s)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Test des nombres décimaux en nombres romains",
    	mathroman_int2roman_tests_headers		= "Nombre décimal; Valeur romaine; Correct; Erreur(s)",
    	mathroman_int_is_not_integer_err		= "Le nombre non entier <b>%1</b> n'est pas convertible en nombre romain",
    	mathroman_int_is_not_number_err			= "La valeur <b>%1</b> n'est pas un nombre convertible en nombre romain",
    	mathroman_is_not_string_err				= "La valeur <b>%1</b> n'est pas un texte convertible en nombre",
    } -- mathroman.i18n.br
    mathroman.i18n.de = {
    	mathroman_errors_head_err				= "Fehler: ",
    	mathroman_roman_err						= "Römischer Fehler: ",
    	mathroman_value_error_err				= "Wert Fehler: ",
    	mathroman_J_before_end_err				= "J Zeichen vor dem Ende",
    	mathroman_char_X_in_N_err				= "Zeichen <b>%1</b> in <b>%2</b>",
    	mathroman_char_increase_err				= "3 zunehmende Charaktere",
    	mathroman_greater_4999_err				= "Wert > 4999",
    	mathroman_null_value_err				= "Nullwert",
    	mathroman_rom2dig_value_err				= "Roman Wert Fehler",
    	mathroman_dig2rom_value_err				= "Dezimalwertfehler",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Test römischer Zahlen in Dezimalzahlen",
    	mathroman_roman2int_tests_headers		= "Römische Nummer; Dezimalwert; Richtig; Error (s)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Test von Dezimalzahlen in römischen Zahlen",
    	mathroman_int2roman_tests_headers		= "Dezimalzahl; Römischer Wert; Richtig; Error (s)",
    	mathroman_int_is_not_integer_err		= "Das nicht ganzzahlige <b>%1</b> ist nicht in römische Zahl umwandelbar",
    	mathroman_int_is_not_number_err			= "Der Wert <b>%1</b> ist keine Zahl, die in eine römische Zahl umgewandelt werden kann",
    	mathroman_is_not_string_err				= "Der Wert <b>%1</b> ist kein konvertierbarer Text in der Zahl",
    } -- mathroman.i18n.de
    mathroman.i18n.en = {
    	mathroman_errors_head_err				= "Error: ",
    	mathroman_roman_err						= "Roman error: ",
    	mathroman_value_error_err				= "Value error: ",
    	mathroman_J_before_end_err				= "character J before the end",
    	mathroman_char_X_in_N_err				= "character <b>%1</b> in <b>%2</b>",
    	mathroman_char_increase_err				= "3 increasing characters",
    	mathroman_greater_4999_err				= "value > 4999",
    	mathroman_null_value_err				= "null value",
    	mathroman_rom2dig_value_err				= "roman value error",
    	mathroman_dig2rom_value_err				= "digital value error",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Test roman to digital numbers",
    	mathroman_roman2int_tests_headers		= "Roman number; Digital value; Correct; Error(s)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Test digital numbers to roman numbers",
    	mathroman_int2roman_tests_headers		= "Digital number; Roman value; Correct; Error(s)",
    	mathroman_int_is_not_integer_err		= "The not integer number <b>%1</b> is not convertible to Roman numeral",
    	mathroman_int_is_not_number_err			= "The value <b>%1</b> is not a convertible number to Roman numeral",
    	mathroman_is_not_string_err				= "The value <b>%1</b> is not a text convertible to number"
    } -- mathroman.i18n.en
    mathroman.i18n.es = {
    	mathroman_errors_head_err				= "Error: ",
    	mathroman_roman_err						= "Error de romano: ",
    	mathroman_value_error_err				= "Error de valor: ",
    	mathroman_J_before_end_err				= "Carácter J antes del fin",
    	mathroman_char_X_in_N_err				= "Carácter <b>%1</b> en <b>%2</b>",
    	mathroman_char_increase_err				= "3 crecientes caracteres",
    	mathroman_greater_4999_err				= "Valor > 4999",
    	mathroman_null_value_err				= "Valor null",
    	mathroman_rom2dig_value_err				= "Romano valor error",
    	mathroman_dig2rom_value_err				= "Decimale valor error",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Prueba de números romanos a números decimales",
    	mathroman_roman2int_tests_headers		= "Número romano; Valor digital; Corregido; Error(s)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Prueba de números decimales a números romanos",
    	mathroman_int2roman_tests_headers		= "Número decimal, Valor romana; Correcto; Error(es),",
    	mathroman_int_is_not_integer_err		= "El no entero <b>%1</b> no se puede convertir en número romano",
    	mathroman_int_is_not_number_err			= "El valor <b>%1</b> no es un número y no se puede convertir en número romano",
    	mathroman_is_not_string_err				= "El valor <b>%1</b> no es un texto y no se puede convertir en número",
    } -- mathroman.i18n.es
    mathroman.i18n.fr = {
    	mathroman_errors_head_err				= "Erreur : ",
    	mathroman_roman_err						= "Erreur de romain : ",
    	mathroman_value_error_err				= "Erreur de valeur : ",
    	mathroman_J_before_end_err				= "Caractère J avant la fin",
    	mathroman_char_X_in_N_err				= "Caractère <b>%1</b> en <b>%2</b>",
    	mathroman_char_increase_err				= "3 caractères croissants",
    	mathroman_greater_4999_err				= "Valeur > 4999",
    	mathroman_null_value_err				= "Valeur nulle",
    	mathroman_rom2dig_value_err				= "Erreur de valeur de nombre romain",
    	mathroman_dig2rom_value_err				= "Erreur de valeur décimale",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Test des nombres romains en nombres décimaux",
    	mathroman_roman2int_tests_headers		= "Nombre romain; Valeur décimale; Correct; Erreur(s)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Test des nombres décimaux en nombres romains",
    	mathroman_int2roman_tests_headers		= "Nombre décimal; Valeur romaine; Correct; Erreur(s)",
    	mathroman_int_is_not_integer_err		= "Le nombre non entier <b>%1</b> n'est pas convertible en nombre romain",
    	mathroman_int_is_not_number_err			= "La valeur <b>%1</b> n'est pas un nombre convertible en nombre romain",
    	mathroman_is_not_string_err				= "La valeur <b>%1</b> n'est pas un texte convertible en nombre",
    } -- mathroman.i18n.fr
    mathroman.i18n.hu = {
    	mathroman_errors_head_err				= "Hiba: ",
    	mathroman_roman_err						= "Római hiba: ",
    	mathroman_value_error_err				= "Értékhiba: ",
    	mathroman_J_before_end_err				= "Karakter J a vége előtt",
    	mathroman_char_X_in_N_err				= "<b>%1</b> karakter <b>%2</b> -ben",
    	mathroman_char_increase_err				= "3 növekvő karakter",
    	mathroman_greater_4999_err				= "Érték > 4999",
    	mathroman_null_value_err				= "Null érték",
    	mathroman_rom2dig_value_err				= "Római számérték hiba",
    	mathroman_dig2rom_value_err				= "Tizedes érték hiba",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() A római számok tizedes számok tesztelése",
    	mathroman_roman2int_tests_headers		= "Római szám; Decimális érték; helyes; Hiba (k)",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() A decimális számok vizsgálata római számokban",
    	mathroman_int2roman_tests_headers		= "Tizedes szám; Római érték; helyes; Hiba (k)",
    	mathroman_int_is_not_integer_err		= "A nem egész <b>%1</b> nem konvertálható a római számra",
    	mathroman_int_is_not_number_err			= "A <b>%1</b> érték nem egy szám, amely átváltható egy római számra",
    	mathroman_is_not_string_err				= "Az <b>%1</b> érték nem konvertibilis szöveg",
    } -- mathroman.i18n.hu
    mathroman.i18n.vi = {
    	mathroman_errors_head_err				= "Lỗi: ",
    	mathroman_roman_err						= "Lỗi roman: ",
    	mathroman_value_error_err				= "Lỗi giá trị: ",
    	mathroman_J_before_end_err				= "Ký tự J trước khi kết thúc",
    	mathroman_char_X_in_N_err				= "<b>%1</b> ký tự trong <b>%2</b>",
    	mathroman_char_increase_err				= "3 ký tự tăng",
    	mathroman_greater_4999_err				= "Giá trị> 4999",
    	mathroman_null_value_err				= "Giá trị rỗng",
    	mathroman_rom2dig_value_err				= "Lỗi giá trị số La Mã",
    	mathroman_dig2rom_value_err				= "Lỗi giá trị thập phân",
    	mathroman_roman2int_tests_title			= "mathroman.roman2int() Kiểm tra các số La Mã trong các số thập phân",
    	mathroman_roman2int_tests_headers		= "Số La Mã; Giá trị thập phân; chính xác; Lỗi",
    	mathroman_int2roman_test_title			= "mathroman.int2roman() Kiểm tra các số thập phân trong số La Mã",
    	mathroman_int2roman_tests_headers		= "Số thập phân; Giá trị La Mã; chính xác; lỗi",
    	mathroman_int_is_not_integer_err		= "Số nguyên <b>%1</b> không thể chuyển đổi thành số La Mã",
    	mathroman_int_is_not_number_err			= "Giá trị <b>%1</b> không phải là số có thể chuyển đổi thành số La Mã",
    	mathroman_is_not_string_err				= "Giá trị <b>%1</b> không phải là văn bản có thể chuyển đổi trong số",
    } -- mathroman.i18n.vi
    
    --	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.
    
    --	Romans view : 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 mathroman.roman2int(rm) -- Convert a roman number to integer -- S170606rmn
    --	{ ["name"] = "mathroman.roman2int (4)', ["args"] = { "VI", }, ["expect"] = { 123 } }, -- example of test case
    	local v = 0 -- valeur totale
    	local v1 = 0 -- valeur de derniere lettre
    	local v2 = 0 -- valeur de lettre precedente
    	local v3 = 0 -- valeur de lettre precedente
    	local x = '-' -- caractere en cours d'evaluation
    	local i = 1 -- numero du caractere en cours d'evaluation
    	local j = 0 -- numero du caractere de reference courant (debut en Lua)
    	local k = 0 -- numero du caractere de reference courant (fin en Lua)
    	local errs, errtab = "", {}
    	if type(rm) ~= "string" then
    		table.insert(errtab, tostring(events.add_err("mathroman_is_not_string_err", tostring(rm) ) ) )
    		return 0, errs
    	end
    	if rm == "" then
    		errs = errs .. events.add_err("mathroman_is_not_string_err", '""')
    		table.insert(errtab, tostring(events.add_err("mathroman_is_not_string_err", '""') ) )
    		return 0, errs
    	end
    	if type(rm) ~= "string" then rm = "-" end
    	local lst = '-MDCLXVIJ' -- caracteres autorises
    	x = string.sub(rm, i, i) or ''
    	while (x ~= '') do
    		v3 = v2
    		v2 = v1
    		v1 = 0
    		if ( x == 'M' ) then v1 = 1000 end
    		if ( x == 'D' ) then v1 = 500 end
    		if ( x == 'C' ) then v1 = 100 end
    		if ( x == 'L' ) then v1 = 50 end
    		if ( x == 'X' ) then v1 = 10 end
    		if ( x == 'V' ) then v1 = 5 end
    		if ( x == 'I' ) then v1 = 1 end
    		if ( x == 'J' ) then v1 = 1 end
    		if ( x == 'J' ) and ( i < string.len(rm) ) then
    			errs = errs .. events.add_err("mathroman_J_before_end_err") -- e4 = 'character J before the end'
    			table.insert(errtab, tostring(events.add_err("mathroman_J_before_end_err") ) ) -- e4 = 'character J before the end'
    		end
    		if ( v1 == 0 ) then
    			errs = errs .. events.add_err("mathroman_char_X_in_N_err", x, i) -- e3 = "character K in 3"
    			table.insert(errtab, tostring(events.add_err("mathroman_char_X_in_N_err", x, i) ) )
    		end
    		v = v + v1
    		if ( (v1 == 5*v2) or (v1 == 10*v2) ) then v = v - (2*v2) end -- adjust 4, 9, 40, 90 ...
    		j, k = string.find(lst, x)
    		if ( j == nil ) then j = -1 end
    		if ( k == nil ) then k = -1 end
    		if (v1 > v2) and (v2 > v3) and (v3 > 0) then
    			errs = errs .. events.add_err("mathroman_char_increase_err") -- e2 = ' increasing chars.'
    			table.insert(errtab, tostring(events.add_err("mathroman_char_increase_err") ) )
    		end
    		i = i + 1
    		x = string.sub(rm, i, i) or ''
    	end
    	if ( v < 1 ) then --	e0 = ' valeur nulle.'
    		errs = errs .. events.add_err("mathroman_null_value_err")
    		table.insert(errtab, tostring(events.add_err("mathroman_null_value_err") ) )
    	end
    	if ( v > 4999 ) then -- e1 = ' valeur > 4999.'
    		errs = errs .. events.add_err("mathroman_greater_4999_err")
    		table.insert(errtab, tostring(events.add_err("mathroman_greater_4999_err") ) )
    	end
    	errs = table.concat(errtab, " ; ")
    	return v, errs -- with or without errors
    end -- function mathroman.roman2int(rm)
    
    function mathroman.romani2r(i, j)
    	if ( j == nil ) then j = '' end
    	local rm=''
    	if ( i == 1000 ) then rm = 'M' end
    	if ( i == 500 ) then rm = 'D' end
    	if ( i == 100 ) then rm = 'C' end
    	if ( i == 50 ) then rm = 'L' end
    	if ( i == 10 ) then rm = 'X' end
    	if ( i == 5 ) then rm = 'V' end
    	if ( i == 1 ) then
    		rm = 'I'
    		if ( j == 'J' ) then  rm = 'J' end
    	end
    	return rm
    end -- function mathroman.romani2r(i, j)
    
    function mathroman.int2roman(int) -- Convert an integer to a roman number, also if int is a string
    --	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { int = 444 }, ["expect"] = { "CDXLIV" } }, -- example of test case
    	local errs = "" -- local collection of errors -- S170606rmn
    	local roman, n = "", tonumber(int)
    	if n then
    		local floor = math.floor(n)
    		if n ~= floor then
    			errs = errs .. events.add_err("mathroman_int_is_not_integer_err", tostring(int) )
    			roman = ""
    			return roman, errs -- with error
    		end
    	elseif int == "" then
    		errs = errs .. events.add_err("mathroman_is_not_string_err", '""' )
    		return "", errs
    	else
    		errs = errs .. events.add_err("mathroman_int_is_not_number_err", tostring(int) )
    		roman = ""
    		return roman, errs -- with error
    	end
    	if type(n) ~= "number" then n = 0 end
    	n = math.floor(n)
    	n = n or 0 -- delete after debug
    	local v100 = 100
    	local v500 = v100*5
    	local v1000 = v100*10 -- roman cycle romain 1000, 100, 10, 1
    	local v, v1, v2, v3 = 0, 0, 0, 0 -- Total value, last, and previous. Valeur totale, derniere, et precedentes.
    	local reste, reduction = 0, 0 -- Rest to convert, last reduction. Reste a convertir, derniere reduction.
    	local rm = ''
    	local roman = '' -- chiffre et nombre romain resultant
    	reste = n
    	if ( n > 4999 ) then
    		errs = errs .. events.add_err("mathroman_greater_4999_err") -- e1 = ' valeur > 4999.'
    		reste = 0
    		roman = "" -- 'ERROR'
    	end
    	if ( n < 1 ) then
    		errs = errs .. events.add_err("mathroman_null_value_err") -- e2 = ' valeur < 1.'
    		reste = 0
    		roman = "" -- 'ERROR'
    	end
    	while (reste > 0) do
    		v3 = v2
    		v2 = v1
    		v1 = reste
    		reduction = 0
    		if ( reste >= v1000 ) then
    			reduction = v1000
    		elseif ( reste >= v100*9 ) then
    			reduction = v100
    			reste = reste + v100*2
    		elseif ( reste >= v500 ) then
    			reduction = v500
    		elseif ( reste >= v100*4 ) then
    			reduction = v100
    			reste = reste + v100*2
    		elseif ( reste >= v100 ) then
    			reduction = v100
    		elseif ( reste >= 1000 ) then
    			v100 = 100
    			v1000 = 1000
    			reduction = v1000
    		end
    		rm = mathroman.romani2r(reduction)
    		roman = roman .. rm
    		reste = reste - reduction
    		if ( reste < v100 ) then
    			if ( v100 >= 10 ) then
    			v100 = v100/10
    			v500 = v100*5
    			v1000 = v100*10
    			end
    		end
    	end
    	return roman, errs -- with or without errors
    end -- function mathroman.int2roman(int)
    
    function mathroman.roman2int_tests(t) -- Tests of main central modules -- S170606rmn
    	local memo = viewers.save_configs("mathroman.roman2int_tests") -- Save global configuration before eventual changes.
    	local t = t or "\n* " .. viewers.form9user("mathroman_roman2int_tests_title")
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		tests_title	 = "mathroman_roman2int_tests_title", -- "mathroman.roman2int() Test roman to digital numbers"
    		test_group = {	{ 123, },	{ 2.78, },		{ "-X", },	{ "", },
    			{ "0", },	{ "MCXI", },{ "XIJ", },		{ "XJI", }, { "XIA", },
    			{ "VLD", }, { "IXC", }, { "MMMMCMXCIX", },			{ "MMMMM", },
    			{ "MMMMMYJXC", },		{ {x}, },		{ function()end, },
    		},
    		headers = "mathroman_roman2int_tests_headers", -- "Roman number; Digital value; Correct; Error(s)"
    		rowGroup = {},
    	}
    	tab_view.t = (tab_view.t or "") .. viewers.ta("roman2int_tests: ", "start")
    	tab_view.t = tab_view.t .. viewers.ta("#test_group: ", lua_table.level_count(tab_view.test_group) )
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local word = case[1] -- DEBUG : mathroman.roman2int() can fail without blocking page.
    		local valX, errs = mathroman.roman2int(word) -- DEBUG : mathroman.roman2int() can fail without blocking page.
    		local wordX, errsX = mathroman.int2roman(valX) -- DEBUG : mathroman.roman2int() can fail without blocking page.
    		return { word, valX, wordX, errs .. " " .. errsX, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "mathroman.roman2int_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function mathroman.roman2int_tests(t)
    
    function mathroman.int2roman_test(t) -- Unitary tests of mathroman.int2roman
    	local memo = viewers.save_configs("mathroman.int2roman_test") -- Save global configuration before eventual changes.
    	local t = t or "\n* " .. viewers.form9user("mathroman_int2roman_test_title")
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		tests_title	 = "mathroman_int2roman_test_title", -- "mathroman.int2roman() Test digital numbers to roman numbers"
    		test_group = {	{ -10, },	{ 3.14, },		{ "not-a-number", },	{ "", },
    			{ 0, },		{ 12, },	{ 17, },		{ "18", },				{ "19", },
    			{ 111, },	{ 444, },	{ 555, },
    			{ "777", }, { "1111", },{ "4999", },	{ "5000", },
    		},
    		headers = "mathroman_int2roman_tests_headers", -- "Digital number; Roman value; Correct; Error(s)"
    		rowGroup = {},
    	}
    	tab_view.t = (tab_view.t or "") .. viewers.ta("int2roman_tests: ", "start")
    	tab_view.t = tab_view.t .. viewers.ta("#test_group: ", lua_table.level_count(tab_view.test_group) )
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local val = case[1] -- DEBUG : mathroman.roman2int() can fail without blocking page.
    		local wordX, errs = mathroman.int2roman(val, " ") -- DEBUG : mathroman.int2roman() can fail without blocking page.
    		local valX, errsX = mathroman.roman2int(wordX) -- DEBUG : mathroman.roman2int() can fail without blocking page.
    		return { val, wordX, valX, errs .. " " .. errsX, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "mathroman.int2roman_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function mathroman.int2roman_test(t)
    
    --	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.
    --	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", group = mathroman.TestsCasesGroup, },
    --	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 1 }, ["expect"] = { "I" } },
    
    mathroman.TestsCasesGroup = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	-- each test_case defines a name, a function, an input, an output. See also viewers.strTestCase. 8 cases
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XXII" }, ["expect"] = { 22 }, },
    }
    
    mathroman.Tests_cases = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	-- each test_case defines a name, a function, an input, an output. See also viewers.strTestCase. 5 cases
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 12, }, ["expect"] = { "XII" }, },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VIA", }, ["expect"] = { 6, "character AAA in 3" }, },
    }
    
    mathroman.int2romanTests = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	-- each test_case defines a name, a function, an input, an output. See also viewers.strTestCase. 8 - 1 = 7 + 8 = 15 cases
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { "19" }, ["expect"] = { "XII" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 4999 }, ["expect"] = { "MMMMCMXCIX" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 5000 }, ["expect"] = { "0", "value > 4999" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { -10 }, ["expect"] = { "X", "null value" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 0 }, ["expect"] = { "0", "null value" } },
    }
    mathroman.roman2intTests = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	-- each test_case defines a name, a function, an input, an output. See also viewers.strTestCase. 6 cases
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "-X" }, ["expect"] = { 10, "mathroman_char_X_in_N_err---1-" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "0" }, ["expect"] = { 0, "null value" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XIA" }, ["expect"] = { 11, "character A in 3" } },
    	--[
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "" }, ["expect"] = { 0 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XIJ" }, ["expect"] = { 12 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XJI" }, ["expect"] = { 12, "X Y Z" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XJI" }, ["expect"] = { 12, "mathroman_char_increase_err" } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VLD" }, ["expect"] = { 445 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "IXC" }, ["expect"] = { 89 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MMMMCMXCIX" }, ["expect"] = { 4999 } },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MMMMM" }, ["expect"] = { 5000, "mathroman_J_before_end_err-XJI" } },
    	--]]
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MMMMMYJXC" }, ["expect"] = { 5089, ";mathroman_J_before_end_err;mathroman_char_increase_err;mathroman_char_X_in_N_err-Y-6;mathroman_greater_4999_err;" } },
    }
    
    mathroman.testsRecursive = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XXIJ" }, ["expect"] = { 22 } },
    --	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, },
    	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 } },
    --	{ ["errorsKey"] = 2, ["modulename"] = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, },
    }
    
    local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, }
    local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", }
    
    mathroman.tests_groups = { -- Autotest cases to validate the mathroman library at MediaWiki level.
    	-- Each test_case defines a name, a function, an input, an output.
    	{ ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.Tests_cases", }, --
    	{ ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.int2romanTests", }, --
    	{ ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.roman2intTests", }, --
    --		modulename = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.testsRecursive", },
    }
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:modes support modes and their options, like p.read(frame).
    --	count = number of tests; provide( n ) returns three values: n, and expected output; run( n ) returns one string.
    --	see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase
    --	This library supports modules to:
    --	* Define their modes, used with frame: p.read(frame)
    --	* Default modes are read, edit, doc or tests
    --	* And their options
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	modes = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    
    --	The Module:Centralizer/I18N translations for lua_table library update and complete Module:Centralizer translations.
    modes.cat_view = "" -- = ":" to document a category rather than truly categorize it
    modes.i18n = {} -- Translations for modes library
    modes.i18n.br = {
    	-- Noms et descriptions des arguments de configurations
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label_descr							= "Argument automatique de Wikidata.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Argument automatique de Wikidata.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Langue du wiki.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Langue de la page.",
    	userlang							= "userlang",
    	userlang_descr						= "Language du lecteur de la page.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	itemid								= 'itemid',
    	itemid_descr						= "Identifiant des données de Wikidata, comme <code>Q535</code> pour Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Autre identifiant des données de Wikidata, comme <code>Q535</code> pour Victor Hugo.",
    	debug								= 'debug',
    	category							= 'Catégorie',
    	mode								= "mode",
    	mode_descr							= "Type d'utilisation du module ou du modèle : lire, éditer, documenter, tester.",
    	options								= "options",
    	options_descr						= "Options d'affichage d'un module ou d'un modèle.",
    	c									= "c",
    	c_descr								= "Options d'affichage d'un module ou d'un modèle.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Versions connues, pour les gérer.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Versions demandées, pour les gérer.",
    	modes_form_ok_categ_tests			= "Test de génération de catégorie OK",
    	-- Principaux textes, erreurs et catégories des outils
    	language							= 'langue',
    	-- Messages et erreurs divers
    	modes_used_options_list_title		= "modes.used_options_list() Utilisation des options :",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Modes et options en bref",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Test des options de modes",
    	modes_options_from_args_title		= "Test des options des arguments",
    	-- Groupes d'arguments
    	modes_needed_to_verify				= "(obligatoire, à vérifier)",
    	modes_list_needed_args				= "Liste des arguments nécessaires :",
    	modes_list_all_config_arguments		= "Liste des arguments de configuration :",
    	modes_list_all_system_arguments		= "Liste des arguments système :",
    	modes_list_all_other_args			= "Liste des autres arguments :",
    	modes_language_cat					= 'Parle <b>%1</b>',
    	modes_date_months_names				= "Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre",
    	modes_date_to_part_format			= "dd yyyy mmmm",
    	modes_date_to_part_call_err			= "Erreur interne : Argument anormal de définition de date <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Module avec erreur interne",
    	modes_date_to_part_not_found_err	= "Erreur interne : partie non définie de date <b>%1</b>.",
    	-- Gestion des arguments
    	modes_error_list_header_err			= "Assistance sur les paramètres de ce modèle :",
    	modes_need_arg_value_err			= "Erreur : Vous devez définir cet argument nécessaire mais absent : <b>%1</b>.",
    	modes_none_value_err				= "Erreur : Aucun argument n'a été défini.",
    	modes_unknown_argument_err			= "Erreur : Le paramètre <b>%1</b> est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.",
    	modes_too_unnamed_arguments_err		= "Erreur : Ce paramètre non nommé est en trop : <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Erreur interne : Signaler au développeur que l'argument interne <b>%1</b> est inconnu dans les notices.",
    	modes_is_defined_err				= "L'argument <b>%1</b>:<b>%2</b> est défini.",
    	modes_is_undefined_err				= "L'argument <b>%1</b>:<b>%2</b> n'est pas défini.",
    	modes_args_values_err				= "Valeur anormale de l'argument <b>%1</b> = <b>%2</b> parmi : (%3) ",
    	-- Messages et erreurs divers
    	modes_nearest_argument_err			= "Erreur : Voulez vous l'argument connu <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "Un nom d'argument plus long accepte plus d'erreurs de lettres.",
    	modes_value_re_defined_err			= "Erreur : La valeur de l'argument <b>%1</b> est déjà définie. Choisir une seule valeur d'un seul synonyme.",
    	modes_lang_table_err				= "Erreur interne : La langue <b>%1</b> ou sa table est erronée.",
    	modes_lang_table_err_i_cat			= "Module avec erreur interne", -- modes_no_source_arguments_cat
    	modes_lang_table_err_i_cat			= "Module avec langue d'arguments erronée",
    	modes_lang_not_translated_err		= "Erreur : La langue <b>%1</b> n'est pas traduite.",
    	modes_generDoc1_paramName_err		= "Erreur interne : en generDoc1, mauvais argument <b>%1</b>.",
    	modes_unknown_auto_arg_err			= "Erreur interne: Argument automatique inconnu : <b>%1</b> = <b>%2</b>.",
    	--
    	modes_delete_docbox_wng				= "Vous devez suprimer cette documentation avant d'enregistrer.<br>Supprimez tous les modes pour revenir en mode read.",
    	modes_auto_val_warning_wng			= "Vérifiez l'argument automatique.",
    	--
    	modes_assist_user_param_err			= "Support aux utilisateurs pour vérifier les paramètres :",
    	modes_args_values_err				= "Valeur anormale de l'argument <b>%1</b> = <b>%2</b> (%3)",
    	--
    	modes_no_known_arguments_err		= "Erreur interne : Module sans table d'arguments connus.",
    	modes_no_known_arguments_i_cat		= "Module sans table d'arguments connus.",
    	modes_no_source_arguments_err		= "Erreur interne : Module sans table d'arguments sources.",
    	modes_no_source_arguments_i_cat		= "Module sans table d'arguments source.",
    	--
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Liste de tous les arguments acceptés",
    	modes_levenshtein_similar_tests_title = "modes.levenshtein() Test des distances de <b>[[w:Distance_de_Levenshtein|Levenshtein]]</b> entre mots:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Définitions des arguments",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Signaler les arguments inconnus",
    	modes_normal_box_main_text_1		= "Boîte d'information simple : titre de cette page <b>%1</b>, description : <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>Il était <b>%1</b>, se nommait <b>%2</b> <b>%3</b>, il est mort en <b>%4</b>.",
    	-- Ces textes sont utilisés pour titrer des tests.
    	modes_list_wiki_selectors_title		= "Liste des sélecteurs de ce module :",
    	modes_all_categories_list_title		= "modes.all_categories_list() Liste des catégories éventuelles de ce module :",
    	modes_all_errors_list_title			= "modes.all_errors_list() Liste des erreurs détectables de ce module :",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Test des arguments à valeurs multiples",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Test de sélection multiple",
    	modes_multiple_selection_test_headers= "Options;Sélecteur;À sélectionner;Sélectionnés",
    	modes_multiple_selection_test_select= "2;nobel;président;député;prix",
    	modes_recursiveLevel_err			= "Erreur de niveau récursif <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Test: Normalise le niveau récursif et la limite récursive",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Module, namespaces, et noms de pages :",
    	modes_args_known_report_title		= "modes.args_known_report(t) Rapport des principaux arguments connus.",
    	modes_args_known_report_headers		= "clé; valeur; type; nécessaire; mot-clé; synonyme; propriété; format; source",
    	modes_get_args_report_title			= "modes.get_args() Valeurs des argument dans p.args_known{}.", -- fr
    } -- modes.i18n.br
    
    modes.i18n.de = {
    	-- Namen und Beschreibungen von Konfigurationsargumenten
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Wikidata automatisches Argument.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Wikidata automatisches Argument.",
    	-- Sprachen
    	contentlang							= "contentlang",
    	contentlang_descr					= "Wiki-Sprache.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Sprache der Seite.",
    	userlang							= "userlang",
    	userlang_descr						= "Lesersprache der Seite.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	QITEM_descr							= "Name der Wikidata-Daten wie <code>Q535</code> für Victor Hugo.",
    	itemid								= 'itemid',
    	itemid_descr						= "Name der Wikidata-Daten wie <code>Q535</code> für Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Name der Wikidata-Daten wie <code>Q535</code> für Victor Hugo.",
    	debug								= 'debug',
    	category							= 'Kategorie',
    	mode								= "modo",
    	mode_descr							= "Art der Verwendung des Moduls oder Modells: Lesen, Bearbeiten, Dokumentieren, Testen.",
    	options								= 'opciones',
    	options_descr						= "Anzeigeoptionen für ein Modul oder ein Modell.",
    	c									= "c",
    	c_descr								= "Anzeigeoptionen für ein Modul oder ein Modell.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Bekannte Versionen, um mit ihnen umzugehen.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Verlangen Sie Versionen, um mit ihnen umzugehen.",
    	modes_form_ok_categ_tests			= "Testkategoriegenerierung OK",
    	--
    	-- Titel der Pruebas
    	modes_used_options_list_title		= "modes.used_options_list() Verwendung von Optionen:",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Modi und Optionen in Kürze",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Testmodusoptionen",
    	modes_options_from_args_title		= "Optionen für das Testen von Argumenten",
    	-- Gruppen von Argumenten
    	modes_needed_to_verify				= "(obligatorio, se debe comprobar)",
    	modes_list_needed_args				= "Liste der notwendigen Argumente:",
    	modes_list_all_config_arguments		= "Liste der Konfigurationsargumente:",
    	modes_list_all_system_arguments		= "Liste der Systemargumente:",
    	modes_list_all_other_args			= "Liste anderer Argumente:",
    	-- Haupttexte, Fehler und Instrumentenkategorien
    	modes_language_cat					= 'Sprechen <b>%1</b>',
    	modes_date_months_names				= "Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember",
    	modes_date_to_part_format			= "dd mmmm yyyy",
    	modes_date_to_part_call_err			= "Interner Fehler: anomale Aufrufargumente am Datum <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Modul mit internem Fehler",
    	modes_date_to_part_not_found_err	= "Interner Fehler: Nicht am Datum gefunden <b>%1</b>.",
    	-- Kontrolle der Argumente
    	modes_error_list_header_err			= "Unterstützung in den Parametern dieses Modells:",
    	modes_need_arg_value_err			= "Fehler: Sie müssen dieses notwendige Argument beheben, aber es fehlt: <b>%1</b>.",
    	modes_none_value_err				= "Fehler: Es wurde kein Argument definiert.",
    	modes_unknown_argument_err			= "Fehler: Der Parameter <b>%1</b> ist in diesem Modell unbekannt. Überprüfen Sie den Namen oder melden Sie diesen Fehler.",
    	modes_too_unnamed_arguments_err		= "Fehler: Zu viel Argument ohne einen Namen: <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Interner Fehler: Informiere den Entwickler, dass das interne Argument <b>%1</b> ist in den Aufzeichnungen unbekannt.",
    	modes_is_defined_err				= "Das <b>%1</b>:<b>%2</b> Argument ist definiert.",
    	modes_args_values_err				= "Abnormaler Wert des Arguments <b>%1</b> = <b>%2</b> dazwischen: (<b>%3</b>) ",
    
    	modes_is_undefined_err				= "Das <b>%1</b>:<b>%2</b> Argument ist nicht definiert.",
    	modes_args_values_err				= "Abnormaler Wert des Arguments <b>%1</b> = <b>%2</b> zwischen: (<b>%3</b>) ",
    	modes_nearest_argument_err			= "Fehler : Willst du das bekannte Argument <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "Längeres Namensargument akzeptiert mehr Buchstabenfehler.",
    	modes_value_re_defined_err			= "Fehler: Der Wert des Arguments <b>%1</b> ist bereits definiert. Wählen Sie nur einen Wert eines einzelnen Synonyms aus",
    	modes_lang_table_err				= "Fehler: Die Sprache <b>%1</b> oder ihre Tabelle ist falsch.",
    	modes_lang_table_err_i_cat			= "Modul mit internem Fehler",	 -- modes_lang_table_err_i_cat
    	modes_lang_table_err_i_cat			= "Modul mit der Sprache der fehlerhaften Argumente",	 -- modes_no_source_arguments_cat
    	modes_lang_not_translated_err		= "Fehler: Die Sprache <b>%1</b> ist nicht übersetzt.",
    	modes_generDoc1_paramName_err		= "Fehler intern: in generDoc1, schlechtes Argument <b>%1</b>.",
    	--
    	modes_unknown_auto_arg_err			= "Interner fehler: Automatisches unbekanntes Argument: <b>%1</b> = <b>%2</b>.",
    	modes_delete_docbox_wng				= "Sie müssen diese Dokumentation vor dem Brennen entfernen.<br>Entfernen Sie alle Modi, um in den Lesemodus zurückzukehren.",
    	modes_auto_val_warning_wng			= "Überprüfen Sie die automatischen Argumente.",
    	--
    	modes_assist_user_param_err			= "Benutzerunterstützung zur Überprüfung der Konfiguration:",
    	modes_args_values_err				= "Abnormaler Wert des Arguments <b>%1</b> = <b>%2</b> (%3)",
    	modes_no_known_arguments_err		= "Fehler intern: Modul ohne Tabelle mit bekannten Argumenten.",
    	modes_no_known_arguments_i_cat		= "Modul ohne Tabelle bekannter Argumente.",
    	modes_no_source_arguments_err		= "Fehler interno: Modul ohne Quellenargumententabelle.",
    	modes_no_source_arguments_i_cat		= "Modul ohne Quellenargumententabelle.",
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Liste aller akzeptierten Argumente",
    	modes_levenshtein_similar_tests_title= "modes.levenshtein() Beweis der Entfernungen <b>[https://es.wikipedia.org/wiki/Distancia_de_Levenshtein Levenshtein]</b> zwischen den Wörtern:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Definitionen von Argumenten",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Melden Sie unbekannte Argumente",
    	modes_normal_box_main_text_1		= "Einfaches Informationsfeld: Titel der Seite: <b>%1</b>, Beschreibung: <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>Er war ein <b>%1</b>, heißt <b>%2</b> <b>%3</b> war in gestorben <b>%4</b>.",
    	-- Diese Texte werden verwendet, um einige Tests zu benennen.
    	modes_list_wiki_selectors_title		= "Liste der Selektoren in diesem Modul:",
    	modes_all_categories_list_title		= "modes.all_categories_list() Liste der möglichen Kategorien dieses Moduls:",
    	modes_all_errors_list_title			= "modes.all_errors_list() Liste der erkennbaren Fehler in diesem Modul:",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Testen mehrerer Argumentwerte",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Mehrfachauswahltest",
    	modes_multiple_selection_test_headers= "Optionen; Auswahl; Um auszuwählen; Ausgewählt",
    	modes_multiple_selection_test_select= "2; nobel; Präsident; stellvertretender; Preis",
    	modes_recursiveLevel_err			= "Fehler der rekursiven Ebene <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Test: Normalisieren Sie die rekursive Ebene und die rekursive Grenze",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Module, Namespaces und Seitennamen:",
    	modes_args_known_report_title		= "modes.args_known_report(t) Bericht der wichtigsten bekannten Argumente.",
    	modes_args_known_report_headers		= "Schlüssel Wert tippen Sie ein; notwendig Schlüsselwort Synonyme; Eigentum; Format; Brunnen",
    	modes_get_args_report_title			= "modes.get_args() Werte der Argumente in p.args_known{}.", -- es
    } -- modes.i18n.de
    
    modes.i18n.en = { -- 182 <tab>mode_...
    	--	From here, TRANSLATE ONLY descriptions with a key like label_descr
    	-- To translate, always keep
    	-- Names and descriptions of configurations arguments
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Automatic Wikidata argument.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Automatic Wikidata argument.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Language of the wiki.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Language of the page.",
    	userlang							= "userlang",
    	userlang_descr						= "Language of the page reader.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	QITEM_descr							= "Wikidata data identifier, like <code>Q535</code> for Victor Hugo.",
    	itemid								= 'itemid',
    	itemid_descr						= "Wikidata data identifier, like <code>Q535</code> for Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Wikidata data identifier, like <code>Q535</code> for Victor Hugo.",
    	debug								= 'debug',
    	category							= 'Category',
    	mode								= "mode",
    	mode_descr							= "Type of use of the module or template: read, edit, document, test.",
    	options								= "options",
    	options_descr						= "Display options of a module or a model.",
    	c									= "c",
    	c_descr								= "Display options of a module or a model.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Known versions, to manage them.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Sought versions, to manage them.",
    	modes_used_options_list_title		= "modes.used_options_list() Use of options:",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Options uses and short test",
    	--
    	modes_list_all_args_main_title		= "modes.list_all_args_main() List of all accepted arguments",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Test options from modes", -- argschanges
    	modes_options_from_args_title		= "Test options from arguments",
    	-- Groups of arguments
    	modes_needed_to_verify				= "(required, to be checked)",
    	modes_list_needed_args				= "List of needed arguments:",
    	modes_list_all_config_arguments		= "List of all config arguments:",
    	modes_list_all_system_arguments		= "List of all system arguments:",
    	modes_list_all_other_args			= "List of all other arguments:",
    	-- Main string, errors and categories of tools
    	modes_language_cat					= 'Speaking <b>%1</b>',
    	modes_date_months_names				= "January, February, March, April, May, June, July, August, September, October, November, December",
    	modes_date_to_part_format			= "dd yyyy mmmm",
    	modes_date_to_part_call_err			= "Internal Error: Abnormal calling arguments in date <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Module with internal error",
    	modes_date_to_part_not_found_err	= "Internal Error: No part found in date <b>%1</b>.",
    	-- Arguments management
    	modes_error_list_header_err			= "Support on the parameters of this model:",
    	modes_need_arg_value_err			= "Error: This argument is required but absent : <b>%1</b>. Should define it.",
    	modes_none_value_err				= "Error: No argument has been defined.",
    	modes_unknown_argument_err			= "Error: parameter <b>%1</b> is unknown in this template. Check the name or report this gap.",
    	modes_too_unnamed_arguments_err		= "Error: This unnamed argument is too many: <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Internal Error: Notify the developer that the internal argument <b>%1</b> is unknown in the records.",
    	modes_is_defined_err				= "The argument <b>%1</b>:<b>%2</b> is defined.",
    	modes_is_undefined_err				= "The argument <b>%1</b>:<b>%2</b> is not defined.",
    	modes_args_values_err				= "Abnormal value of the argument <b>%1</b>:<b>%2</b> including (%3) ",
    	modes_nearest_argument_err			= "Error: Do you need the known argument <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "A longer name argument accepts more letter errors.",
    	modes_value_re_defined_err			= "Error: The value of the argument <b>%1</b> is already defined. Choose only one value of a single synonymous.",
    	modes_lang_table_err				= "Error: The <b>%1</b> language or its table is incorrect.",
    	modes_lang_table_err_i_cat			= "Module with internal error", -- modes_lang_table_err_i_cat
    	modes_lang_table_err_i_cat			= "Module with erroneous language of arguments",
    	modes_lang_not_translated_err		= "Error: The language <b>%1</b> is not translated.",
    	modes_generDoc1_paramName_err		= "Internal Error: in generDoc1, bad argument <b>%1</b>.",
    	--
    	modes_unknown_auto_arg_err			= "Internal Error: Unknown automatic argument: <b>%1</b> = <b>%2</b>.",
    	modes_delete_docbox_wng				= "You must remove this documentation before recording.<br>Remove all modes to return to read mode.",
    --	modes_auto_val_warning_wng			= "Verify the automatic argument: <b>%1</b> = <b>%2</b>.",
    	modes_auto_val_warning_wng			= "Verify the automatic arguments.",
    	--
    	modes_assist_user_param_err			= "User support for checking the settings:",
    	modes_args_values_err				= "Abnormal value of the argument <b>%1</b> = <b>%2</b> (%3)",
    	--
    	modes_no_known_arguments_err		= "Internal Error: Module without known arguments table.",
    	modes_no_known_arguments_i_cat		= "Module without known arguments table.",
    	modes_no_source_arguments_err		= "Internal Error: Module without source arguments table.",
    	modes_no_source_arguments_i_cat		= "Module without source arguments table.",
    	--
    	modes_list_all_args_main_title		= "modes.list_all_args_main() List of all accepted arguments",
    	modes_levenshtein_similar_tests_title= "modes.levenshtein() Test the distances between words <b>[https://en.wikipedia.org/wiki/Levenshtein_distance Levenshtein]</b>:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Arguments definitions",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Report unknown arguments",
    	modes_normal_box_main_text_1		= "Simple infobox: page title: <b>%1</b>, description: <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>He was <b>%1</b>, named <b>%2</b> <b>%3</b> was dead in <b>%4</b>.",
    
    	-- These string are used to title some tests.
    	modes_list_wiki_selectors_title		= "List of selectors of this module:",
    	modes_all_categories_list_title		= "modes.all_categories_list() List of eventual categories of this module:",
    	modes_all_errors_list_title			= "modes.all_errors_list() List of detectable errors in this module:",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Test of multiple values arguments",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Multiple selection test",
    	modes_multiple_selection_test_headers= "Options;Selector;To selector;Selected",
    	modes_multiple_selection_test_select= "2;nobel;president;deputy;price",
    	modes_recursiveLevel_err			= "Recursive level error <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Test: Normalize the recursive level and the recursive limit",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Module, namespaces, and page names:",
    	modes_args_known_report_title		= "modes.args_known_report(t) Report of main known args.",
    	modes_args_known_report_headers		= "key; val; type; need; keyword; syn; prop; format; source",
    	modes_get_args_report_title			= "modes.get_args() Values of the arguments in p.args_known{}.", -- en
    } -- modes.i18n.en
    
    modes.i18n.es = {
    	-- Nombres y descripciones de argumentos de configuraciones
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Wikidata automática argumento.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Wikidata automática argumento.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Idioma del wiki.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Idioma de la página.",
    	userlang							= "userlang",
    	userlang_descr						= "Idioma del lector de la página.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	QITEM_descr							= "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.",
    	itemid								= 'itemid',
    	itemid_descr						= "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.",
    	debug								= 'debug',
    	category							= 'Categoría',
    	mode								= "modo",
    	mode_descr							= "Tipo de uso del módulo o modelo: leer, editar, documentar, probar.",
    	options								= 'opciones',
    	options_descr						= "Opciones de visualización de un módulo o un modelo.",
    	c									= "c",
    	c_descr								= "Opciones de visualización de un módulo o un modelo.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Conocidas versiones, para manejarlos.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Versiones demanda, para manejarlos.",
    	modes_form_ok_categ_tests			= "Prueba generación categoría en OK",
    	--
    	-- Titres des pruebas
    	modes_used_options_list_title		= "modes.used_options_list() Uso de opciones:",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Modos y opciones en brief",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Prueba de opciones de modos", -- argschanges
    	modes_options_from_args_title		= "Prueba de opciones de argumentos",
    	-- Grupos de argumentos
    	modes_needed_to_verify				= "(obligatorio, se debe comprobar)",
    	modes_list_needed_args				= "Lista de argumentos necesarios:",
    	modes_list_all_config_arguments		= "Lista de argumentos de configuración:",
    	modes_list_all_system_arguments		= "Lista de argumentos del sistema:",
    	modes_list_all_other_args			= "Lista de los otros argumentos:",
    	-- Textos principales, errores y categorías de instrumentos
    	modes_language_cat					= 'Hablando <b>%1</b>',
    	modes_date_months_names				= "Enero, Febrero, Marzo, Abril, Mayo, Junio​​, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre",
    	modes_date_to_part_format			= "dd mmmm yyyy",
    	modes_date_to_part_call_err			= "Error interno: argumentos de llamadas anómala en fecha <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Módulo con error interno",
    	modes_date_to_part_not_found_err	= "Error interno: No se encuentra en fecha <b>%1</b>.",
    	-- Control de argumentos
    	modes_error_list_header_err			= "Asistencia de los parámetros de este modelo:",
    	modes_need_arg_value_err			= "Error: Usted tiene que fijar este argumento necesario, pero falta: <b>%1</b>.",
    	modes_none_value_err				= "Error: No hay argumento se ha definido.",
    	modes_unknown_argument_err			= "Error: El parámetro <b>%1</b> es desconocido en este modelo. Compruebe el nombre o reportar esta falta.",
    	modes_too_unnamed_arguments_err		= "Error: Demasiado argumento sin nombre: <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Error interno: Informar al el desarrollador que el argumento interno <b>%1</b> es desconocido en los registros.",
    	modes_is_defined_err				= "El argumento <b>%1</b>:<b>%2</b> está definido.",
    	modes_is_undefined_err				= "El argumento <b>%1</b>:<b>%2</b> no está definido.",
    	modes_args_values_err				= "Valor anormal del argumento <b>%1</b> = <b>%2</b> entre: (%3) ",
    	modes_nearest_argument_err			= "Error : ¿Es usted conocido argumento <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "Un argumento nombre más largo acepta más letras errores.",
    	modes_value_re_defined_err			= "Error: El valor del argumento <b>%1</b> ya está definido. Elija sólo un valor de un solo sinónimo",
    	modes_lang_table_err				= "Error: La <b>1%</b> idioma o su tabla es incorrecta.",
    	modes_lang_table_err_i_cat			= "Módulo con error interno",	 -- modes_lang_table_err_i_cat
    	modes_lang_table_err_i_cat			= "Módulo con lenguaje de argumentos erróneos",	 -- modes_no_source_arguments_cat
    	modes_lang_not_translated_err		= "Error: El lenguaje <b>%1</b> no se traduce.",
    	modes_generDoc1_paramName_err		= "Error interno: en generDoc1, mal argumento <b>%1</b>.",
    	--
    	modes_unknown_auto_arg_err			= "Error interno: Argumento desconocido automático: <b>%1</b> = <b>%2</b>.",
    	modes_delete_docbox_wng				= "Debe quitar esta documentación antes de grabar.<br>Retire todos los modos para volver al modo read.",
    	modes_auto_val_warning_wng			= "Verifique el argumentos automáticos.",
    	--
    	modes_assist_user_param_err			= "Apoyo al usuario para comprobar la configuración:",
    	modes_args_values_err				= "Valor anormal del argumento <b>%1</b> = <b>%2</b> (%3)",
    	--
    	modes_no_known_arguments_err		= "Error interno: Módulo sin tabla de argumentos conocidos.",
    	modes_no_known_arguments_i_cat		= "Módulo sin tabla de argumentos conocidos.",
    	modes_no_source_arguments_err		= "Error interno: Módulo sin tabla de argumentos fuentes.",
    	modes_no_source_arguments_i_cat		= "Módulo sin tabla de argumentos fuente.",
    
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Lista de todos los argumentos aceptados",
    	modes_levenshtein_similar_tests_title= "modes.levenshtein() Prueba de las distancias <b>[https://es.wikipedia.org/wiki/Distancia_de_Levenshtein Levenshtein]</b> entre las palabras:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Definiciones de argumentos",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Informar argumentos desconocidos",
    	modes_normal_box_main_text_1		= "Simple caja de información: Título de la página: <b>%1</b>, descripción: <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>Él era un <b>%1</b>, es nombrado <b>%2</b> <b>%3</b> había muerto en <b>%4</b>.",
    	-- Estos textos se utilizan para titular algunas pruebas.
    	modes_list_wiki_selectors_title		= "Lista de las selectores de este modulo:",
    	modes_all_categories_list_title		= "modes.all_categories_list() Lista de las posibles categorías de este modulo:",
    	modes_all_errors_list_title			= "modes.all_errors_list() Lista de los errores detectables de este modulo:",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Prueba de múltiples valores argumentos",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Prueba de selección múltiple",
    	modes_multiple_selection_test_headers= "Opciones;Selector;Para seleccionar;Seleccionadas",
    	modes_multiple_selection_test_select= "2;nobel;presidente;diputado;precio",
    	modes_recursiveLevel_err			= "Error de nivel recursivo <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Prueba: Normalizar el nivel recursivo y el límite recursiva",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Módulo, namespaces, y nombres de páginas:",
    	modes_args_known_report_title		= "modes.args_known_report(t) Informe de los principales argumentos conocidos.",
    	modes_args_known_report_headers		= "clave; valor; tipo; necesario; palabra clave; sinónimos; propiedad; formato; fuente",
    	modes_get_args_report_title			= "modes.get_args() Valores de los argumentos en p.args_known{}.", -- es
    } -- modes.i18n.es
    
    modes.i18n.fr = {
    	-- Noms et descriptions des arguments de configurations
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Argument automatique de Wikidata.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Argument automatique de Wikidata.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Langue du wiki.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Langue de la page.",
    	userlang							= "userlang",
    	userlang_descr						= "Language du lecteur de la page.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	itemid								= 'itemid',
    	itemid_descr						= "Identifiant des données de Wikidata, comme <code>Q535</code> pour Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Autre identifiant des données de Wikidata, comme <code>Q535</code> pour Victor Hugo.",
    	debug								= 'debug',
    	category							= 'Catégorie',
    	mode								= "mode",
    	mode_descr							= "Type d'utilisation du module ou du modèle : lire, éditer, documenter, tester.",
    	options								= "options",
    	options_descr						= "Options d'affichage d'un module ou d'un modèle.",
    	c									= "c",
    	c_descr								= "Options d'affichage d'un module ou d'un modèle.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Versions connues, pour les gérer.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Versions demandées, pour les gérer.",
    	modes_form_ok_categ_tests			= "Test de génération de catégorie OK",
    	-- Principaux textes, erreurs et catégories des outils
    	language							= 'langue',
    	-- Messages et erreurs divers
    	modes_used_options_list_title		= "modes.used_options_list() Utilisation des options :",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Modes et options en bref",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Test des options de modes", -- argschanges
    	modes_options_from_args_title		= "Test des options des arguments",
    	-- Groupes d'arguments
    	modes_needed_to_verify				= "(obligatoire, à vérifier)",
    	modes_list_needed_args				= "Liste des arguments nécessaires :",
    	modes_list_all_config_arguments		= "Liste des arguments de configuration :",
    	modes_list_all_system_arguments		= "Liste des arguments système :",
    	modes_list_all_other_args			= "Liste des autres arguments :",
    	modes_language_cat					= 'Parle <b>%1</b>',
    	modes_date_months_names				= "Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre",
    	modes_date_to_part_format			= "dd yyyy mmmm",
    	modes_date_to_part_call_err			= "Erreur interne : Argument anormal de définition de date <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Module avec erreur interne",
    	modes_date_to_part_not_found_err	= "Erreur interne : partie non définie de date <b>%1</b>.",
    	-- Gestion des arguments
    	modes_error_list_header_err			= "Assistance sur les paramètres de ce modèle :",
    	modes_need_arg_value_err			= "Erreur : Vous devez définir cet argument nécessaire mais absent : <b>%1</b>.",
    	modes_none_value_err				= "Erreur : Aucun argument n'a été défini.",
    	modes_unknown_argument_err			= "Erreur : Le paramètre <b>%1</b> est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.",
    	modes_too_unnamed_arguments_err		= "Erreur : Ce paramètre non nommé est en trop : <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Erreur interne : Signaler au développeur que l'argument interne <b>%1</b> est inconnu dans les notices.",
    	modes_is_defined_err				= "L'argument <b>%1</b>:<b>%2</b> est défini.",
    	modes_is_undefined_err				= "L'argument <b>%1</b>:<b>%2</b> n'est pas défini.",
    	modes_args_values_err				= "Valeur anormale de l'argument <b>%1</b> = <b>%2</b> parmi : (%3) ",
    	-- Messages et erreurs divers
    	modes_nearest_argument_err			= "Erreur : Voulez vous l'argument connu <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "Un nom d'argument plus long accepte plus d'erreurs de lettres.",
    	modes_value_re_defined_err			= "Erreur : La valeur de l'argument <b>%1</b> est déjà définie. Choisir une seule valeur d'un seul synonyme.",
    	modes_lang_table_err				= "Erreur interne : La langue <b>%1</b> ou sa table est erronée.",
    	modes_lang_table_err_i_cat			= "Module avec erreur interne", -- modes_no_source_arguments_cat
    	modes_lang_table_err_i_cat			= "Module avec langue d'arguments erronée",
    	modes_lang_not_translated_err		= "Erreur : La langue <b>%1</b> n'est pas traduite.",
    	modes_generDoc1_paramName_err		= "Erreur interne : en generDoc1, mauvais argument <b>%1</b>.",
    	modes_unknown_auto_arg_err			= "Erreur interne: Argument automatique inconnu : <b>%1</b> = <b>%2</b>.",
    	--
    	modes_delete_docbox_wng				= "Vous devez suprimer cette documentation avant d'enregistrer.<br>Supprimez tous les modes pour revenir en mode read.",
    	modes_auto_val_warning_wng			= "Vérifiez l'argument automatique.",
    	--
    	modes_assist_user_param_err			= "Support aux utilisateurs pour vérifier les paramètres :",
    	modes_args_values_err				= "Valeur anormale de l'argument <b>%1</b> = <b>%2</b> (%3)",
    	--
    	modes_no_known_arguments_err		= "Erreur interne : Module sans table d'arguments connus.",
    	modes_no_known_arguments_i_cat		= "Module sans table d'arguments connus.",
    	modes_no_source_arguments_err		= "Erreur interne : Module sans table d'arguments sources.",
    	modes_no_source_arguments_i_cat		= "Module sans table d'arguments source.",
    	--
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Liste de tous les arguments acceptés",
    	modes_levenshtein_similar_tests_title = "modes.levenshtein() Test des distances de <b>[[w:Distance_de_Levenshtein|Levenshtein]]</b> entre mots:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Définitions des arguments",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Signaler les arguments inconnus",
    	modes_normal_box_main_text_1		= "Boîte d'information simple : titre de cette page <b>%1</b>, description : <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>Il était <b>%1</b>, se nommait <b>%2</b> <b>%3</b>, il est mort en <b>%4</b>.",
    	-- Ces textes sont utilisés pour titrer des tests.
    	modes_list_wiki_selectors_title		= "Liste des sélecteurs de ce module :",
    	modes_all_categories_list_title		= "modes.all_categories_list() Liste des catégories éventuelles de ce module :",
    	modes_all_errors_list_title			= "modes.all_errors_list() Liste des erreurs détectables de ce module :",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Test des arguments à valeurs multiples",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Test de sélection multiple",
    	modes_multiple_selection_test_headers= "Options;Sélecteur;À sélectionner;Sélectionnés",
    	modes_multiple_selection_test_select= "2;nobel;président;député;prix",
    	modes_recursiveLevel_err			= "Erreur de niveau récursif <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Test: Normalise le niveau récursif et la limite récursive",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Module, namespaces, et noms de pages :",
    	modes_args_known_report_title		= "modes.args_known_report(t) Rapport des principaux arguments connus.",
    	modes_args_known_report_headers		= "clé; valeur; type; nécessaire; mot-clé; synonyme; propriété; format; source",
    	modes_get_args_report_title			= "modes.get_args() Valeurs des argument dans p.args_known{}.", -- fr
    } -- modes.i18n.fr
    
    modes.i18n.hu = {
    	-- Nombres y descripciones de argumentos de configuraciones
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Automatikus Wikidata argumentum.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Automatikus Wikidata argumentum.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Wiki nyelv.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Az oldal nyelve.",
    	userlang							= "userlang",
    	userlang_descr						= "Az oldal olvasó nyelve.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	QITEM_descr							= "Wikidata adatok neve, például Victor Hugo kódja <code>Q535</code>.",
    	itemid								= 'itemid',
    	itemid_descr						= "Wikidata adatok neve, például Victor Hugo kódja <code>Q535</code>.",
    	itemid2								= 'id',
    	itemid2_descr						= "Wikidata adatok neve, például Victor Hugo kódja <code>Q535</code>.",
    	debug								= 'debug',
    	category							= 'kategória',
    	mode								= "modo",
    	mode_descr							= "A modul vagy modell használata: olvasás, szerkesztés, dokumentum, tesztelés.",
    	options								= 'opciones',
    	options_descr						= "Egy modul vagy modell megjelenítési lehetőségei.",
    	c									= "c",
    	c_descr								= "Egy modul vagy modell megjelenítési lehetőségei.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Jól ismert verziók, kezelni őket.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Kérjen változatokat, kezelni őket.",
    	-- Textos principales, errores y categorías de instrumentos
    	modes_form_ok_categ_tests			= "OK kategória-generációs teszt",
    	--
    	-- Titres des pruebas
    	modes_used_options_list_title		= "modes.used_options_list() Az opciók használata:",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Módok és lehetőségek röviden",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Tesztelési mód beállításai",
    	modes_options_from_args_title		= "Tesztelési argumentum opciók",
    	-- Grupos de argumentos
    	modes_needed_to_verify				= "(kötelező, ellenőrizze)",
    	modes_list_needed_args				= "A szükséges érvek felsorolása:",
    	modes_list_all_config_arguments		= "Konfigurációs argumentumok listája:",
    	modes_list_all_system_arguments		= "Rendszer-érvek listája:",
    	modes_list_all_other_args			= "Egyéb érvek felsorolása:",
    	-- Fő szövegek, hibák és műszerkategóriák
    	modes_language_cat					= 'beszélő <b>%1</b>',
    	modes_date_months_names				= "Január, február, március, április, május, június, július, augusztus, szeptember, október, november, december",
    	modes_date_to_part_format			= "dd mmmm yyyy",
    	modes_date_to_part_call_err			= "Belső hiba: anomáliás híváselméletek a dátumon <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Modul belső hibával",
    	modes_date_to_part_not_found_err	= "Belső hiba: Nem található a dátumon <b>%1</b>.",
    	-- Control de argumentos
    	modes_error_list_header_err			= "A modell paramétereinek támogatása:",
    	modes_need_arg_value_err			= "Hiba: Meg kell oldanod ezt a szükséges érvet, de hiányzik: <b>%1</b>.",
    	modes_none_value_err				= "Hiba: Nincs argumentum definiálva.",
    	modes_unknown_argument_err			= "Hiba: A <b>%1</b> paraméter ismeretlen ebben a modellben. Ellenőrizze a nevet vagy jelezze ezt a hibát.",
    	modes_too_unnamed_arguments_err		= "Hiba: túl sok argumentum a név nélkül: <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Belső hiba: Tájékoztassa a fejlesztőt, hogy a <b>%1</b> belső argumentum ismeretlen a rekordokban.",
    	modes_is_defined_err				= "A argumentum <b>%1</b>:<b>%2</b> definiálva van.",
    	modes_is_undefined_err				= "A <b>%1</b>:<b>%2</b> argumentum nincs meghatározva.",
    	modes_args_values_err				= "Az argumentum abnormális értéke <b>%1</b> = <b>%2</b> között: (<b>%3</b>) ",
    	modes_nearest_argument_err			= "Hiba: Ismeretes az argumentum <b>%1</b> ?",
    	modes_max_nearest_argument_msg		= "A hosszabb név argumentum több betűhibát is elfogad.",
    	modes_value_re_defined_err			= "Hiba: Az <b>%1</b> argumentum értéke már definiált. Válasszon csak egyetlen értéket egy szinonimának",
    	modes_lang_table_err				= "Hiba: A <b>%1</b> nyelv vagy annak táblája nem megfelelő.",
    	modes_lang_table_err_i_cat			= "Modul belső hibával",	 -- modes_lang_table_err_i_cat
    	modes_lang_table_err_i_cat			= "A téves érvek nyelvével rendelkező modul",	 -- modes_no_source_arguments_cat
    	modes_lang_not_translated_err		= "Hiba: A nyelv <b>%1</b> nem fordított le.",
    	modes_generDoc1_paramName_err		= "Belső hiba: generDoc1-ben, rossz érv <b>%1</b>.",
    	--
    	modes_unknown_auto_arg_err			= "Belső hiba: Automatikus ismeretlen argumentum:  <b>%1</b>  = <b>%2</b>.",
    	modes_delete_docbox_wng				= "Törölje a dokumentációt az égetés előtt.<br> Távolítsa el az összes módot, hogy visszatérjen az olvasási üzemmódba.",
    	modes_auto_val_warning_wng			= "Ellenőrizze az automatikus érveket.",
    	--
    	modes_assist_user_param_err			= "Felhasználói támogatás a konfiguráció ellenőrzéséhez:",
    	modes_args_values_err				= "Az érv abnormális értéke <b>%1</b> = <b>%2</b> ( <b>%3</b> )",
    	--
    	modes_no_known_arguments_err		= "Belső hiba: Az ismert argumentumok táblázata nélküli modul.",
    	modes_no_known_arguments_i_cat		= "Modul tábla nélkül ismert érvekkel.",
    	modes_no_source_arguments_err		= "Belső hiba: A tábla argumentum nélküli tábla nélküli modul.",
    	modes_no_source_arguments_i_cat		= "Modul forrás argumentum táblázattal.Modul forrás argumentum táblázattal.",
    
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Az elfogadott érvek listája",
    	modes_levenshtein_similar_tests_title= "modes.levenshtein() A távolságok igazolása <b>[https://es.wikipedia.org/wiki/Distancia_de_Levenshtein Levenshtein]</b> entre las palabras:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Az érvek fogalommeghatározása",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Ismeretlen érvek jelentése",
    	modes_normal_box_main_text_1		= "Egyszerű információs mező: Az oldal címe: <b>%1</b>, leírás: <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/><b>%1</b> névvel <b>%2</b> <b>%3</b> meghalt <b>%4</b>.",
    	-- Ezeket a szövegeket néhány teszt tesztelésére használják.
    	modes_list_wiki_selectors_title		= "Ebben a modulban a szelektorkészletek listája:",
    	modes_all_categories_list_title		= "modes.all_categories_list() A modul lehetséges kategóriái:",
    	modes_all_errors_list_title			= "modes.all_errors_list() A modulban észlelhető hibák felsorolása:",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Több argumentum értékének vizsgálata",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Többszörös kiválasztási teszt",
    	modes_multiple_selection_test_headers= "Opciók; Kiválasztó; Kiválasztás; Kiválasztott",
    	modes_multiple_selection_test_select= "2; Nobel; elnök; helyettese; ár",
    	modes_recursiveLevel_err			= "Rekurzív szint hiba <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Teszt: Normalizálja a rekurzív szintet és a rekurzív határt",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Modul, névterek és oldalnevek:",
    	modes_args_known_report_title		= "modes.args_known_report(t) A legfontosabb ismert érvekről szóló jelentés.",
    	modes_args_known_report_headers		= "kulcs; érték; írja; szükséges; kulcsszó; fordítása; tulajdon; formátumban; forrás",
    	modes_get_args_report_title			= "modes.get_args() Az érvek értékei p.args_known{}.", -- es
    } -- modes.i18n.hu
    
    modes.i18n.vi = {
    	-- Noms et descriptions des arguments de configurations
    	[1]									= "1",
    	[2]									= "2",
    	[3]									= "3",
    	[4]									= "4",
    	["modules_guide"]					= "Argument modules_guide",
    	label								= 'label',
    	label_descr							= "Đối số tự động để Wikidata.",
    	sitelink							= 'sitelink',
    	sitelink_descr						= "Đối số tự động để Wikidata.",
    	-- Languages
    	contentlang							= "contentlang",
    	contentlang_descr					= "Ngôn ngữ wiki.",
    	pagelang							= "pagelang",
    	pagelang_descr						= "Ngôn ngữ trang.",
    	userlang							= "userlang",
    	userlang_descr						= "Ngôn ngữ để người đọc trang.",
    	--
    	QITEM								= 'QITEM',
    	uri									= 'uri',
    	itemid								= 'itemid',
    	itemid_descr						= "Định danh dữ liệu Wikidata, chẳng hạn như <code>Q535</code> để Victor Hugo.",
    	itemid2								= 'id',
    	itemid2_descr						= "Số nhận dạng khác để dữ liệu Wikidata, chẳng hạn như <code>Q535</code> để Victor Hugo.",
    	debug								= 'gỡ lỗi',
    	category							= 'Loại',
    	mode								= "mode",
    	mode_descr							= "Loại sử dụng mô-đun hoặc mô hình: đọc, chỉnh sửa, tài liệu, kiểm tra.",
    	options								= "options",
    	options_descr						= "Hiển thị tùy chọn mô-đun hoặc mô hình.",
    	c									= "c",
    	c_descr								= "Hiển thị tùy chọn mô-đun hoặc mô hình.",
    	knownversions						= "knownversions",
    	knownversions_descr					= "Các phiên bản đã biết, để quản lý chúng.",
    	soughtversions						= "soughtversions",
    	soughtversions_descr				= "Các phiên bản được yêu cầu, để quản lý chúng.",
    	-- Principaux textes, erreurs et catégories des outils
    	language								= 'langue',
    	-- Messages et erreurs divers
    	modes_used_options_list_title		= "modes.used_options_list() Sử dụng các tùy chọn:",
    	modes_options_uses_tests_title		= "modes.options_from_mode_tests() Chế độ và tùy chọn trong ngắn hạn",
    	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Tùy chọn chế độ thử nghiệm",
    	modes_options_from_args_title		= "Kiểm tra đối số tùy chọn",
    	-- Groupes d'arguments
    	modes_needed_to_verify				= "(bắt buộc, phải được xác minh)",
    	modes_list_needed_args				= "Danh sách các đối số cần thiết:",
    	modes_list_all_config_arguments		= "Danh sách các đối số cấu hình:",
    	modes_list_all_system_arguments		= "Danh sách các đối số hệ thống:",
    	modes_list_all_other_args			= "Danh sách các đối số khác:",
    	modes_language_cat					= 'Nói tiếng <b>%1</b>',
    	modes_date_months_names				= "Tháng 1, tháng 2, tháng 3, tháng 4, tháng 5, tháng 6, tháng 7, tháng 9, tháng 10, tháng 11, tháng 12",
    	modes_date_to_part_format			= "dd yyyy mmmm",
    	modes_date_to_part_call_err			= "Lỗi nội bộ: Đối số định nghĩa ngày bất thường <b>%1</b>.",
    	modes_date_to_part_call_cat			= "Mô-đun có lỗi nội bộ",
    	modes_date_to_part_not_found_err	= "Lỗi nội bộ: phần không xác định để ngày <b>%1</b>.",
    	-- Gestion des arguments
    	modes_error_list_header_err			= "Hỗ trợ các thông số để mô hình này:",
    	modes_need_arg_value_err			= "Lỗi: Bạn phải đặt đối số cần thiết nhưng vắng mặt này: <b>%1</b>.",
    	modes_none_value_err				= "Lỗi: Không có đối số nào được xác định.",
    	modes_unknown_argument_err			= "Lỗi: Thông số <b>%1</b> không xác định trong mẫu này. Kiểm tra tên này hoặc báo cáo sự thiếu này.",
    	modes_too_unnamed_arguments_err		= "Lỗi: Tham số chưa đặt tên này vượt quá: <b>%1</b> = <b>%2</b>.",
    	modes_without_translation_wsid_err	= "Lỗi nội bộ: Báo cáo cho nhà phát triển rằng đối số nội bộ <b>%1</b> không xác định trong các bản ghi.",
    	modes_is_defined_err				= "Đối số <b>%1</b>:<b>%2</b> được đặt.",
    	modes_is_undefined_err				= "Đối số <b>%1</b>:<b>%2</b> không được xác định.",
    	modes_args_values_err				= "Giá trị bất thường để đối số <b>%1</b> = <b>%2</b> từ: ( <b>%3</b> ) ",
    	-- Messages et erreurs divers
    	modes_nearest_argument_err			= "Lỗi: Bạn có muốn đối số <b>%1</b> đã biết không?",
    	modes_max_nearest_argument_msg		= "Tên đối số dài hơn chấp nhận nhiều lỗi thư hơn.",
    	modes_value_re_defined_err			= "Lỗi: Giá trị để đối số <b>%1</b> đã được đặt. Chọn một giá trị duy nhất từ một từ đồng nghĩa duy nhất.",
    	modes_lang_table_err				= "Lỗi nội bộ: Ngôn ngữ <b>%1</b> hoặc bảng để nó sai.", -- để=để
    	modes_lang_table_err_i_cat			= "Mô-đun có lỗi nội bộ", -- modes_no_source_arguments_cat
    	modes_lang_table_err_i_cat			= "Mô-đun với ngôn ngữ đối số sai",
    	modes_lang_not_translated_err		= "Lỗi: Ngôn ngữ <b>%1</b> không được dịch.",
    	modes_generDoc1_paramName_err		= "Lỗi nội bộ: trong generDoc1, đối số không hợp lệ <b>%1</b>.",
    	modes_unknown_auto_arg_err			= "Lỗi nội bộ: Đối số tự động không xác định: <b>%1</b> = <b>%2</b>.",
    	--
    	modes_delete_docbox_wng				= "Bạn phải xóa tài liệu này trước khi lưu.<br> Xóa tất cả các chế độ để trở về chế độ đọc.",
    	modes_auto_val_warning_wng			= "Kiểm tra đối số tự động.",
    	--
    	modes_assist_user_param_err			= "Hỗ trợ người dùng để kiểm tra cài đặt:",
    	modes_args_values_err				= "Giá trị bất thường để đối số <b>%1</b> = <b>%2</b> ( <b>%3</b> )",
    	--
    	modes_no_known_arguments_err		= "Lỗi nội bộ: Mô-đun không có bảng các đối số đã biết.",
    	modes_no_known_arguments_i_cat		= "Mô-đun không có bảng các đối số đã biết.",
    	modes_no_source_arguments_err		= "Lỗi nội bộ: Mô-đun không có bảng đối số nguồn.",
    	modes_no_source_arguments_i_cat		= "Mô-đun không có bảng đối số nguồn.",
    	--
    	modes_list_all_args_main_title		= "modes.list_all_args_main() Danh sách tất cả các đối số được chấp nhận",
    	modes_levenshtein_similar_tests_title = "modes.levenshtein() Kiểm tra khoảng cách <b>[[w:Distance_de_Levenshtein|Levenshtein]]</b> entre mots:",
    	modes_args_known_structure_title	= "modes.args_known_structure() Định nghĩa đối số",
    	modes_args_unknown_report_title		= "viewers.simple_list_test() Báo cáo đối số không xác định",
    	modes_normal_box_main_text_1		= "Hộp thông tin đơn giản: tiêu đề để trang này <b>%1</b>, mô tả: <b>%2</b>",
    	modes_normal_box_main_text_2		= "<br/>Anh ta <b>%1</b>, tên anh ta <b>%2</b> <b>%3</b>, anh ta đã chết <b>%4</b>.",
    	-- Ces textes sont utilisés pour titrer des tests.
    	modes_list_wiki_selectors_title		= "Danh sách các bộ chọn để mô-đun này:",
    	modes_all_categories_list_title		= "modes.all_categories_list() Danh sách các danh mục có thể có để mô-đun này:",
    	modes_all_errors_list_title			= "modes.all_errors_list() Danh sách các lỗi có thể phát hiện trong mô-đun này:",
    	modes_multiple_values_tests_title	= "modes.multiple_values() Thử nghiệm đối số nhiều giá trị",
    	modes_multiple_selection_tests_title= "modes.multiple_selection() Kiểm tra nhiều lựa chọn",
    	modes_multiple_selection_test_headers= "Tùy chọn; Bộ chọn; Để chọn; Đã chọn",
    	modes_multiple_selection_test_select= "2; nobel; chủ tịch; Phó; giá",
    	modes_recursiveLevel_err			= "Lỗi mức đệ quy <b>%1</b> > <b>%2</b>",
    	modes_recursive_normal_tests_title	= "modes.recursive_normal() Kiểm tra: Bình thường hóa mức đệ quy và giới hạn đệ quy",
    	modes_namespaces_page_list_title	= "modes.namespaces_page_list() Mô-đun, namespaces, và tên trang:",
    	modes_args_known_report_title		= "modes.args_known_report(t) Báo cáo để các đối số được biết đến chính.",
    	modes_args_known_report_headers		= "chính; giá trị; loại; cần thiết; từ khóa; đồng nghĩa; bất động sản; định dạng; nguồn",
    	modes_get_args_report_title			= "modes.get_args() Giá trị để các đối số trong p.args_known{}.",
    } -- modes.i18n.vi
    
    -- - - - ------------------ - - - - ---------------------------------
    -- Support of the management of options. Sostén de la gestión de las opciones. Soutien de la gestion des options.
    -- - - - ------------------ - - - - ---------------------------------
    
    modes.options_for_modes = { -- default options_for_modes
    	read	= " box1 ",
    	edit	= " box1 docdef docline docsrc docdata catview docview : ",
    	doc		= " nobox1 noerr nocatview ",
    	tests	= " box1 docdef docline docsrc docdata catview docview : tests ",
    	-- List of parameters for module documentation
    	-- "docview" or ":" add the documentation panel
    	-- "docmin" list only some basic parameters
    	-- "docdef" list only the parameters defined, having a non-zero value
    	-- "docmax" list all known parameters
    	-- "docnotice" generate documentations of records
    	-- "docline" put all parameters on a single line
    	-- "docsrc" put the parameters in colors according to the sources
    	-- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc : " -- for standard documentation
    	-- modes.options = " erron noerr nobox1 nocatview " -- do not form normal result
    	-- modes.options = " debug tests en es fr " -- enforce a language for debug
    	-- Option nocatview means "Do not categorize and do not show categories."
    }
    
    -- Manage Library:modes options. Administrar opciones. Gérer les options.
    modes.template_options = "" -- Normal options from the template, like {{Bananas|options=docmax docdef}}.
    modes.mode_options = "" -- Internal options from the mode.
    modes.available_options = "" -- table to collect all available options, at any time.
    modes.used_options = {} -- table to collect really or tested options then list them at end of tests.
    
    mathroman.args_known = { -- Table of the definitions of all known arguments at module level.
    	-- Arguments in order without names, with their keyword for use as other arguments.
    	[1]				= {need = 0,		syn = 2,	keyword = "mode"},
    	-- Special arguments to modify the fonctions and outputs of this module.
    	mode			= {typ = "config",	need = 0,	keyword = "mode"},
    	c				= {typ = "config",	need = 0,	keyword = "c"},
    	options			= {typ = "config",	need = 0,	keyword = "options"},
    	-- The userlang argument permits at an administrator in his own langage (errors, warnings, catégories, tests) to help a wiki in any language.
    	contentlang		= {typ = "config",	need = 1,	keyword = "contentlang"},
    	pagelang		= {typ = "config",	need = 2,	keyword = "pagelang"},
    	userlang		= {typ = "config",	need = 0,	keyword = "userlang"},
    	birthyear		= {typ = "dat",		need = 0,	keyword = "birthyear", prop = "P569", format = "year"},
    }
    
    function modes.bind_args_known_props(args_known, args_new) -- Bind known args and their properties for central libraries. Later for modules.
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	if (type(args_known) ~= "table") then return {} end
    	local args_known_one = {}
    	if (type(args_new) ~= "table") then return args_known end
    	for key, props in pairs(args_new) do -- import and mix known args and properties
    		if (type(props) == "table") then
    			args_known_one[key] = props or args_known[key]
    			props.key = key
    		end -- Add properties for a new argument
    	end
    	return args_known_one
    end -- local args_known_props = modes.bind_args_known_props(args_known, args_new)
    
    function modes.args_known_one_lib(args_known, args_new) -- Bind known args and their properties for central libraries. Later for modules.
    	local args_known = args_known or modes.args_known or p.args_known or {} -- modes.args_known = { -- p.args_known = { -- }
    	if (type(args_known) ~= "table") then return {} end
    	local args_known_props = {}
    	for key, one_lib in pairs(args_new) do -- import and mix known args and properties
    		if (type(one_lib) == "table") then
    			bind_args = modes.bind_args_known_props(args_known, args_new)
    			args_known_props = modes.bind_args_known_props(modes.args_known, args_new)
    		end
    	end
    	return args_known_props
    end -- function modes.args_known_one_lib(args_known, args_new)
    
    function modes.bind_args_known_one_lib_report(t) -- Report the binding of one library known args.
    	local memo = viewers.save_configs("modes.bind_args_known_one_lib_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* mathroman.args_known_one_lib(t) Report the binding of one library known args."
    	local args_known = args_known or modes.args_known or p.args_known or {} -- modes.args_known = { -- p.args_known = { -- }
    	local args_known_props = modes.args_known_one_lib(modes.args_known, mathroman.args_known)
    	t = t .. "\n* " .. viewers.ta("#args_known_props", lua_table.level_count(args_known_props) )
    	if (type(args_known) ~= "table") then return args_known end
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = args_known,
    		rowGroup = {},
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			return { viewers.value(case.key), case.bind, case.typ, case.need, case.keyword, case.prop, case.format, }
    		end,
    		title_memo = "modes_bind_args_known_report_title",
    		title_memo = "modes.bind_args_known_one_lib_report(t) Report the binding of one library known args. **",
    		headers = "modes_bind_args_known_report_headers",
    		headers = "key;bind;typ;need;keyword;prop;format",
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "modes.bind_args_known_one_lib_report") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.bind_args_known_one_lib_report(t)
    
    function lua_table.sort_onkey(tab, key) -- Sort a table with any types of keys.
    --	local tab = tab or {} -- keep table errors to permit to debug
    	local key = key or "keyword"
    	return table.sort(tab, function (a, b)
    		if (type(a[key]) == type(b[key])) then return ( a[key] < b[key] ) -- any translated arguments of same types
    		else return ( tostring(a[key]) < tostring(b[key]) ) end -- alphabetic sort of translated arguments
    	end )
    end
    
    function modes.args_known_report(t, args_known) -- Report of main known args.
    	local memo = viewers.save_configs("modes.args_known_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>modes.args_known_report(t)</b> Report of main known args."
    	local args_known = args_known or modes.args_known or p.args_known or {} -- modes.args_known = { -- p.args_known = { -- }
    	local args_group = {} -- modes.args_known = { -- p.args_known = { -- }
    	for key, tab in pairs(args_known) do -- import and mix known args and properties
    		table.insert( args_group, tab )
    	end
    	local prop, props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page. ric
    	table.sort(props, function (a, b) return ( (a.keyword or a.prop) < (b.keyword or b.prop)) end ) -- alphabetic sort of translated arguments
    	t = t .. "\n* " .. viewers.ta("args_known count", lua_table.level_count(args_known) )
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = args_group, -- tab_view.test_group or
    		rowGroup = {},
    		title_memo = "modes.args_known_report(t) Report of main known args. **",
    		title_memo = "modes_args_known_report_title", -- "modes.args_known_report(t) Rapport des principaux arguments connus.",
    		headers = "modes_args_known_report_headers", -- headers = "key; val; type; need; keyword; syn; prop; format; source",
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup. tab_view.form_one_case or
    			return { (case.keyword), (case.val or "-"), case.typ, case.need, case.keyword, case.syn, case.prop, case.format, case.src, }
    		end,
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "modes.args_known_report") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.args_known_report(t, args_final)
    
    function modes.init_options(template_options)
    	-- modes.template_options = modes.init_options(args.options)
    	-- modes.template_options = modes.init_options("fr params docview docmin docmax docdef docnotice docafter docline docsrc")
    	if (type(template_options) == "string") then modes.template_options = template_options end
    	if (type(modes.template_options) ~= "string") then modes.template_options = "" end
    	-- Early effects on options which modify other ones.
    	-- modes.options = " : docdata docmin docdef docmax docline docview docafter docnotice docsrc" -- for documentation
    	-- modes.options = " erron noerr nobox1 nocatview " -- without normal result
    	-- modes.options = " debug tests en es fr " -- for debug or enforce language
    	modes.options_to_cat_view()
    	if modes.option("noerr") then events.erron = false end
    	if modes.option("erron") then events.erron = true end
    	if modes.option("docolor") then modes.docolor = true end
    	-- If an option is a language, enable this language for the user.
    	-- Si una opción es un lenguaje, activar esta lengua para usuario.
    	-- Si une option est une langue, activer cette langue pour l'utilisateur.
    	for lang, tab in pairs(versions.i18n) do
    		if modes.option(lang) then
    			langs.init_content_page_user_lang(langs.content_lang, xx, yy, lang) -- langs.content_lang, langs.user_lang
    		end
    	end
    	return modes.template_options
    end -- function modes.init_options(template_options)
    
    function modes.options_from_mode(mode_name, options_for_modes)
    	modes.options_for_modes = options_for_modes or modes.options_for_modes
    	modes.mode_name = mode_name or modes.mode_name or "read"
    	if modes.options_for_modes and modes.options_for_modes[mode_name] then modes.mode_options = modes.options_for_modes[mode_name] end
    	return modes.mode_options, mode_name
    end
    
    function modes.option(key, opt) -- Is one option in available options?
    	-- Language identifiers allow to enforce some languages.
    	-- Errors appear only in Template or Module namespace, waiting the task T53660.
    	if type(key) ~= "string" then key = "" end
    	key = mw.text.trim(key)
    	if type(opt) ~= "string" then opt = "" end
    	opt = mw.text.trim(opt)
    	local available_options = (modes.template_options or "")
    	if available_options and modes.mode_options -- other param can replace modes.mode_options
    	then	available_options = " " .. available_options .. " " .. modes.mode_options .. " "
    	elseif	available_options and opt then available_options = " " .. available_options .. " " .. opt .. " " end
    	available_options = viewers.simple_list(available_options, " ")
    	-- The searched keyword is it among the options words? And not included in another word.
    	local ifyes = viewers.is_in_sp(key or "", available_options) -- and true
    	-- Collect options tested along the execution of the module
    	modes.used_options = modes.used_options or {}
    	if ifyes then modes.used_options[key] = "y"
    	else modes.used_options[key] = "n" end
    	local used = ""
    	for key, xx in pairs(modes.used_options) do
    		if xx == "y" then used = used .. ", <b>" .. tostring(key) .. "</b> " .. xx
    		else used = used .. " " .. tostring(key) .. ", " .. xx end
    	end
    	modes.available_options = available_options
    	modes.used_opts = used -- yes is not nil
    	return ifyes, used, available_options -- yes is not nil
    end -- function modes.option(key, opt)
    
    function modes.options_from_mode_tests(t)
    	local memo = viewers.save_configs("modes.options_from_mode_tests") -- Save global configuration before eventual changes.
    	local t = tostring(t)
    	local t = t or "options_from_mode_test:"
    	for md, opt in pairs(modes.options_for_modes) do t = t .. "<br>- " .. viewers.ta(md, opt) end
    	t = t .. viewers.table_head() .. viewers.table_col("Mode") .. viewers.table_col("List of options") .. viewers.table_col("noerr value") .. viewers.table_col("docview value") .. viewers.table_col("tests value")
    	local function test_options_from_mode(md, op1, op2, op3)
    		modes.available_options = ""
    		local opstest = modes.options_from_mode(md) or ""
    		return viewers.table_row() .. viewers.table_dat(md) .. viewers.table_dat(opstest) .. viewers.table_dat( modes.option(op1, opstest) )
    		.. viewers.table_dat(modes.option(op2, opstest)) .. viewers.table_dat(modes.option(op3, opstest))
    	end
    	t = t .. "<br>options_from_mode_test:"
    	t = t .. test_options_from_mode("read", "noerr", "docview", "tests")
    	t = t .. test_options_from_mode("edit", "noerr", "docview", "tests")
    	t = t .. test_options_from_mode("tests", "noerr", "docview", "tests")
    	t = t .. viewers.table_end()
    	viewers.restore_configs(memo, "modes.options_from_mode_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.options_from_mode_tests(t)
    
    function modes.used_options_list(t, used_options)
    	local t = t or "List of modes:"
    	used_options = used_options or modes.used_options
    	modes.mode_name = mode_name or modes.mode_name or "read"
    	for md, opt in pairs(modes.options_for_modes) do t = t .. "<br>- " .. viewers.ta(md, opt) end
    	-- List of used options after collect them
    	t = t .. "\n* " .. viewers.form9user("langs_content_page_user_lang_msg", langs.user_lang, langs.content_lang)
    	t = t .. "\n* Actual mode used: <b>" .. modes.mode_name .. "</b>"
    	t = t .. "\n* Options read the last time in these tests, ones <b>activated</b> are in bold: "
    	t = t .. "\n* Options lues pour la dernière fois pendant ces tests, celles <b>activées</b> sont en gras : "
    	t = t .. "<br>"
    	local used = ""
    	for key, x in pairs(modes.used_options) do
    		if x == "y" then used = used .. ", <b>" .. tostring(key) .. "</b> "
    		else used = used .. ", " .. tostring(key) .. " " end
    	end
    	t = t .. used
    	return t, used
    end
    
    function modes.options_to_cat_view() -- Init or restaure modes.cat_view = modes.cat_view from options
    	if modes.option(":") or modes.option("catview") then modes.cat_view = ":" else modes.cat_view = "" end
    	return modes.cat_view
    end -- function modes.options_to_cat_view()
    
    function modes.options_from_args_tests(t)
    	local memo = viewers.save_configs("modes.options_from_args_tests") -- Save global configuration before eventual changes.
    	local mode_options_memo = modes.mode_options -- save
    	local template_options_memo = modes.template_options -- save
    	local used_options_memo = mw.clone(modes.used_options) -- save
    	modes.used_options = {} -- for test
    	local t = tostring(t)
    	t = t or "options_from_args_tests:"
    	t = t .. viewers.table_head() .. viewers.table_col("mode_options") .. viewers.table_col("template_options") .. viewers.table_col("opt can replace mode_options")
    	.. viewers.table_col("available options") .. viewers.table_col("option result") .. viewers.table_col("valid result")
    	local function options_from_args(mode_options, template_options, opt, key, verif)
    		modes.available_options = ""
    		modes.mode_options = mode_options or ""
    		modes.template_options = template_options or ""
    		local ifyes, available_options = modes.option(key, opt)
    		local testOK = ""
    		if tostring(ifyes) == tostring(verif) then testOK = "true" else testOK = "false" end
    		return viewers.table_row() .. viewers.table_dat( mode_options or "" ) .. viewers.table_dat( template_options or "" ) .. viewers.table_dat( opt or "" )
    		.. viewers.table_dat( modes.available_options ) .. viewers.table_dat( viewers.ta(key, ifyes) ) .. viewers.table_dat( testOK )
    	end
    	t = t .. options_from_args("nobox1 nocatview", "en docview", nil,			"nobox1",	"true")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", nil,			"nocatview",	"true")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", nil,			"en",		"true")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", nil,			"docview",	"true")
    	t = t .. options_from_args("nobox1 nocatview", ": docview", nil,			":",		"true")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", "docline fr",	"docline",	"false")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", "docline fr",	"docline",	"false")
    	t = t .. options_from_args("		   ", nil,			"docline fr",	"docline",	"false")
    	t = t .. options_from_args("		   ", nil,			"docline fr",	"fr",		"false")
    	t = t .. options_from_args("		   ", "en docview", "docline fr",	"en",		"true")
    	t = t .. options_from_args("nobox1 nocatview", nil,			"docline fr",	"docline",	"false")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", "docline fr",	nil,		"true")
    	t = t .. options_from_args("nobox1 nocatview", "en docview", nil,			"docline",	"false")
    	t = t .. viewers.table_end()
    	t = t .. modes.used_options_list(nil, modes.used_options)
    	t = t .. "\n* After these tests, previous options are restored. Après ces tests, les options antérieures sont restaurés."
    	modes.mode_options = mode_options_memo -- restore
    	modes.template_options = template_options_memo -- restore
    	modes.used_options = used_options_memo -- restore
    	viewers.restore_configs(memo, "modes.options_from_args_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.options_from_args_tests(t)
    
    function modes.change_itemid(id_in) -- Select a wikidata default item if needed.
    	local id = ""
    	if id_in then -- Local function parameter have priority.
    		id = id_in
    	else -- Else use the template arguments or inforce QITEM here.
    		id = modes.args_source.id
    	--	id = "Q535"		--	(1802 – 1885) Victor Hugo
    	--	id = "Q8739"	--	(near 287 av. J.-C. – 212 av. J.-C.) Archimède, Machine d'Archimède
    	--	id = "Q20882"	--	(1832 – 1923) Gustave Eiffel
    		id = "Q1290"	--	(1623 – 1662) Blaise Pascal
    	--	id = "Q41568"	--	(1533 – 1592) Michel de Montaigne
    	--	id = "Q83428"	--	(near 1493 – 1541) Paracelse
    	--	id = "Q131671"	--	(VIe siècle av. J.-C. – Ve siècle av. J.-C.) Xénophane
    	--	id = "Q213330"	--	(1330 – 1418) Nicolas Flamel
    	--	id = "Q21157618"--	(	  – 1932) Charles Maumené
    	--	id = "Q9364"	--	(1905 – 1980) Jean-Paul Sartre
    	end
    	local nst = 10 -- mw.site.namespaces.Template
    	local nsm = 828 -- mw.site.namespaces.Module
    	local mwtitle = mw.title.getCurrentTitle()
    	modes.main_title = mwtitle.text -- Server mw.uri.new
    	local nsX = mw.title.getCurrentTitle():inNamespaces("10", "11", "828", "829")
    	local nsX = mwtitle:inNamespaces("10", "11", "828", "829")
    	local ns = tostring(mw.site.namespaces.id)
    	if viewers.is_in_sp(ns, "10;11;828;829", ";") then
    		-- Change QITEM only where title cannot be in wikidata.
    		id = id or modes.main_title or modes.args_template.title or modes.args_template.QITEM or modes.args_template.label or modes.args_template.itemid
    	end
    	return id
    end -- function modes.change_itemid(id_in)
    
    function modes.args_known_structure(t, args_known) -- modes_args_known_structure_title = Table structure of arguments
    --	if true then return "" end -- to DEBUG : S170606aks
    	local t = t or "\n* <b>args_known_structure :</b> " -- modes_list_all_args_main_title
    	local tt
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {		}
    	if type(args_known) == "table" then
    		for key, elem in pairs(args_known) do
    			tt = viewers.tam("typ", elem.typ) .. viewers.tam("keyword", elem.keyword) .. viewers.tam("syn", elem.syn)
    			tt = tt .. viewers.tam("need", elem.need) .. viewers.tam("prop", elem.prop) .. viewers.tam("format", elem.format)
    			tt = string.sub(tt, 3, -1)
    			t = t .. '\n: ' .. tostring(key) .. ' = { ' .. tt .. ' } '
    		end
    	end
    	return t
    end -- function modes.args_known_structure(t, args_known)
    
    function modes.levenshtein(word1, word2) -- Compute the Levenshtein distance between 2 ASCII words.
    	-- prevent exceptions
    	local cout = 0
    	if (type(word1) ~= "string") or (type(word2) ~= "string") then
    		return 999, "<br>lev: " .. viewers.ta("word1", word1) .. viewers.ta("word2", word2)
    	end
    	local len1 = string.len(word1)
    	local len2 = string.len(word2)
    	local lev = 0
    	local t = "<br>lev: " .. viewers.ta("word1", word1) .. viewers.ta("word2", word2)
    	if (type(word1) ~= "string") or (type(word2) ~= "string") or (word1 == "") or (word2 == "") then
    		lev = len1 + len2
    		return lev, t .. viewers.ta("lev", lev)
    	end
    	-- simple case
    	if (word1 == word2) then
    		lev = 0
    		return lev, t .. viewers.ta("lev", lev)
    	end
    	local d = {}
    	for i = 1, len1+2 do -- for i = 1, len1-1+1 do
    		d[i] = {}
    		--	d[i][1] = 0 -- d[i][1] = i
    		for j = 1, len2+2 do
    			--	d[i][j] = {}
    			d[i][j] = 0 -- d[1][j] = j
    		end
    	end
    	-- simulate double dimensions tables
    	for i = 2, len1+1 do -- for i = 1, len1-1+1 do
    		--	d[i] = {}
    		d[i][1] = i-1 -- d[i][1] = i
    	end
    	for j = 2, len2+1 do
    		d[1][j] = j-1 -- d[1][j] = j
    	end
    	for i = 2, len1+1 do -- for i = 2, len1+1 do
    		for j = 2, len2+1 do -- for j = 2, len2+1 do
    			-- we recover the two characters
    			local c1 = string.byte(word1, i-1)
    			local c2 = string.byte(word2, j-1)
    			if (c1 == c2) then
    				cout = 0
    				d[i][j] = d[i-1][j-1]
    			else
    				cout = 1
    				d[i][j] = math.min(d[i-1][j], d[i][j-1], d[i-1][j-1]) + 1
    			end
    			--	d[i][j] = math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cout)
    		end
    	end
    	local lev = d[len1+1][len2+1] -- return d[len1-1][len2] - 1
    	return lev, t .. viewers.ta("lev", lev)
    end -- function modes.levenshtein(word1, word2)
    
    function modes.levenshtein_similar_tests(t) -- Tests of modes.similar_args_diffmaxi(10, t .. "diffmaxi = ")
    	local memo = viewers.save_configs("modes.levenshtein_similar_tests") -- Save global configuration before eventual changes.
    	local t = t or ("\n* " .. viewers.form9user("modes_max_nearest_argument_msg") ) -- "A longer name argument accepts more letter errors."
    	t = t .. "\n* " .. "Formula to compute the near words limit: Formule de calcul de limite des mots proches : "
    	local errors, key, argsyn, arglingual, txt = ""
    	t = t ..  "\n* List of diffmaxi / lengths : "
    	local diffmaxi
    	for i = 1, 10 do
    		diffmaxi, tt  = modes.similar_args_diffmaxi( string.sub("azertyuiopqsdfghjklm", 1, i), "azertyuiopqsdfghjklm") -- Format a string from the formula
    		modes.length_from_i[i] = diffmaxi
    		t = t .. viewers.ta(tostring(i), diffmaxi)
    	end
    	local diffmaxi, tt = modes.similar_args_diffmaxi(10, t .. "diffmaxi = ")
    	local group_test = { -- events.test_group
    		{ try = "nom",			correct = "nom", },
    		{ try = "nom",			correct = "Nom", },
    		{ try = "top",			correct = "pot", },
    		{ try = "ami",			correct = "amis", },
    		{ try = "nom",			correct = "name", },
    		{ try = "m",			correct = "mu", },
    		{ try = "m",			correct = "mur", },
    		{ try = "mur",			correct = "m", },
    		{ try = "c",			correct = "c", },
    		{ try = "c",			correct = "long", },
    		{ try = "xxx",			correct = " ", },
    		{ try = "",				correct = "xyz", },
    		{ try = "xxx",			correct = "xyz", },
    		{ try = "prénom",		correct = "Prenom", },
    		{ try = "catégorie",	correct = "Category", },
    		{ try = "description",	correct = "Description", },
    		{ try = "anneeDeces",	correct = "anneeNaissance", },
    		{ try = "avant-après",	correct = "après-avant", },
    	}
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = group_test,
    		title_memo = "modes.recursive_normal() Test: Normalize the recursive level and the recursive limit",
    		headers = "try; try_length; correct; correct_length; error", -- Test Normalize recursiveLevel and recursive_limit
    		headers_class = "wikitable alternative center sortable",
    		modes_nearest_argument_err			= "Error: Do you need the known argument <b>%1</b> ?",
    		modes_max_nearest_argument_msg		= "A longer name argument accepts more letter errors.",
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			case.try_length = string.len(case.try)
    			case.correct_length = string.len(case.correct)
    			case.diffmaxi = modes.similar_args_diffmaxi( string.len(case.try) )
    			case.diff = modes.similar_args_diffmaxi(case.correct)
    			if case.diff > case.diffmaxi then case.errors = viewers.usual_color(case.correct, "error") end
    			return { case.try, case.try_length, case.correct, case.correct_length, case.errors }
    		end,
    		rowGroup = {},
    	--	track_on == "details",
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Form a table view with lines and columns.
    	t = t .. "\n* <b>levenshtein_test</b> errors = " .. viewers.styles_color_error(errors)
    	viewers.restore_configs(memo, "modes.levenshtein_similar_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.levenshtein_similar_tests( res, c)
    
    modes.constants = modes.constants or {}
    -- Similar words search : diff on length
    -- Cerrar de palabras puscadas: diff en longitud
    -- Recherche de mots proches: diff sur longueur
    modes.constants.near_word_search_diff_coef = 0.30 -- Access to change these constants from anywhere.
    modes.constants.near_word_search_diff_const = 0.82
    
    -- Maximum number of different letters between 2 argument names
    -- Número máximo de letras diferentes entre 2 nombres de argumento
    -- Nombre maximum de lettres différentes entre deux noms d'arguments
    modes.length_from_i = {} -- Format a string from the formula
    function modes.similar_args_diffmaxi(word, t) -- Format a string from the formula
    	local coef = modes.constants.near_word_search_diff_coef or 0.30
    	local constant = modes.constants.near_word_search_diff_const or 0.82
    	local word = tostring(word)
    	local length = string.len(word)
    	local diffmaxi = math.floor( coef * length + constant )
    	if type(t) == "string" then t = t .. tostring(coef) .. " * length + " .. tostring(constant) else t = "" end
    	return diffmaxi, t
    end -- local diffmaxi, t = function modes.similar_args_diffmaxi(word, t) -- Format a string from the formula
    
    -- For an unknown argument, seeks the name of the closest among the known arguments translated
    function modes.similar_args_list(args_known)
    	local list, arglingual = {}, "xxx"
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	if type(args_known) ~= "table" then return "similar_args_list", 1 end
    	for key, argm in pairs(args_known) do -- List only all known arguments
    		if not tonumber(key) then -- For named arguments only
    			key = tostring(key)
    			arglingual = tostring(langs.content_translations[key])
    			list[key] = arglingual
    		end
    	end
    	return list
    end -- function modes.similar_args_list(args_known)
    
    -- Check if the value of an argument is among the possible values.
    -- Vérifier si la valeur d'un argument est parmi les valeurs possibles.
    --	local ... = modes.multiple_values(test.argm, test.argvalue, test.args_final)
    function modes.multiple_values(argname, argvalue, args_final, args_known)
    	if type(args_final) ~= "table" then args_final = modes.args_final or {} end
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	local argvalue = argvalue or args_final[argname]
    	local arg_values, key_values, keyword, keyval, argval, rank
    	local argmt = args_known[argname]
    	if argmt then
    		arg_values = langs.content_translations[argmt.arg_values] or "" -- example "no;nada;cn;50;us;70;mpf" in local language
    		key_values = argmt.key_values or "" -- example "no;none;cn;50;us;70;mpf" in referal english
    	end
    	if type(arg_values) == "string" and type(key_values) == "string" then
    		local arg_tab = mw.text.split(arg_values, ';') -- table of argmt
    		local key_tab = mw.text.split(key_values, ';') -- table of key
    		-- Default values
    		keyword = nil
    		rank = 0 -- rank of local value and key value
    		keyval = nil -- key value
    		argval = nil
    		if argmt and arg_values and argvalue then
    			for i, key in ipairs(arg_tab) do
    				if key == argvalue then -- Search argvalue in arg_tab
    					rank = i
    					keyval = key_tab[i] -- Return correponding keyval in key_tab
    					argval = argvalue
    					keyword = argmt.keyword
    				end
    			end
    		end
    	end
    	return keyword, keyval, argval, rank, arg_values
    end -- function modes.multiple_values(argname, argvalue, args_final, args_known)
    
    function modes.multiple_values_tests(t) -- Test: convert a string to a table of words
    	local t = t or "\n* Test <b>multiple_values</b> :"
    	local group_test = { -- events.test_group
    		{ argm = "region",	argvalue = "inde", },
    		{ argm = "region",	argvalue = nil, },
    		{ argm = "rights",	argvalue = "mpf", },
    		{ argm = "rights",	argvalue = "non", },
    		{ argm = "rights",	argvalue = nil, },
    		{ argm = "sex",	 argvalue = "femme", },
    		{ argm = "sex",	 argvalue = "homme", },
    		{ argm = "sex",	 argvalue = "enfant", },
    --	rights_values					= '70,50,mpf,ONU,none', -- example
    --	region							= 'region', -- argument with verified multiple values
    	}
    	local tab_view = {}
    	tab_view.headers = viewers.form9user("argm; all values; value; keyword; keyval; argval; rank")
    	tab_view.test_group = group_test
    	tab_view.rowGroup = {}
    	if type(group_test) == "table" then
    		for i, test in ipairs(group_test) do
    			local keyword, keyval, argval, rank, arg_values = modes.multiple_values(test.argm, test.argvalue, test.args_final)
    			table.insert( tab_view.rowGroup, { tostring(test.argm or "-"), tostring(arg_values or "-"), tostring(test.argvalue or "-"), tostring(keyword or "-"), tostring(keyval or "-"), tostring(argval or "-"), tostring(rank or "-") } )
    		end
    	else t = t .. "error : multiple_values_tests has no table. " end
    	t = t .. tableview.new(tab_view) -- Formats a table with lines and columns.
    	return t
    end -- function modes.multiple_values_tests(t)
    
    function modes.multiple_selection(opt, selector, to_select)
    	-- Select items to selector containing selecting items
    	local t, selected_txt, selector_txt, selector_tab, to_select_txt, to_select_tab, selected_tab = "", ""
    	local cut = string.sub( opt, 1, 1 ) or ";"
    	if type(selector) == "table" then selector_tab = selector end
    	if type(selector) == "string" then selector_tab = mw.text.split(selector, cut, true) end
    	if type(to_select) == "table" then to_select_tab = clone(to_select) end
    	if type(to_select) == "string" then to_select_tab = mw.text.split(to_select, cut, true) end
    	selected_tab = {}
    	local k, Nsel, N, maxi, pos = 0, 0, 1, 999, nil
    	local reject_select = false
    	local equal = true
    	for i, selector in ipairs(selector_tab) do -- selector authorities only following selectors
    		if Nsel >= maxi then break end
    		selector = mw.text.trim(selector)
    		N = tonumber(selector)
    		if selector == "+" then -- selector all items
    			for key, val in pairs(to_select_tab) do
    				Nsel = Nsel + 1
    				selected_tab[key] = val
    			end
    		elseif selector == "-" then -- minus sign rejects all
    			reject_select = true
    		elseif N and N < 1 then -- minus sign rejects all
    			reject_select = true
    		elseif N and (string.sub(selector, 1, 1) == "+") then -- selector +N more items
    			maxi = Nsel + N
    		elseif N then -- selector N maximum total items
    			maxi = N
    		else -- selector ONE item from to_select_tab if it matches selector ( not - or + or +N or N )
    			for key, val in pairs(to_select_tab) do
    				local select_t, val_t = selector, val
    				if not viewers.is_in("U", opt) then select_t = string.lower(select_t) end -- recognize lowercase and uppercase
    				if not viewers.is_in("t", opt) then select_t = mw.text.trim(select_t) end -- recognize after trim
    				if not viewers.is_in("U", opt) then val_t = string.lower(val_t) end -- recognize lowercase and uppercase
    				if not viewers.is_in("t", opt) then val_t = mw.text.trim(val_t) end -- recognize after trim
    				equal = viewers.is_in("=", opt) -- recognize only equal string
    				if equal then equal = (selector == val) else equal = viewers.is_in(select_t, val_t) end
    			--	if viewers.is_in(selector, val) then
    				if equal then -- recognize if selector is equal or is inside an item from to_select_tab
    					t = t .. viewers.ta(selector, val)
    					selected_tab[selector] = val
    					Nsel = Nsel + 1
    					to_select_tab[key] = " " -- Delete the selected item to use it only once
    					selected_txt = selected_txt .. val .. ', '
    				end
    			end
    		end
    	end
    	return selected_txt, selected_tab, t
    end -- function modes.multiple_selection(opt, selector, to_select)
    
    function modes.multiple_selection_tests(t) -- reports examples of multiple selections of honors for some persons.
    	local memo = viewers.save_configs("modes.multiple_selection_tests") -- Save global configuration before eventual changes.
    	local t = (t or "") .. "\n* <b>multiple_selection</b> options: " .. viewers.ta("=", "equal only") .. viewers.ta("t", "not trim before and after") .. viewers.ta("U", "not lowercase and uppercase")
    	--[[
    	local function multiple_selection_test1(t, opt, selector, to_select)
    		local selected_txt, selected_tab, txt = modes.multiple_selection(opt, selector, to_select)
    		local t = t .. viewers.table_row() .. viewers.table_dat(opt) .. viewers.table_dat(selector) .. viewers.table_dat(to_select) .. viewers.table_dat( txt .. viewers.ta("selected_txt", selected_txt) )
    		return t, opt, selector, to_select -- , selected_txt, selected_tab
    	end
    	--]]
    	local opt = "; "
    	t = t .. "\n: selector = <b>nobel,+1,président,3,député,prix</b> signifie : sélectionner le premier, puis 1 de plus parmi les suivants, puis 3 en tout au maximum."
    	local head = mw.text.split( viewers.form9user("modes_multiple_selection_test_headers") , ';')
    	t = t .. viewers.table_head() .. viewers.table_col(head[1]) .. viewers.table_col(head[2]) .. viewers.table_col(head[3]) .. viewers.table_col(head[4])
    --	recursiveLevel, recursive_limit, recursiveLevel_err == modes.recursive_normal(recursiveLevel, recursive_limit) -- typical use tab_view
    	local t = t or "\n* modes.recursive_normal_tests: "
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ recursiveLevel_in = nil, recursive_limit_in = nil, },
    			{ recursiveLevel_in = -12, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 1, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 1, recursive_limit_in = 0, },
    			{ recursiveLevel_in = 2.718, recursive_limit_in = 3.1416, },
    			{ recursiveLevel_in = 3, recursive_limit_in = nil, },
    			{ recursiveLevel_in = 5, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 6, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 11111, recursive_limit_in = 5, "versions_module_miss_i18n_count_err" },
    		},
    		title_memo = "viewers_save_restore_balance_title",
    		headers = "viewers_save_restore_balance_headers", -- viewers_tableView_default_headers
    		headers = "select; First alternative; Second alternative; errors",
    		headers_class = "wikitable alternative center sortable",
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    	--	local function recursive_normal_test1(case.recursiveLevel_in, case.recursive_limit_in, case.modes_recursiveLevel_err)
    			case.recursiveLevel, case.recursive_limit, case.recursiveLevel_err =
    			modes.recursive_normal( case.recursiveLevel_in or modes.recursive_limit or 1, recursive_limit_in or modes.recursive_limit or 3 )
    			local t = "\n* " .. viewers.ta("Level_in", case.recursiveLevel_in) .. viewers.ta("Limit_in", recursive_limit_in)
    			t = t .. viewers.ta("recursiveLevel", recursiveLevel) .. viewers.ta("recursive_limit", recursive_limit) .. viewers.ta("recursiveLevel_err", recursiveLevel_err)
    			return { case.recursiveLevel_in, case.recursive_limit_in, case.recursiveLevel, case.recursive_limit, case.modes_recursiveLevel_err }
    		end,
    	--	headers = "Level_in; Limit_in; recursiveLevel; recursive_limit; recursiveLevel_err", -- viewers_tableView_default_headers
    		rowGroup = {},
    	--	track_on == "details",
    	}
    	t = t .. "<br/> after convert in form_one_case = function(case)"
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Form a table view with lines and columns.
    	viewers.restore_configs(memo, "modes.recursive_normal_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.multiple_selection_tests(t)
    
    function modes.verify_args_tables(_known, _source)
    	-- initialize all the values to "" in argmt table
    --	if type(_known) ~= "table" then _known = modes.args_known end
    --	if type(_source) ~= "table" then _source = modes.args_source end
    	if type(modes.args_known) ~= "table" then
    		events.add_err("modes_no_known_arguments_err")
    		events.add_cat("modes_no_known_arguments_i_cat")
    		return viewers.styles_color_error(" Internal error : no source or no known arguments ! ")
    	end
    	if type(modes.args_source) ~= "table" then
    		events.add_err("modes_no_source_arguments_err")
    		events.add_cat("modes_no_source_arguments_cat")
    		return viewers.styles_color_error(" Internal error : no source or no known arguments ! ")
    	end
    	return
    end -- function modes.verify_args_tables(_known, _source)
    
    function modes.get_args(args_known) -- Update argmt.val and argmt.src in p.args_known{}
    	local m, val = modes, nil
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {...}
    	local prop, props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page.
    	local arguments_known = mw.clone(args_known)
    	local counts = { ["template"] = 0, ["import"] = 0, ["source"] = 0, ["datas"] = 0, ["final"] = 0, ["known"] = 0, }
    	local arguments = {}
    	local tt = ""
    	for key, argmt in pairs(arguments_known) do -- For all known parameters
    		if type(argmt) == "table" then
    	-- * These origins of arguments are in the increasig priority: <code>known</code>, <code>import</code>, <code>datas</code>, <code>template</code>, <code>interact_final</code>.
    			if argmt.keyword then
    				argmt.val = argmt.default ; argmt.src = "known" ;
    				counts.known = counts.known+1 ; tt = tt .. viewers.ta(argmt.src, counts.known)
    			end
    			if modes.args_import[argmt.keyword] then
    				argmt.val = modes.args_import[argmt.keyword] ; argmt.src = "import" ;
    				counts[argmt.src] = counts[argmt.src]+1 ; tt = tt .. viewers.ta(argmt.src, counts[argmt.src])
    			end
    			if prop[argmt.keyword] then
    				argmt.val = prop[argmt.keyword] ; argmt.src = "datas" ;
    				counts[argmt.src] = counts[argmt.src]+1 ; tt = tt .. viewers.ta(argmt.src, counts[argmt.src])
    			end
    			if modes.args_final[argmt.keyword] then
    				argmt.val = modes.args_final[argmt.keyword] ; argmt.src = "final" ;
    				counts[argmt.src] = counts[argmt.src]+1 ; tt = tt .. viewers.ta(argmt.src, counts[argmt.src])
    			end
    			table.insert(arguments, argmt) -- insert in the arguments their own key
    		end
    	end
    	local labelcontent_memo, label_to_change, has_label = {}, {}, {}
    	for i, onearg in pairs(arguments) do -- To search the label and labelcontent arguments
    		if onearg.keyword == "labelcontent" then labelcontent_memo = onearg end
    		if onearg.keyword == "label" then label_to_change = onearg end
    	end
    	if label_to_change and labelcontent_memo then -- To search and change the label argument
    		label_to_change.val = labelcontent_memo.val
    		label_to_change.keyword = "label"
    		label_to_change.prop = "label"
    		label_to_change.src = "datas"
    		label_to_change.need = labelcontent_memo.need
    	end
    	arguments.label = arguments.label or arguments.labeluser or arguments.labelpage or arguments.labelcontent or arguments.labelbylang -- insure label.val
    	table.sort(arguments, function (a, b) return ( tostring(a.keyword) < tostring(b.keyword) ) end ) -- alphabetic sort of translated arguments
    	modes.arguments = arguments
    	return arguments, counts, tt -- With argmt.val and argmt.src
    end -- local arguments = modes.get_args(args_known) -- Update argmt.val and argmt.src in p.args_known{}
    
    function modes.get_default_args(args_known) -- Gets default arguments values
    --	List of twice-view cases : in CentralManual modes.get_args_report ; not in ModuleCentral test mode ; yes in ModuleCentral "Doc with function from string". Search ▼
    	local memo = viewers.save_configs("modes.get_default_args") -- Save global configuration before eventual changes.
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {		}
    --	["QITEM"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "QITEM",		["prop"] = "QITEM", ["prop_default"] = "Q307", },
    --	keep Galilée (Q307), avoid Victor Hugo (Q535), Rudyard Kipling (Q34743),
    --	Galilée (Q307), Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322),
    --	Nelson Mandela (Q8023), Rudyard Kipling (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772)
    --	["QITEM"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "QITEM",	["prop"] = "QITEM", prop_default = "Q34743", },
    	for key, one_arg in pairs(args_known) do
    		if type(one_arg) == "table" then
    			if type(one_arg.default_item == "string") then datas.prop_default = one_arg.prop .. "_default" end -- "Q34743" -- Rudyard Kipling **
    		end
    	end
    	table.sort(arguments, function (a, b) return ( tostring(a.keyword) < tostring(b.keyword) ) end ) -- alphabetic sort of translated arguments
    	modes.arguments = arguments
    	viewers.restore_configs(memo, "modes.get_default_args") -- Restore global configurations after eventual changes.
    	return arguments, counts, tt -- With argmt.val and argmt.src
    end -- local arguments = modes.get_default_args(args_known) -- Gets default arguments values
    
    function modes.get_args_report(t) -- Update modes.get_args()=args_known
    --	List of twice-view cases : in CentralManual modes.get_args_report ; not in ModuleCentral test mode ; yes in ModuleCentral "Doc with function from string". Search ▼
    	local memo = viewers.save_configs("modes.get_args_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>modes.get_args(args_known)</b>:	Update argmt.val and argmt.src in p.args_known{}."
    	t = t .. '\n* List of twice-view cases : in CentralManual modes.get_args_report ; not in ModuleCentral test mode ; yes in ModuleCentral "Doc with function from string". Search ▼'
    	local arguments, counts, tt = modes.get_args(p.args_known) -- Update argmt.val and argmt.src in p.args_known{}
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = arguments, -- Use default cases.
    		rowGroup = {},
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			return { case.key, case.val or "-", case.typ, case.need, case.keyword, case.syn, case.prop, case.format, case.src or "-", }
    		end,
    		title_memo = "modes_get_args_report_title", -- "modes.get_args() Values of the arguments in p.args_known{}.", -- en
    		headers = "modes_args_known_report_headers", -- "key; val; type; need; keyword; syn; prop; format; source"
    	} -- drop_box.new(
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	t = t .. viewers.ta("args_known", lua_table.level_count(p.args_known) ) .. viewers.ta("arguments", lua_table.level_count(arguments) )
    	t = t .. "\n* Counts for all args_known{}."
    	for count, n in pairs(counts) do -- For all known parameters
    		t = t .. viewers.ta(tostring(count), n)
    	end
    	t = t .. "\n* Track argmt.keyword = n : " .. tt
    	t = t .. "\n* Final content of arguments{}."
    	for key, argmt in pairs(arguments) do -- For all known parameters
    		t = t .. viewers.ta(tostring(key), argmt.kw)
    	end
    	viewers.restore_configs(memo, "modes.get_args_report") -- Restore global configurations after eventual changes.
    	return t
    end -- t = t .. modes.get_args_report(t) -- Update modes.get_args()=args_known
    
    function modes.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template S170710mix
    	local mix = mix or {}
    	modes.mix = mix
    	-- Get basic values
    	modes.frame = mw.getCurrentFrame()
    	modes.args_template = modes.frame:getParent().args
    --	mix.args_template = args_template or mix.args_template or modes.args_template or {}
    	mix.all_args = {}
    	local function mix_args(args)
    		if (type(args) ~= "table") then args = {} end
    		for key, argmnt in pairs(args) do mix.all_args[key] = argmnt end -- get arguments named or in order.
    	end
    	-- actual steps to mix -- begin with least priority
    	mix_args(modes.args_template) -- already known, or default values args_template have the lowest priority
    	mix_args(mix.args_template)
    	mix_args(mix.args_import)
    	mix_args(args_template) -- direct args_template have the highest priority
    	-- end with most priority
    	mix.args = mix.all_args
    	return mix
    end -- local mix = modes.mix_args(mix, mode_name, args_template)
    
    function modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins
    	mix = mix or {}
    	mix.args_template = args_template or modes.args_template or mix.args_template
    	if (type(mix.args_template) ~= "table") then default = "read" end
    	mix.mode_name = mix.args_template.mode or mix.args_template[1] or mode_name or "read"
    	modes.args_template = mix.args_template
    	modes.mode_name = mix.mode_name
    	return mix
    end -- local mix = modes.mix_modes(mix, mode_name, args_template)
    
    function modes.mix_options(mix, old_group, new_group) -- Mix 2 groups of options from diverse origins S170710mix
    	mix = mix or {}
    	if (type(old_group) ~= "string") then old_group = "" end
    	if (type(new_group) ~= "string") then new_group = "" end
    	local old_group_tab = mw.text.split(old_group, " ", true)
    	local new_group_tab = mw.text.split(new_group, " ", true)
    	local all_group_tab = mw.clone(old_group_tab) -- do not disturb old_group_tab
    	for i, option in ipairs(new_group_tab) do table.insert(all_group_tab, option) end -- add new with old options
    	local no_options_tab, active_options_tab = {}, {}
    	for i, option in ipairs(all_group_tab) do -- form 2 groups of no_options and active_options
    		local no_t, opt_t = string.sub( option, 1, 2), (string.sub( option, 3) or "") -- no prefix and option without no
    		if ( no_t == "no" )
    		then no_options_tab[option] = opt_t -- form a group of no_options, perhaps to delete an active option
    		else active_options_tab[option] = option -- form a group of active_options, perhaps to delete
    		end
    	end
    	local keep_group_tab = mw.clone(all_group_tab)
    	-- Reject no_options to keep active_options
    	for i, option in pairs(active_options_tab) do
    		if ( no_options_tab[option] ) then
    			active_options_tab[option] = nil -- form a group of active_options, perhaps to delete
    		end
    	end
    	mix.active_options = table.concat(active_options_tab, " ")
    	mix.no_options = table.concat(no_options_tab, " ")
    	return mix
    end -- active_options = modes.mix_options(old_group, new_group) -- S170710mix
    
    function modes.init_args_mode_options(mix, mode_name, args_template) -- Imports and mixes args mode and options from template and invoke
    --	Guideline: Any combination of options can define a mixture of options to modify options.
    --	This function allows any module to modify this process.
    --	The default process gives the priority to options from arguments.
    --	Each "option" can be removed by the option "nooption". Options starting with "no" are disabled.
    	-- Init basic values
    	local mix = mix or {}
    	modes.mix = mix
    	mix.mode_name = mode_name or mix.mode_name or modes.mode_name
    	-- Steps to mix modes values
    	--
    	-- Once run mix_args and mix_modes, in case a mode option would change the mode.
    	mix = modes.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template
    	mix = modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins S170710mix
    	modes.options = modes.options_for_modes[modes.mode_name] -- options from mode
    	--
    	-- Once repeat mix_args and mix_modes, in case the mode changes through them.
    	mix = modes.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template
    	mix = modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins S170710mix
    	modes.options = modes.options_for_modes[modes.mode_name] -- options from mode
    	mix = modes.mix_options(mix, modes.options, modes.args_template.options ) -- Mix options from template
    	modes.options = mix.options
    	--
    	-- activate init_args_mode_options
    	modes.list_invoke = mix.list_invoke or modes.list_invoke
    	modes.list_template = mix.list_template or modes.list_template
    	modes.args_template = mix.args_template or modes.args_template
    	modes.mode_template = mix.mode_template or modes.mode_template or modes.args_template.mode
    	modes.active_options = mix.active_options or modes.active_options
    	modes.no_options = mix.no_options or modes.no_options or table.concat(no_options_tab, " ")
    	modes.options_template = mix.options_template or modes.options_template or modes.args_template.options
    	modes.mode_name = mix.mode_name or modes.mode_name
    	modes.options_for_modes = mix.options_for_modes or modes.options_for_modes
    	modes.options = mix.options or modes.options
    	return mix
    end --	modes.args_mixed = function modes.init_args_mode_options(mix, mode_name, args_template)
    
    function modes.args_mixer(args_template) -- S170703amo
    --	Guideline: Any combination of templates can define a mixture of arguments to modify arguments.
    --	This function allows any module to modify this process.
    --	The default process gives the priority to templates arguments.
    	local t = "\n* <b>modes.args_mixer()</b> Import and mix arguments from templates and invoke."
    	local args_template = args_template or modes.args_template or {}
    	t = t .. "\n* " .. viewers.ta("\n* args_template", args_template)
    	if (type(args_template) == "table") then
    		for arg_key, argment in pairs(args_template) do
    			args_template[arg_key] = argment -- sought args from templates
    			args_template.QITEM = args_template.QITEM or args_template.itemid -- temporary debug the test page
    			t = t .. viewers.ta(arg_key, argment)
    			if arg_key == "itemid" then t = t .. viewers.ta("QITEM", argment) end -- temporary debug the test page
    		end
    	end
    	args_template.QITEM = args_template.QITEM or args_template.itemid -- temporary debug the test page
    	viewers.TITL = tracker.initadd({ ["name"] = "TITL", limit = 2, }) -- Initialize a track
    	TITL.add(TITL, 1, "args_mixer", args_template ) -- TITL.t
    	-- Activate the sought args
    	modes.args_mixed = args_template
    	t = t .. viewers.ta("modes.args_mixed count", lua_table.count_all(modes.args_mixed) )
    	return modes.args_mixed
    end -- local t = modes.args_mixer(args_template)
    
    function modes.modes_mixer(args_template) -- S170703amo
    	local t = ""
    	args_template = args_template or modes.args_template
    	t = t .. viewers.ta("modes.args_template[1]", modes.args_template[1]) .. viewers.ta("modes.args_template.mode", modes.args_template.mode)
    	-- Activate the sought mode
    	modes.mode_name = modes.args_template.mode or modes.args_template[1]
    	modes.args_mixed.mode_name = modes.mode_name
    	t = t .. viewers.ta("sought mode_name", modes.mode_name)
    	return t, modes.mode_name
    end -- local t = modes.modes_mixer(args_template)
    
    function modes.options_mixer(args_template) -- S170703amo
    --	Guideline: Any combination of options can define a mixture of options to modify options.
    --	This function allows any module to modify this process.
    --	The default process gives the priority to options from arguments.
    --	Each option can be deleted by the nooption option. Then options cannot begin by "no" chars.
    --
    --	First, import args, then mix modes and options.
    	local t = "\n* <b>modes.options_mixer()</b> Import and mix options from template."
    --	modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc: " -- for documentation
    	modes.options_template = modes.args_template.options or " catview nobox1 doclist docdata nodocline"
    	modes.options_all = modes.options_template .. " " .. modes.options_invoke
    	t = t .. viewers.ta("\n* options_template", modes.options_template )
    	t = t .. viewers.ta("\n* options_invoke", modes.options_invoke )
    	modes.options_tab = mw.text.split(modes.options_all, " ", true)
    	local opt_pretab, opt_tab, noopt_tab, opt_list = {}, {}, {}, " "
    	for i, option in pairs(modes.options_tab) do -- Build the subgroup table from the groupname string
    		local no_t, opt_t = string.sub( option, 1, 2), string.sub( option, 3)
    		if ( no_t == "no" )
    			then noopt_tab[option] = opt_t -- no_option to delete an active option
    			else opt_pretab[option] = option end -- active option
    	end
    	local lst = "" ; for key, val in pairs(modes.options_tab) do lst = lst .. viewers.ta(key, val ) end
    	t = t .. viewers.ta("\n* #modes.options_tab", lua_table.count_all( modes.options_tab ) ) .. viewers.ta("options_tab", lst )
    	local lst = "" ; for key, val in pairs(opt_pretab) do lst = lst .. viewers.ta(key, val ) end
    	t = t .. viewers.ta("\n* #opt_pretab", lua_table.count_all( opt_pretab ) ) .. viewers.ta("opt_pretab", lst )
    	local lst = "" ; for key, val in pairs(noopt_tab) do lst = lst .. viewers.ta(key, val ) end
    	t = t .. viewers.ta("\n* #noopt_tab", lua_table.count_all( noopt_tab ) ) .. viewers.ta("noopt_tab", lst )
    	opt_tab = mw.clone(opt_pretab) -- unknown arguments to detect are source arguments without known arguments.
    	for option, opt_t in pairs(noopt_tab) do -- Build the subgroup table from the groupname string
    		opt_tab[opt_t] = nil -- no_option delete an active option
    	end -- active options are in opt_tab
    	local lst = "" ; for key, val in pairs(opt_tab) do lst = lst .. viewers.ta(key, val ) end
    	t = t .. viewers.ta("\n* #opt_tab = " .. lua_table.count_all( opt_tab ) ) .. viewers.ta("opt_tab whitout no", lst )
    	-- Activate the sought options
    	local template_options = " "
    	for key, val in pairs(noopt_tab) do template_options = template_options .. " " .. val end
    	modes.template_options = template_options
    	t = t .. viewers.ta("modes.template_options", modes.template_options)
    	return t, modes.template_options
    end -- local t = modes.options_mixer(args_template)
    
    function modes.import_args_mode_options(args_template) -- Import and mix args mode and options from template and invoke -- S170703amo
    --	Guideline: Any combination of options can define a mixture of options to modify options.
    --	This function allows any module to modify this process.
    --	The default process gives the priority to options from arguments.
    --	Each option can be deleted by the nooption option. Then options begining by "no" are forbiden.
    --	local fenv = getfenv() -- Not activated in fr.wikisource.org by allowEnvFuncs in the engine configuration.
    	if (type(modes.options_for_modes) ~= "table") then modes.options_for_modes = {} end
    	if (type(modes.args_template) ~= "table") then modes.args_template = {} end
    	if (type(args_template) == "table") then args_template =  modes.args_template end
    	-- Import args mode options
    	local t = "t= * * * "
    	modes.frame = mw.getCurrentFrame() -- frame or modes.frame or
    	modes.args_template = modes.frame:getParent().args
    	args_template = modes.args_template
    	modes.mode_name = args_template.mode or args_template[1] or "read"
    	modes.args_mixed = modes.args_mixer(args_template)
    	modes.modes_mixer(args_template)
    	modes.options_mixer(args_template)
    	return modes.args_mixed
    end -- local t = modes.import_args_mode_options(args_template)
    
    -- For an unknown argument, seeking the name of the nearest argument among the known arguments
    function modes.similar_args_search(search, list)
    	local dist, lengths, tlev = 9, 0
    	local trouve1, trouve2, trouve3 = nil, nil, nil
    	local min1, min2, min3 = 99, 99, 99
    	if (type(search) ~= "string") then search = "" end
    	local diffmaxi = modes.similar_args_diffmaxi( string.len(search) )
    	local t = ", " .. tostring(diffmaxi) .. " / " .. tostring(length) .. " "
    	for key, arglingual in pairs(list) do
    		-- Search the most similar and same length. Buscar las más similares y la misma longitud. Chercher le plus ressemblant et la même longueur.
    		dist, tlev = modes.levenshtein(search, arglingual)
    		if (dist <= min1) then
    			trouve3 = trouve2
    			min3 = min2
    			trouve2 = trouve1
    			min2 = min1
    			min1 = dist
    			trouve1 = tostring(arglingual)
    		end
    	end
    	t = t .. "<br>" .. viewers.ta("cherche", cherche) .. viewers.ta("trouve1", trouve1) .. viewers.ta("min1", min1) .. viewers.ta("trouve2", trouve2) .. viewers.ta("min2", min2) .. " " .. t
    	if trouve1 and min1 == 0 then t = t .. viewers.styles_color_wikidata(viewers.ta("connu", trouve1)) end
    	if trouve1 and min1 <= diffmaxi then t = t .. viewers.styles_color_wikidata(viewers.ta("min1 "..min1.."<="..diffmaxi, trouve1)) end
    	if trouve2 and min2 <= diffmaxi then t = t .. viewers.styles_color_wikidata(viewers.ta("min2 "..min2.."<="..diffmaxi, trouve2)) end
    	if trouve3 and min3 <= diffmaxi then t = t .. viewers.styles_color_wikidata(viewers.ta("min3 "..min3.."<="..diffmaxi, trouve3)) end
    	return trouve1, min1, trouve2, min2, t
    end -- function modes.similar_args_search(search, list)
    
    function modes.import_arguments(args_known, args_source, content_translations, args_wikidata) -- Import all arguments from template, or invoke, or wikidata
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {		}
    	modes.args_known = args_known
    	local args_wikidata = args_wikidata or modes.args_wikidata or p.args_wikidata or {} -- optional value from p.args_known = { -- }
    	modes.args_wikidata = args_wikidata
    	local args_import = args_import or modes.args_import or {} -- optional value from p.args_known = {		}
    	modes.args_import = args_import
    	-- default parameters
    	if type(args_source) ~= "table" then args_source = modes.args_source end
    	content_translations = content_translations or langs.content_translations
    	-- Mix args_source in args_import, with priority for present args_source.
    	for key, argm in pairs(modes.args_template) do modes.args_import[key] = argm end
    	local err = nil
    	local cats = ""
    	modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S")
    	ARGS.add(viewers.ARGS, 1, "import_arguments", { ["argsknown"] = args_known, ["argssource"] = args_source, ["argswikidata"] = args_wikidata, ["nowyear"] = modes.nowyear, } ) -- ARGS.t
    	modes.import_arguments_err = ""
    	modes.import_arguments_track = ""
    	local err = modes.verify_args_tables(args_known, args_source)
    	if err then return args_import, err end
    	---------------------------------------
    	langs.main_i18n = versions.memo_i18n
    	local i18n = versions.memo_i18n or versions.main_i18n
    	local err, er1, t2 = "", "", ""
    	local key, argval, argid = "kkk", "xxx", ""
    	local argknw, arglingual, argreceived = nil, "", ""
    	local argm = {} -- used arguments
    	local key_N, key_NN = 0, 0
    	local arg_found, rec_found, already_found = false, false, false
    	-- initialize all arguments to "not found" before import them from p.args_known = { -- }
    	for key_known, argm in pairs(args_known) do
    		if type(argm) == "table" then argm.found = 0 end
    	end
    	modes.args_unknown = mw.clone(modes.args_source) -- unknown arguments to detect are source arguments without known arguments.
    	local key_known_init = nil
    	local argm_syn = nil
    	-- Get datas from mw.wikibase for the page and Mix datas in modes.args_import.
    	datas.prop, datas.props = datas.get_item(modes.args_unknown, QITEM) -- Get datas from mw.wikibase for the page.
    	-- Try to read all known arguments. Intentar leer todos los argumentos conocidos. Essayer de lire tous les arguments connus.
    	for key_known, argm in pairs(args_known) do
    		if type(argm) == "table" then
    			argm.src = nil
    			argm.trk = " n"
    			key_known_init = key_known
    			-- first initialise each known argument
    			modes.import_arguments_track = tostring(modes.import_arguments_track) .. " - " .. tostring(key_known)
    			argm_syn = args_known[argm.keyword]
    			ARGS.add(viewers.ARGS, 1, "args_known for", { key = key_known, Nargm = lua_table.level_count(argm), syn = argm.syn, } ) -- ARGS.t
    			if argm.syn == 2 then
    				-- Name an unnamed argument, positional, by its synonym. Nommer un argument non nommé, numéroté, par son synonyme.
    				-- Rename a named argument, by its synonym. Renommer un argument nommé, par son synonyme.
    	--			argm_orig = key_known -- DEBUG
    				key_known = argm.keyword
    				--	synonyms are defined with the stamp "syn = 2", then here stamp the basic argument with "syn = 1".
    				args_known[key_known].syn = 1
    				argm = args_known[key_known] -- new variable argm
    				argm.src = nil
    				argm.trk = "s"
    				modes.import_arguments_track = tostring(modes.import_arguments_track) .. ">" .. tostring(key_known)
    			end
    			-- initialise an argument.
    			arg_found = false
    			argval = nil
    			argm.trk = argm.trk.."="
    			-- Import a wikidata argument. Importer un argument wikidata
    			if type(datas.props) == "table" and datas.props[key_known] then
    				argm["val"] = datas.props[key_known]
    				argval = datas.props[key_known]
    				argm.src = "wd"
    				argm.trk = argm.trk.."w"
    				if argm_orig then
    				--	args_known[argm_orig].src = "wd"
    				--	args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."w"
    				end
    				arg_found = true
    				modes.import_arguments_track = modes.import_arguments_track .. "=<b>" .. tostring(argval) .. "</b> "
    			end
    			-- import a source argument. importer un argument source.
    			arglingual = content_translations[key_known]
    			modes.import_arguments_track = modes.import_arguments_track .. "/" .. tostring(arglingual)
    			if arglingual then -- The argument name has a translation in wiki language
    				if args_source[arglingual] and not modes.args_source[arglingual] then -- the argument come from template else from invoke else from wikidata
    		--		if argval then -- the argument value exist and come from template else from invoke else from wikidata
    					argval = args_source[arglingual]
    					argm.src = "args"
    					argm.trk = argm.trk.." a"
    					arg_found = true
    					local arg_values = content_translations[argm.arg_values]
    					if argm.keys_values and arg_values then
    						-- The argument is limited to multiple values with arg_values and keys_values, and the values are defined.
    						local pos = string.find(arg_values, argval)
    						if pos then
    							-- The value of the argument is in the multiple values of the arguments.
    					--		argm.src = "args"
    							argm.trk = argm.trk.."m"
    					--		arg_found = true
    							if argm_orig then
    							--	args_known[argm_orig].src = "args"
    							--	args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."d"
    							end
    						else
    							events.add_err("modes_args_values_err", argm.keyword, argval, arg_values)
    					--		argval = nil
    						end
    					else
    					--	argm.src = "args"
    						argm.trk = argm.trk.."c"
    					--	arg_found = true
    						if argm_orig then
    						--	args_known[argm_orig].src = "args"
    						--	args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."c"
    						end
    					end
    					modes.import_arguments_track = modes.import_arguments_track .. "=<b>" .. tostring(argval) .. "</b> "
    				end -- not args_source[arglingual] is normal
    			else -- internal error and category
    			--	events.add_err("versions_module_miss_i18n_trad_err", key_known)
    			--	Generate a category to list all modules with missing translation
    				cats = cats .. events.add_cat( "versions_err_module_miss_i18n_cat" )
    			end
    			key_N = tonumber(key_known_init)
    			if key_N and not args_known[key_N] then
    				events.add_err("modes_too_unnamed_arguments_err", key_N, argval)
    				events.add_cat("versions_with_usage_error_cat")
    			end
    			-- Record the argument. Guarde el argumento. Enregistrer l'argument.
    			if arg_found == true then
    				argm.found = argm.found + 1 -- count redifined arguments
    				argm.val = argval
    				args_import[key_known] = argval -- received international arguments table
    				if modes.args_unknown[arglingual] then
    					modes.args_unknown[arglingual] = nil -- unknown arguments are source arguments without known arguments.
    				end
    			end
    		end
    	end
    	-- modes.import_arguments: after import itself, some surrounding checks.
    	for key_known, argm in pairs(args_known) do -- For all known arguments
    	--	Redefined arguments. Argumentos redefinieron. Arguments redéfinis.
    	--	synonyms are defined with the stamp "syn = 2", then here stamp the basic argument with "syn = 1".
    		if argm.keyword and args_known[argm.keyword] and args_known[argm.keyword].syn then -- if the argument is a synonym, increase the found level
    			if argm.found and (argm.found > 2) then
    				events.add_err("modes_value_re_defined_err", (argm["keyword"] or "**") ) --.. ">2")
    				cats = cats .. events.add_cat("versions_with_usage_error_cat")
    			end
    		else
    			if argm.found and (argm.found > 1) then
    				events.add_err("modes_value_re_defined_err", (argm["keyword"] or "**") ) --.. ">1")
    				cats = cats .. events.add_cat("versions_with_usage_error_cat")
    			end
    		end
    		-- need = 0 not necessary argument
    		-- need = 1 necessary from argument
    		-- need = 2 necessary from argument or module interaction
    		-- Missing Arguments. Argumentos que faltan. Arguments manquants.
    		if argm.need and (argm.need == 1) and (not argm.val) then
    			arglingual = content_translations[key_known]
    			if arglingual then
    				events.add_err("modes_need_arg_value_err", arglingual)
    				cats = cats .. events.add_cat("versions_with_usage_error_cat")
    			end
    		end
    	end
    	-- All arguments sources have they been used?
    	--	modes.args_unknown -- unknown arguments are source arguments without known arguments.
    	local args_list = modes.similar_args_list(modes.args_known)
    	for key_src, val_src in pairs(modes.args_unknown) do -- For all unknown source arguments. function tableview.new(
    		arglingual = tostring(key_src) -- look for the translated argument
    		key_N = tonumber(arglingual)
    		-- No error for unmamed arguments
    		if not key_N then
    			events.add_err("modes_unknown_argument_err", arglingual, val_src)
    			cats = cats .. events.add_cat("versions_with_usage_error_cat")
    			-- "Error: parameter <b>%1</b> is unknown in this template. Check the name or flag this gap.",
    			-- Look for a known and similar name argument
    			local diffmaxi = modes.similar_args_diffmaxi( string.len(arglingual) )
    			local trouve1, min1, trouve2, min2 = modes.similar_args_search(arglingual, args_list)
    			if min1 and (min1 <= diffmaxi) then
    				events.add_err("modes_nearest_argument_err", trouve1)
    			end
    			if min2 and (min2 <= diffmaxi) then
    				events.add_err("modes_nearest_argument_err", trouve2)
    			end
    		end
    		key_N = tonumber(arglingual)
    		if key_N and not args_known[key_N] then
    			events.add_err("modes_too_unnamed_arguments_err", key_N, val_src)
    			events.add_cat("versions_with_usage_error_cat")
    		end
    	end -- For all unknown source arguments.
    	modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S")
    	modes.args_import.nowyear = modes.nowyear
    	modes.args_import = args_import
    	return modes.args_import
    end -- modes.args_import = modes.import_arguments(args_known, args_source, content_translations, args_wikidata)
    
    function modes.args_unknown_report(t) -- Report unknown arguments.
    	local t = t or "\n* modes.args_unknown_report(t) Report main unknown arguments."
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = modes.args_unknown, -- Use default cases.
    		rowGroup = {},
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			return { case.i, case.where, case.save, }
    		end,
    		title_memo = "modes_args_unknown_report_title",
    		headers = "modes_args_unknown_report_headers",
    		headers = "i;where;save",
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	return t
    end -- t = t .. modes.args_unknown_report(t) -- Report unknown arguments.
    --	res = res .. drop_box.new(selector, "modes_args_unknown_report_title", modes.args_unknown_report)
    
    -- - - - ------------------ - - - - ---------------------------------
    -- Argts : Generate documentation. Generar documentación. Générer la documentation.
    -- - - - ------------------ - - - - ---------------------------------
    
    function modes.generDoc(opt, args_final, module_name)
    	-- List of paramètres for the module documentation
    	-- Lister des paramètres pour la documentation du module
    	-- "docview" or ":" ajouter le panneau de documentation
    	-- "docmin" quelques paramètres de base
    	-- "docdef" seulement les paramètres définis, ayant une valeur non nulle
    	-- "docmax" tous les paramètres connus
    	-- "docnotice" generer les documentations des notices
    	-- "docline" mettre tous les paramètres sur une seule ligne
    	-- "docsrc" mettre les paramètres en couleurs selon les sources
    	-- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc: " -- for documentation
    	-- modes.options = " erron noerr nobox1 nocatview " -- without normal result
    	-- modes.options = " debug tests en es fr " -- for debug or enforce language
    	-- Option nocatview means "Do not categorize and do not show categories."
    	local args_known = modes.args_known
    	local err = modes.verify_args_tables(args_known, modes.args_source)
    	if err then return err end
    	if type(module_name) ~= "string" then module_name = modes.module_name end
    	if type(module_name) ~= "string" then module_name = modes.frame:getTitle() end -- main module, example "Auteur"
    	if type(module_name) ~= "string" then module_name = "Central" end
    	local n, t, val = 0, "", ""
    	if type(args_final) ~= "table" then t = t.."err_args_final="..type(args_final).."<br>" end -- optional arguments
    	if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments
    	local key, argknw, argval, arglingual = "", "", ""
    	local lst = true
    	local lst_doc, lst_1, lst_t = {}, {}, ""
    	for key, parm in pairs(args_final) do -- for all known arguments
    		val = ""
    		n = tonumber(key)
    		if n then key = tostring(parm["keyword"]) end -- key for unnamed arguments, in numeric sort
    		argknw = args_known[key]
    		arglingual = viewers.form9user(arglingual) -- multilingual name of the argmt in the template
    		if arglingual == "nil" then arglingual = key end -- if argument is translatable
    		val = parm -- tostring(args_import[key])
    		if not viewers.is_def(val) then val = "" end
    		lst = false
    		opt = opt .. " docdef " -- optional display
    		if modes.option("docmin", opt) and argknw and (argknw["need"] > 0) then lst = true end
    		if modes.option("docdef", opt) and (val ~= "") then lst = true end
    		if modes.option("docmax", opt) then lst = true end
    		if not args_known[key] then lst = false end
    		if key and args_known[key] and args_known[key].typ == "sys" then lst = false end
    		if lst then t = t .. viewers.tam( viewers.form9user(key), parm) end -- list if found and selected
    	end
    	t = "\n* " .. module_name .. " " .. t -- .. "}}" -- <br>
    	return t
    end -- function modes.generDoc(opt, args_final, module_name)
    
    function modes.sources_of_datas_colors()
    	local res = ""
    	if modes.docolor then --	Document the data sources by colors
    		local datas_sources_of_datas = viewers.form9user("datas_sources_of_datas")
    		--	datas_sources_of_datas = "Informations from: /Wikidata, /template or module, /other, /warning, /error",
    		local splitxt = mw.text.split(datas_sources_of_datas, "/", true)
    		res = res .. splitxt[1]	 .. " <b> " .. viewers.styles_color_wikidata(splitxt[2]) .. viewers.styles_color_colargs(splitxt[3]) .. viewers.styles_color_normal(splitxt[4]) .. viewers.styles_color_warning(splitxt[5]) .. viewers.styles_color_error(splitxt[6]) .. ".</b> <br>"
    	end
    	return res
    end -- function modes.sources_of_datas_colors()
    
    function modes.module_init(frame) -- Get modes.args_source with modes.args_source
    	local frame = frame or modes.frame or mw.getCurrentFrame()
    	modes.frame = frame
    	modes.nowyear = tonumber(os.date("%Y") ) -- UTC now_date = os.date("%Y-%m-%dT%H:%M:%S")
    --	Mix arguments from {{#invoke:}}, then arguments from the prioritary template which replace ones from {{#invoke:}}.
    	local v2, nn, ni = 0, 0, 0
    	local args_tab, mode = {}
    	local templat = frame:getParent().args -- arguments from template
    	 -- Mix invoked modified arguments from prioritary template arguments.
    	 -- Argument 1 from template become the mode in #invoke. Other i arguments must be shifted.
    	local invoked = frame.args -- arguments from #invoke module
    	local args_tab = mw.clone(invoked) -- less priority than template
    	for key, val in pairs(args_tab) do -- invoked arguments can modify #invoke arguments.
    		local key = mw.text.trim(key)
    		local val = mw.text.trim(val)
    		local i = tonumber(key)
    		if i then
    			if i == 1 then
    				mode = val -- mode = template[1]
    				args_tab.mode = val
    			else args_tab[i-1] = val end -- transmit other unnamed arguments template[i], but shifted because the mode is in template[1]
    		else args_tab[key] = val end -- transmit any named template arguments template. Even the mode, which replace template[1], behind.
    	end
    	local args_tab = mw.clone(templat) -- template have the priority and can itself #invoke arguments
    	for key, val in pairs(templat) do -- template arguments can modify #invoke arguments.
    		local key = mw.text.trim(key)
    		local val = mw.text.trim(val)
    		local i = tonumber(key)
    		if i then
    			if i == 1 then
    				mode = val -- mode = template[1]
    				args_tab.mode = val
    			else args_tab[i-1] = val end -- transmit other unnamed arguments template[i], but shifted because the mode is in template[1]
    		else args_tab[key] = val end -- transmit any named template arguments template. Even the mode, which replace template[1], behind.
    	end
    	modes.args_source = args_tab -- args from: modes.module_init() -- Get modes.args_source with modes.args_source
    --	modes.args_source = modes.argsConfigIinit(modes.args_source) -- Extract and put apart args_source from args_source
    	-- Default values of main module version.
    	if versions.main_versions then
    		versions.main_versions.versionName = versions.main_versions.versionName or "Central0"
    		versions.main_versions.versionNumber = versions.main_versions.versionNumber or "0.0.0"
    		versions.main_versions.versionDate = versions.main_versions.versionDate or "2018-06-15"
    	end
    	return modes.args_source
    end -- modes.args_source = function modes.module_init(frame)
    
    function modes.init_options_for_modes(frame, options_for_modes, mode_name)
    	local res = "\n* modes.init_options_for_modes()"
    	frame = frame or mw.getCurrentFrame()
    	modes.frame = frame
    	modes.options_for_modes = options_for_modes or modes.options_for_modes
    	modes.mode_name = mode_name or modes.mode_name or "read"
    	modes.mode_options = modes.options_from_mode(modes.mode_name, modes.options_for_modes)
    	return res
    end -- function modes.init_options_for_modes(frame, options_for_modes, mode_name)
    
    function modes.get_arg_mode(mode_name, source_key, lang, args_source) -- Select the actual mode from some sources
    	local mode_key = "mode"
    	local args_source = args_source or modes.args_source
    	if type(args_source) == "table" -- and type(args_source[source_key]) == "string"
    	then mode_name = mode_name or args_source[source_key] or "read"
    	else modes.mode_name = mode_name or modes.mode_name or "read" end
    	return mode_name, source_key, lang, args_source
    end -- function modes.get_arg_mode(mode_name, source_key, lang, args_source)
    
    function modes.all_categories_list(t) -- List all eventual categories of this wiki
    	local memo = viewers.save_configs("modes.all_categories_list") -- Save global configuration before eventual changes.
    	local t = "\n* " .. (t or viewers.form9user("modes_all_categories_list_title") )
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	if (type(langs.user_lang) == "string") and type(versions.memo_i18n[langs.user_lang]) == "table" then
    		for key, txt in pairs(versions.memo_i18n[langs.user_lang]) do
    			if viewers.is_in("cat_", key) or viewers.is_in("_cat", key) then
    				txt = viewers.form9user(key, "**", "**", "**", "**", "**", "**")
    				t = t .. "<br>" .. viewers.ta(key, txt)
    			end
    		end
    	end
    	viewers.restore_configs(memo, "modes.all_categories_list") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.all_categories_list(t)
    
    function modes.all_errors_list(t) -- List detectable errors of this module
    	local t = "\n* " .. (t or viewers.form9user("modes_all_errors_list_title") )
    	if (type(langs.user_lang) == "string") and type(versions.memo_i18n[langs.user_lang]) == "table" then
    		for key, txt in pairs(versions.memo_i18n[langs.user_lang] or modes.modes_args.userlang) do
    			if viewers.is_in("err_", key) or viewers.is_in("_err", key) then
    				txt = viewers.form9user(key, "**", "**", "**", "**", "**", "**")
    				t = t .. "<br>" .. viewers.ta(key, txt)
    			end
    		end
    	end
    	return t
    end -- function modes.all_errors_list(t)
    
    function modes.list_all_args_main(t, args_known) -- List of all accepted arguments
    	local memo = viewers.save_configs("modes.list_all_args_main") -- Save global configuration before eventual changes.
    	local t = "\n* " .. (t or viewers.form9user("modes_list_all_args_main_title") )
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	if type(args_known) ~= "table" then return (t .. "The known arguments table modes.args_known misses.") end
    	t = t .. viewers.ta("args N", lua_table.level_count(args_known) )
    	local descr, description = "", ""
    	args = mw.clone(args_known)
    	local arglst = {}
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	for key, elem in pairs(args) do
    		elem.key = tostring(key)
    		descr = key .. "_descr" -- key for description of an argument
    		if type(langs.user_translations) == "table" then
    			elem.description = langs.user_translations[descr] or "**missing translation**"
    			elem.user_lang_key = langs.user_translations[elem.key] or "**missing key**"
    			elem.user_lang_keyword = langs.user_translations[elem.keyword] or "**missing keyword**"
    		--	elem.base_id = elem.base_id
    		--	elem.base_base = elem.base_base
    		--	elem.not_type = elem.not_type
    		end
    		if type(langs.user_translations) ~= "nil" then
    			table.insert(arglst, elem)
    		end
    	end -- insert in the arguments their own key
    	table.sort(arglst, function (a, b) return tostring(a.user_lang_key) < tostring(b.user_lang_key) end ) -- alphabetic sort of translated arguments
    	local gr_sys, gr_config, gr_need, gr_other, gr_authority = {}, {}, {}, {}, {}
    	for i, elem in ipairs(arglst) do -- group arguments in some groups
    		if elem.need == 1 or elem.need == 2 then table.insert(gr_need, elem)
    		elseif elem.typ == "sys" then table.insert(gr_sys, elem)
    		elseif elem.typ == "config" then table.insert(gr_config, elem)
    		elseif elem.base_base then table.insert(gr_authority, elem)
    		else table.insert(gr_other, elem) end
    	end
    	local needed = viewers.styles_small_caps(viewers.form9user("modes_needed_to_verify"))
    	local function list_group( group, needed )
    		needed = needed or ""
    		local t = ""
    		for key, elem in pairs(group or {}) do
    			if elem.syn
    			then t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> => <b>" .. elem.user_lang_key .. "</b> : " .. needed .. " " .. tostring(elem.description) -- .. elem.lev_arg_txt
    			else t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> : " .. needed .. " " .. tostring(elem.description) end
    		end
    		return t
    	end
    	t = t .. "<br><br>* <b>" .. viewers.form9user("modes_list_needed_args") .. "</b> " .. list_group( gr_need, needed )
    	t = t .. "<br><br>* <b>" .. viewers.form9user("modes_list_all_other_args") .. "</b> " .. list_group( gr_other )
    	t = t .. "<br><br>* <b>" .. viewers.form9user("list_all_authorities") .. "</b> " .. list_group( gr_authority )
    	t = t .. "<br><br>* <b>" .. viewers.form9user("modes_list_all_config_arguments") .. "</b> " .. list_group( gr_config )
    	t = t .. "<br><br>* <b>" .. viewers.form9user("modes_list_all_system_arguments") .. "</b> " .. list_group( gr_sys )
    	viewers.restore_configs(memo, "modes.list_all_args_main") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.list_all_args_main(t, args_known) -- modes_list_all_args_main_title for main
    
    function modes.recursive_normal( recursiveLevel_in, recursive_limit_in, modes_recursiveLevel_err ) -- Normalize recursiveLevel and recursive_limit
    --	recursiveLevel, recursive_limit, recursiveLevel_err == modes.recursive_normal(recursiveLevel, recursive_limit) -- typical use
    	-- default modes.recursive_limit
    	local recursiveLevel, recursive_limit = recursiveLevel_in, recursive_limit_in
    	local recursiveLevel_err = recursiveLevel_err or""
    	if type(modes_recursiveLevel_err) ~= "string" then modes_recursiveLevel_err = "modes_recursiveLevel_err" end
    	if type(modes.recursive_limit) ~= "number" then modes.recursive_limit = 11111 end
    	if modes.recursive_limit < 1 then modes.recursive_limit = 11111 end
    	if type(recursive_limit) ~= "number" then recursive_limit = modes.recursive_limit end
    	-- If recursive_limit is defined, it can be greater or lesser than modes.recursive_limit
    	recursive_limit = math.floor(recursive_limit) + 1
    	if recursive_limit < 1 then recursive_limit = modes.recursive_limit end
    	-- default recursiveLevel
    	if type(recursiveLevel) ~= "number" then recursiveLevel = 1 end
    	recursiveLevel = math.floor( recursiveLevel ) + 1
    	if recursiveLevel < 1 then recursiveLevel = 1 end
    	--
    	if recursiveLevel > recursive_limit then
    		recursiveLevel_err = viewers.form9user( modes_recursiveLevel_err, recursiveLevel, recursive_limit)
    		recursiveLevel_err = viewers.styles_color_error( tostring(recursiveLevel_err) )
    	end
    	return recursiveLevel, recursive_limit, recursiveLevel_err
    end -- function modes.recursive_normal( recursiveLevel_in, recursive_limit_in, modes_recursiveLevel_err )
    
    function modes.recursive_normal_tests( t ) -- Test Normalize recursiveLevel and recursive_limit
    	local memo = viewers.save_configs("modes.recursive_normal_tests") -- Save global configuration before eventual changes.
    --	recursiveLevel, recursive_limit, recursiveLevel_err == modes.recursive_normal(recursiveLevel, recursive_limit) -- typical use tab_view
    	local t = t or "\n* modes.recursive_normal_tests: "
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ recursiveLevel_in = nil, recursive_limit_in = nil, },
    			{ recursiveLevel_in = -12, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 1, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 1, recursive_limit_in = 0, },
    			{ recursiveLevel_in = 2.718, recursive_limit_in = 3.1416, },
    			{ recursiveLevel_in = 3, recursive_limit_in = nil, },
    			{ recursiveLevel_in = 5, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 6, recursive_limit_in = 5, },
    			{ recursiveLevel_in = 11111, recursive_limit_in = 5, "versions_module_miss_i18n_count_err" },
    		},
    		title_memo = "modes.recursive_normal() Test: Normalize the recursive level and the recursive limit",
    		headers = "Level_in; Limit_in; recursiveLevel; recursive_limit; recursiveLevel_err", -- Test Normalize recursiveLevel and recursive_limit
    		headers_class = "wikitable alternative center sortable",
    		form_one_case = function(case) -- Convert a case from test_group to rowGroup.
    			case.recursiveLevel, case.recursive_limit, case.recursiveLevel_err =
    			modes.recursive_normal( case.recursiveLevel_in or modes.recursive_limit or 1, case.recursive_limit_in or modes.recursive_limit or 3 )
    			return { case.recursiveLevel_in, case.recursive_limit_in, case.recursiveLevel, case.recursive_limit, case.modes_recursiveLevel_err }
    	--	headers = "Level_in; Limit_in; recursiveLevel; recursive_limit; recursiveLevel_err", -- viewers_tableView_default_headers
    		end,
    		rowGroup = {},
    	--	track_on == "details",
    	}
    	t = t .. "<br/> after convert in form_one_case = function(case)"
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Form a table view with lines and columns.
    	viewers.restore_configs(memo, "modes.recursive_normal_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function modes.recursive_normal_tests(recursiveLevel, recursive_limit)
    
    function modes.namespaces_page_list(t) -- List namespaces for the actual page.
    	if type(t) ~= "string" then t = nil end
    	local t = t or "\n* <b>spaces_page_names_test</b> :"
    	local mwtitle = mw.title.getCurrentTitle()
    	t = t .. viewers.ta("mwtitle", mwtitle)
    	local nsText = mwtitle.nsText
    	t = t .. viewers.ta("nsText", nsText)
    	local baseText = mwtitle.baseText -- namespace for the page
    	t = t .. viewers.ta("baseText", baseText)
    	local url = tostring(mwtitle:canonicalUrl( ))
    	t = t .. viewers.ta("url", url)
    	t = t .. "\n* Module namespace: "
    	local ns = mw.site.namespaces
    	if ns and ns[828] then
    		t = t .. viewers.ta("id828", ns[828].id)
    		t = t .. viewers.ta("canonicalName828", ns[828].canonicalName)
    		t = t .. viewers.ta("name828", ns[828].name)
    		t = t .. viewers.ta("displayName828", ns[828].displayName)
    	end
    	t = t .. "\n* All namespaces (from 0 to 2000): "
    	local ns = ""
    	for ins = 0, 2000 do
    		if mw.site.namespaces[ins] then
    			ns = mw.site.namespaces[ins].canonicalName
    			t = t .. viewers.ta(ns, ins)
    		end
    	end
    	t = t .. "\n* mw.title.getCurrentTitle(): "
    	local getCurrentTitle = mw.title.getCurrentTitle()
    	for key, val in pairs(getCurrentTitle) do -- Synthesis and descriptions of all status
    		t = t .. viewers.ta( viewers.value(key),  viewers.value(val) )
    	end
    	return t
    end -- function modes.namespaces_page_list()
    
    function modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM)
    --	After versions.init(), initialize modes and their options, known arguments, translations, and default item.
    	local res = ""
    	modes.frame = frame
    	langs.Central_version = Central_version -- To adapt the version of Module:Centralizer in any translated text.
    	modes.args_known = args_known or modes.args_known
    	modes.module_init(frame) -- Get modes.args_source with modes.args_source
    	modes.mode_name = mode_name or modes.mode_name or "read"
    	modes.init_options_for_modes(frame, options_for_modes, mode_name) -- Needed to init categories and errors
    	local mode_name, source_key, try_lang = modes.get_arg_mode(mode_name, source_key, try_lang, args_source)
    	langs.init_content_page_user_lang(modes.args_source.contentlang, modes.args_source.pagelang, modes.args_source.userlang, "modes.init")
    	local recursiveLevel, recursive_limit, recursiveLevel_err = modes.recursive_normal(recursiveLevel, modes.recursive_limit)
    	return res
    end -- function modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM)
    
    --	p_template_drop_box_name		= 'Cuadro desplegable', -- Equivalent templates exist in other wikis
    --	p_template_drop_box_name		= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    --	p_template_drop_box_name		= 'Drop-down box', -- Template: Drop-down box for drop_box.form
    --	p_template_drop_box_name		= 'Cuadro desplegable', -- Modelo: cuadro desplegable  :Boîte déroulante for drop_box.form
    
    --	cut_libraries
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	The Library:versions installs other libraries, supports versions, then binds modules, libraries and i18n translations.
    --	This library supports modules to: function versions.
    --	* Collect and bind modules and sub-modules depending from their p.version{}
    --	* Collect and bind translations from modules or libraries itself, and their /I18N sub-modules
    --	* Formats parametrable strings_c
    --	* Add a language needs only to add its own i18n subtable, like i18n.en = {}
    --	* Manage alternate versions of sub-modules sought in main, like Module:Sub, Module:Sub.2.1, Module:SubPlus.
    --	A central module and its translations can inpedendently change. Its p.version{} identifications change also.
    --	For this goal a module contains at least one i18n tranlations table. Its /I18N sub-modules contains translations in several languages.
    --	Central Libraries, like modules, contain their own p.version{} identifications and i18n translations in Module:Library/library_name/I18N.
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    
    --	versions = {} --	The Library:versions installs other libraries, bind modules and libraries, bind i18n translations, manage versions.
    --	versions = {} --	The Library:versions must stay in _G global space, to not change in init phase.
    
    --	versions = {} -- already declared by Scribunto, see central_library.new() -- Record a library in package.loaded
    
    --	The Module:Centralizer/I18N translations for lua_table library update and complete Module:Centralizer translations.
    versions.i18n = {} -- Translations for versions library
    versions.i18n.br = {
    	-- Principaux textes, erreurs et catégories des outils
    	versions_module_with_error_err			= "Module avec erreur",
    	versions_with_internal_error			= "Module avec erreur interne",
    	versions_with_internal_error_cat		= "Module avec erreur interne",
    	versions_with_usage_error				= "Module avec erreur d'utilisation",
    	versions_with_usage_error_cat			= "Module avec erreur d'utilisation",
    	versions_err_module_miss_i18n_i_cat		= "Module manquant de traduction i18n",
    	versions_module_miss_i18n_mini_err		= "Erreur interne : La table i18n n'a que <b>%1</b> traductions.",
    	versions_running_times_title			= "versions.running_times() Temps d'exécution et références pour les Lua-codeurs.",
    	versions_luatables_counts				= "<b>%1</b> variables, <b>%3</b> sous-tables, <b>%2</b> fonctions",
    	versions_table_dont_exists				= "La table <b>%1</b> n'existe pas.",
    	versions_table_listlimit_levelmaxi		= "Limite de niveau recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Limite de longueur max_n = <b>%1</b> ",
    	versions_with_usage_error_cat			= "Module avec erreur d'utilisation",
    	versions_module_with_error_err			= "Module avec erreur",
    	versions_with_internal_error_cat		= "Module avec erreur interne",
    
    	-- Gestion des versions
    	versions_versions_no_select_altern_err	= "Erreur de versions : pas de sélection dans l'alternative <b>%1</b> du module <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Erreur de versions : <b>%1</b> sélections dans l'alternative <b>%2</b> du module <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Erreur de versions : le sélecteur <b>%1</b> n'est pas dans les alternatives <b>%2</b> du module <b>%3</b>.",
    	versions_versions_missing_module_err	= "Erreur de versions : module absent pour la version <b>%1</b> du module <b>%2</b>.",
    	versions_main_module_missing_err		= "Le module principal est introuvable.",
    	versions_select_unknown_module_err		= "Internal error: Le Module:<b>%1</b> manquant est remplacé par le module normal Module:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "Le module de traductions <b>%1</b> n'a pas de version de base.",
    	versions_no_versions_module_err			= "Le module <b>%1</b> n'est pas dans le système des versions.",
    	versions_all_versions_tests				= "Versions avertissements : <b>%1</b>, normaux : <b>%2</b>, liste : <b>%3</b>.",
    	versions_all_versions_check				= "Versions: manquantes: <b>%1</b>, inconnues: <b>%2</b>, normales: <b>%3</b>, en excès: <b>%4</b>, toutes selectionées : <b>%5</b>.",
    	versions_missing_versions_err			= "Le module <b>%1</b> manque dans le module principal <b>%2</b>.",
    	versions_replaced_versions_err			= "Le module <b>%1</b> remplace le sous-module absent dans le module principal <b>%2</b>.",
    	versions_unknownversions_err			= "Le module <b>%1</b> est inconnu dans le module principal <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Erreur interne : Le texte <b>%1</b> manque de traduction en langue <b>%2</b>, et/ou d'autres.",
    	versions_module_miss_i18n_count_err		= "Erreur interne : Il y a <b>%1</b> manques parmi <b>%2</b> traductions.",
    	versions_module_miss_i18n_none_err		= "OK, aucune traduction manquante.",
    	versions_module_miss_i18n_trad_err		= "Erreur interne : manque de traduction pour l'argument <b>i18n.%1.%2</b>.",
    
    	-- Titres des tests
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Objects dans l'espace global _G",
    	versions_central_changes_headers		= "clé; valeur; compte; niveau",
    	versions_support_desk_title				= "Informations de soutien: en version <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Rapport de gestion des versions",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Test de la gestion des versions des modules",
    	versions_verif_bind_modules_report		= "Liaison des modules et contrôle des versions",
    	versions_bind_modules_test_headers		= "Versions demandées; Versions utilisées; Versions connues; ACTUEL : Erreurs dans le module actif; SIMULATION : Erreurs dans le module actif",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Documentations, tâches et modifications",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Liste triée des modules et bibliothèques centraux.",
    	versions_sort_central_modules_headers	= "Titre; Version; Date; Traductions / Langues",
    	versions_sort_central_modules_counts	= "ceci: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Tests du support de versions.",
    	versions_versions_management_headers	= "sought; versions; process; comments",
    	versions_add_deprecated_err				= "Fonction obsolète <b>%1(...)</b>. Remplacez-la par <b>%2(...)</b> dans le module <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Test: Fonction obsolète. Remplacez-la dans le module.",
    } -- versions.i18n.br
    versions.i18n.de = {
    	-- Principaux textes, erreurs et catégories des outils
    	versions_module_with_error_err			= "Modul mit Fehler",
    	versions_with_internal_error			= "Modul mit internem Fehler",
    	versions_with_internal_error_cat		= "Modul mit internem Fehler",
    	versions_with_usage_error				= "Modul mit Bedienungsfehler",
    	versions_with_usage_error_cat			= "Modul mit Bedienungsfehler",
    	versions_err_module_miss_i18n_i_cat		= "Modul fehlende Übersetzung i18n",
    	versions_module_miss_i18n_mini_err		= "Erreur interne : La table i18n n'a que <b>%1</b> traductions.",
    	versions_running_times_title			= "versions.running_times() Temps d'exécution et références pour les Lua-codeurs.",
    	versions_luatables_counts				= "<b>%1</b> variables, <b>%3</b> sous-tables, <b>%2</b> fonctions",
    	versions_table_dont_exists				= "La table <b>%1</b> n'existe pas.",
    	versions_table_listlimit_levelmaxi		= "Limite de niveau recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Limite de longueur max_n = <b>%1</b> ",
    	versions_with_usage_error_cat			= "Module avec erreur d'utilisation",
    	versions_module_with_error_err			= "Module avec erreur",
    	versions_with_internal_error_cat		= "Module avec erreur interne",
    
    	-- Gestion des versions
    	versions_versions_no_select_altern_err	= "Erreur de versions : pas de sélection dans l'alternative <b>%1</b> du module <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Erreur de versions : <b>%1</b> sélections dans l'alternative <b>%2</b> du module <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Erreur de versions : le sélecteur <b>%1</b> n'est pas dans les alternatives <b>%2</b> du module <b>%3</b>.",
    	versions_versions_missing_module_err	= "Erreur de versions : module absent pour la version <b>%1</b> du module <b>%2</b>.",
    	versions_main_module_missing_err		= "Le module principal est introuvable.",
    	versions_select_unknown_module_err		= "Internal error: Le Module:<b>%1</b> manquant est remplacé par le module normal Module:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "Le module de traductions <b>%1</b> n'a pas de version de base.",
    	versions_no_versions_module_err			= "Le module <b>%1</b> n'est pas dans le système des versions.",
    	versions_all_versions_tests				= "Versions avertissements : <b>%1</b>, normaux : <b>%2</b>, liste : <b>%3</b>.",
    	versions_all_versions_check				= "Versions: manquantes: <b>%1</b>, inconnues: <b>%2</b>, normales: <b>%3</b>, en excès: <b>%4</b>, toutes selectionées : <b>%5</b>.",
    	versions_missing_versions_err			= "Le module <b>%1</b> manque dans le module principal <b>%2</b>.",
    	versions_replaced_versions_err			= "Le module <b>%1</b> remplace le sous-module absent dans le module principal <b>%2</b>.",
    	versions_unknownversions_err			= "Le module <b>%1</b> est inconnu dans le module principal <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Erreur interne : Le texte <b>%1</b> manque de traduction en langue <b>%2</b>, et/ou d'autres.",
    	versions_module_miss_i18n_count_err		= "Erreur interne : Il y a <b>%1</b> manques parmi <b>%2</b> traductions.",
    	versions_module_miss_i18n_none_err		= "OK, aucune traduction manquante.",
    	versions_module_miss_i18n_trad_err		= "Erreur interne : manque de traduction pour l'argument <b>i18n.%1.%2</b>.",
    
    	-- Titres des tests
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Objects dans l'espace global _G",
    	versions_central_changes_headers		= "clé; valeur; compte; niveau",
    	versions_support_desk_title				= "Informations de soutien: en version <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Rapport de gestion des versions",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Test de la gestion des versions des modules",
    	versions_verif_bind_modules_report		= "Liaison des modules et contrôle des versions",
    	versions_bind_modules_test_headers		= "Versions demandées; Versions utilisées; Versions connues; ACTUEL : Erreurs dans le module actif; SIMULATION : Erreurs dans le module actif",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Documentations, tâches et modifications",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Liste triée des modules et bibliothèques centraux.",
    	versions_sort_central_modules_headers	= "Titre; Version; Date; Traductions / Langues",
    	versions_sort_central_modules_counts	= "ceci: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Tests du support de versions.",
    	versions_versions_management_headers	= "sought; versions; process; comments",
    	versions_add_deprecated_err				= "Fonction obsolète <b>%1(...)</b>. Remplacez-la par <b>%2(...)</b> dans le module <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Test: Fonction obsolète. Remplacez-la dans le module.",
    } -- versions.i18n.de
    versions.i18n.en = {
    	-- Main string, errors and categories of tools
    	versions_module_with_error_err			= "Module with error",
    	versions_with_internal_error			= "Module with internal error",
    	versions_with_internal_error_cat		= "Module with internal error",
    	versions_with_usage_error				= "Module with usage error",
    	versions_with_usage_error_cat			= "Module with usage error",
    	versions_running_times_title			= "versions.running_times() Running times and references for Lua-coders.",
    	versions_luatables_counts				= "<b>%1</b> variables, <b>%3</b> sub-tables, <b>%2</b> functions",
    	versions_table_dont_exists				= "The table <b>%1</b> does not exist.",
    	versions_table_listlimit_levelmaxi		= "Level limit recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Length limit max_n = <b>%1</b> ",
    	-- Versions management
    	versions_versions_no_select_altern_err	= "Versions error: no selection in the alternative <b>%1</b> of the module <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Versions error: <b>%1</b> selections in the alternative <b>%2</b> of the module <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Versions error: <b>%1</b> selector is not in alternative <b>%2</b> of the module <b>%3</b>.",
    	versions_versions_missing_module_err	= "Versions error: missing module for the version <b>%1</b> of the module <b>%2</b>.",
    	versions_main_module_missing_err		= "The main module is not found.",
    	versions_select_unknown_module_err		= "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "The <b>%1</b> translations module has no basic version.",
    	versions_no_versions_module_err			= "The module <b>%1</b> is not in the system of versions.",
    	versions_all_versions_tests				= "Versions warning: <b>%1</b>, normal: <b>%2</b>, listall: <b>%3</b>.",
    	versions_all_versions_check				= "Versions: missings: <b>%1</b>, unknowns: <b>%2</b>, normals: <b>%3</b>, excess: <b>%4</b>, all selected: <b>%5</b>.",
    	versions_missing_versions_err			= "The module <b>%1</b> misses in the main module <b>%2</b>.",
    	versions_replaced_versions_err			= "The module <b>%1</b> replaces the missing sub-module in the main module <b>%2</b>.",
    	versions_unknownversions_err			= "The module <b>%1</b> is unknown in the main module <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Internal Error: The text <b>%1</b> lack of translation in <b>%2</b> language, and/or others.",
    	versions_module_miss_i18n_count_err		= "Internal Error: There are <b>%1</b> missings in <b>%2</b> translations.",
    	versions_module_miss_i18n_none_err		= "OK, none missing translations.",
    	versions_module_miss_i18n_trad_err		= "Internal Error: Module missing i18n translation for the argument <b>i18n.%1.%2</b>.",
    	versions_err_module_miss_i18n_cat		= "Module missing i18n translation",
    	versions_err_module_miss_i18n_cat		= "Module with internal error",
    	versions_module_miss_i18n_mini_err		= "Error: I18n table has only <b>1%</b> translations.",
    
    	-- Titles of tests
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Objects in _G global space",
    	versions_central_changes_headers		= "key; val; count; level",
    	versions_support_desk_title				= "Support information: in version <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Versions management report",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Test for management of modules versions",
    	versions_verif_bind_modules_report		= "Binding of modules and versions control",
    	versions_bind_modules_test_headers		= "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Documentations, tasks and changes",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Sorted list of central modules and libraries.",
    	versions_sort_central_modules_headers	= "Title; Version; Date; Translations / Languages",
    	versions_sort_central_modules_counts	= "this: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Tests of versions management.",
    	versions_versions_management_headers	= "sought; versions; process; comments",
    	versions_add_deprecated_err				= "Deprecated function <b>%1(...)</b>. Replace it by <b>%2(...)</b> in the module <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Test: Deprecated function. Replace it in the module.",
    } -- versions.i18n.en
    versions.i18n.es = {
    	-- Textos principales, errores y categorías de instrumentos
    	versions_module_with_error_err			= "Módulo con error",
    	versions_with_internal_error			= "Módulo con error interno",
    	versions_with_internal_error_cat		= "Módulo con error interno",
    	versions_with_usage_error				= "Módulo con error del uso",
    	versions_with_usage_error_cat			= "Módulo con error del uso",
    	versions_err_module_miss_i18n_i_cat		= "Módulo traducción i18n que falta",
    	versions_running_times_title			= "versions.running_times() Tiempos de ejecución y referencias para los codificadores Lua.",
    	versions_luatables_counts				= "<b>%1</b> variables, <b>%3</b> subtablas, <b>%2</b> funciones",
    	versions_table_dont_exists				= "La tabla <b>%1</b> no existe.",
    	versions_table_listlimit_levelmaxi		= "Límite de nivel recursive_limit = <b>%1</b>",
    	versions_table_listlimit_max_n			= "Límite de longitud max_n = <b>%1</b>",
    	versions_with_usage_error_cat			= "Módulo con error del uso",
    	versions_module_with_error_err			= "Módulo con error",
    	versions_with_internal_error_cat		= "Módulo con interno error",
    
    	-- Gestión de versiones
    	versions_versions_no_select_altern_err	= "Error de versiones: no hay selección en alternativa <b>%1</b> del módulo <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Error de versiones: <b>%1</b>  selecciones en la alternativa <b>%2</b> del módulo <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Error de versiones: selector <b>%1</b> no es en alternativas <b>%2</b> del módulo <b>%3</b>.",
    	versions_versions_missing_module_err	= "Error de versiones: módulo ausente para la versión <b>%1</b> del módulo <b>%2</b>.",
    	versions_main_module_missing_err		= "El módulo principal no es encontrado.",
    	versions_select_unknown_module_err		= "Internal error: El Módulo:<b>%1</b> faltante se reemplaza por lo normal Module:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "El módulo de traducciones <b>%1</b> no tiene ninguna versión básica.",
    	versions_no_versions_module_err			= "El <b>%1</b> módulo no está en el sistema de versiones.",
    	versions_all_versions_tests				= "Versiones aviso: <b>%1</b>, normal: <b>%2</b>, lista: <b>%3</b>.",
    	versions_all_versions_check				= "Versiones: falta: <b>%1</b>, incógnitas: <b>%2</b>, normales: <b>%3</b>, en exceso: <b>%4</b>, selecciona todo: <b>%5</b>.",
    	versions_missing_versions_err			= "El módulo <b>%1</b> no disponible en el módulo principal <b>%2</b>.",
    	versions_replaced_versions_err			= "El módulo <b>%1</b> reemplaza el sub-módulo ausente en el módulo principal <b>%2</b>.",
    	versions_unknownversions_err			= "El módulo <b>%1</b> es desconocido en el módulo principal <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Error Interno: El texto <b>%1</b> falta de traducción en <b>%2</b> lengua, y / o otras.",
    	versions_module_miss_i18n_count_err		= "Error interno: Hay <b>%1</b> que falta en <b>%2</b> traducciones.",
    	versions_module_miss_i18n_none_err		= "OK, ninguno traducciones que faltan.",
    	versions_module_miss_i18n_trad_err		= "Error interno: translation faltan en Módulo i18n para el argumento <b>i18n.%1.%2</b>.",
    	versions_module_miss_i18n_mini_err		= "Error: la tabla i18n tiene solamente <b>1%</b> traducciones.",
    
    	-- Titres des pruebas
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Objects en el espacio global _G",
    	versions_central_changes_headers		= "llave; valor; contar; nivel",
    	versions_support_desk_title				= "Información de soporte: en versión <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Informe de gestión de versiones",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Test for management of modules versions",
    	versions_verif_bind_modules_report		= "Binding of modules and versions control",
    	versions_bind_modules_test_headers		= "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Documentación, parches y modificaciones",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Lista ordenada de módulos y bibliotecas centrales.",
    	versions_sort_central_modules_headers	= "Título; Versión; Fecha; Traducciones / Idiomas",
    	versions_sort_central_modules_counts	= "esta + <b>%2</b>/<b>%3</b> T/I, ",
    	versions_versions_management_title		= "versions.versions_support_test() Pruebas de gestión de versiones.",
    	versions_versions_management_headers	= "sought; versions; process; comments",
    	versions_add_deprecated_err				= "Función obsoleta <b>%1(...)</b>. Sustitúyala por <b>%2(...)</b> en el módulo <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Prueba: Función obsoleta. Sustitúyala en el módulo.",
    } -- versions.i18n.es
    versions.i18n.fr = {
    	-- Principaux textes, erreurs et catégories des outils
    	versions_module_with_error_err			= "Module avec erreur",
    	versions_with_internal_error			= "Module avec erreur interne",
    	versions_with_internal_error_cat		= "Module avec erreur interne",
    	versions_with_usage_error				= "Module avec erreur d'utilisation",
    	versions_with_usage_error_cat			= "Module avec erreur d'utilisation",
    	versions_err_module_miss_i18n_i_cat		= "Module manquant de traduction i18n",
    	versions_module_miss_i18n_mini_err		= "Erreur interne : La table i18n n'a que <b>%1</b> traductions.",
    	versions_running_times_title			= "versions.running_times() Temps d'exécution et références pour les Lua-codeurs.",
    	versions_luatables_counts				= "<b>%1</b> variables, <b>%3</b> sous-tables, <b>%2</b> fonctions",
    	versions_table_dont_exists				= "La table <b>%1</b> n'existe pas.",
    	versions_table_listlimit_levelmaxi		= "Limite de niveau recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Limite de longueur max_n = <b>%1</b> ",
    	versions_with_usage_error_cat			= "Module avec erreur d'utilisation",
    	versions_module_with_error_err			= "Module avec erreur",
    	versions_with_internal_error_cat		= "Module avec erreur interne",
    
    	-- Gestion des versions
    	versions_versions_no_select_altern_err	= "Erreur de versions : pas de sélection dans l'alternative <b>%1</b> du module <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Erreur de versions : <b>%1</b> sélections dans l'alternative <b>%2</b> du module <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Erreur de versions : le sélecteur <b>%1</b> n'est pas dans les alternatives <b>%2</b> du module <b>%3</b>.",
    	versions_versions_missing_module_err	= "Erreur de versions : module absent pour la version <b>%1</b> du module <b>%2</b>.",
    	versions_main_module_missing_err		= "Le module principal est introuvable.",
    	versions_select_unknown_module_err		= "Internal error: Le Module:<b>%1</b> manquant est remplacé par le module normal Module:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "Le module de traductions <b>%1</b> n'a pas de version de base.",
    	versions_no_versions_module_err			= "Le module <b>%1</b> n'est pas dans le système des versions.",
    	versions_all_versions_tests				= "Versions avertissements : <b>%1</b>, normaux : <b>%2</b>, liste : <b>%3</b>.",
    	versions_all_versions_check				= "Versions: manquantes: <b>%1</b>, inconnues: <b>%2</b>, normales: <b>%3</b>, en excès: <b>%4</b>, toutes selectionées : <b>%5</b>.",
    	versions_missing_versions_err			= "Le module <b>%1</b> manque dans le module principal <b>%2</b>.",
    	versions_replaced_versions_err			= "Le module <b>%1</b> remplace le sous-module absent dans le module principal <b>%2</b>.",
    	versions_unknownversions_err			= "Le module <b>%1</b> est inconnu dans le module principal <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Erreur interne : Le texte <b>%1</b> manque de traduction en langue <b>%2</b>, et/ou d'autres.",
    	versions_module_miss_i18n_count_err		= "Erreur interne : Il y a <b>%1</b> manques parmi <b>%2</b> traductions.",
    	versions_module_miss_i18n_none_err		= "OK, aucune traduction manquante.",
    	versions_module_miss_i18n_trad_err		= "Erreur interne : manque de traduction pour l'argument <b>i18n.%1.%2</b>.",
    
    	-- Titres des tests
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Objects dans l'espace global _G",
    	versions_central_changes_headers		= "clé; valeur; compte; niveau",
    	versions_support_desk_title				= "Informations de soutien: en version <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Rapport de gestion des versions",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Test de la gestion des versions des modules",
    	versions_verif_bind_modules_report		= "Liaison des modules et contrôle des versions",
    	versions_bind_modules_test_headers		= "Versions demandées; Versions utilisées; Versions connues; ACTUEL : Erreurs dans le module actif; SIMULATION : Erreurs dans le module actif",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Documentations, tâches et modifications",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Liste triée des modules et bibliothèques centraux.",
    	versions_sort_central_modules_headers	= "Titre; Version; Date; Traductions / Langues",
    	versions_sort_central_modules_counts	= "ceci: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Tests du support de versions.",
    	versions_versions_management_headers	= "sought; versions; process; comments",
    	versions_add_deprecated_err				= "Fonction obsolète <b>%1(...)</b>. Remplacez-la par <b>%2(...)</b> dans le module <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Test: Fonction obsolète. Remplacez-la dans le module.",
    } -- versions.i18n.fr
    versions.i18n.hu = {
    	-- Fő szövegek, hibák és szerszámkategóriák
    	versions_module_with_error_err			= "A modul hibás",
    	versions_with_internal_error			= "Modul belső hibával",
    	versions_with_internal_error_cat		= "Modul belső hibával",
    	versions_with_usage_error				= "Modul hibás használat esetén",
    	versions_with_usage_error_cat			= "Modul hibás használat esetén",
    	versions_err_module_miss_i18n_i_cat		= "Az i18n hiányzó modul hiányzik",
    	versions_module_miss_i18n_mini_err		= "Belső hiba: Az i18n táblázat csak <b>%1</b> fordításokat tartalmaz.",
    	versions_running_times_title			= "versions.running_times() Végrehajtási idők és hivatkozások a Lua-kódolók számára.",
    	versions_luatables_counts				= "<b>%1</b> változók, <b>%2</b> allables, <b>%3</b> függvények",
    	versions_table_dont_exists				= "A <b>%1</b> táblázat nem létezik.",
    	versions_table_listlimit_levelmaxi		= "Szintkorlát recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Hossza határ max_n = <b>%1</b> ",
    	versions_with_usage_error_cat			= "Modul hibás használat esetén",
    	versions_module_with_error_err			= "A modul hibás",
    	versions_with_internal_error_cat		= "Modul belső hibával",
    
    	-- Gestion des versions
    	versions_versions_no_select_altern_err	= "Változatok hiba: nincs lehetőség a modul <b>%1</b> alternatívájára <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Változatok hiba: <b>%1</b> választása a modul <b>%2</b> alternatívájaként <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Változatok hiba: a <b>%1</b> választó nem szerepel az alternatívákban <b>%2</b> a modul <b>%3</b>.",
    	versions_versions_missing_module_err	= "Változatok hiba: hiányzó modul a verzióhoz <b>%1</b> a modul <b>%2</b>.",
    	versions_main_module_missing_err		= "A főmodul nem található.",
    	versions_select_unknown_module_err		= "Belső hiba: Modul: <b>%1</b> hiányzik a normál modul helyett. Modul:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "A fordítási modul <b>%1</b> nem rendelkezik alapváltozattal.",
    	versions_no_versions_module_err			= "A <b>%1</b> modul nincs a verziórendszerben.",
    	versions_all_versions_tests				= "Figyelmeztető verziók: <b>%1</b>, normál: <b>%2</b>, lista: <b>%3</b>.",
    	versions_all_versions_check				= "Változatok: hiányzik: <b>%1</b>, ismeretlen: <b>%2</b>, normál: <b>%3</b>, feleslegben: <b>%4</b>, minden kiválasztott: <b>%5</b>.",
    	versions_missing_versions_err			= "A modul <b>%1</b> manque dans le module principal <b>%2</b>.",
    	versions_replaced_versions_err			= "A modul <b>%1</b> helyettesíti a hiányzó al-modulot a főmodulban <b>%2</b>.",
    	versions_unknownversions_err			= "A modul <b>%1</b> a fő modulban ismeretlen <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Belső hiba: A <b>%1</b> szöveg hiányzik a <b>%2</b> fordításban és / vagy más nyelven.",
    	versions_module_miss_i18n_count_err		= "Belső hiba: <b>%1</b> hiányosságok vannak a <b>%2</b> fordítások között.",
    	versions_module_miss_i18n_none_err		= "OK, nincs hiányzó fordítás.",
    	versions_module_miss_i18n_trad_err		= "Belső hiba: az érvelés fordításának hiánya <b>i18n.%1.%2</b>.",
    
    	-- Titres des tests
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Tárgyak a globális térben _G",
    	versions_central_changes_headers		= "kulcs; érték; figyelembe; szint",
    	versions_support_desk_title				= "Támogatási információ: verzió <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Jelentés menedzsment az verziók",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Modul teszt a menedzsment az verziók",
    	versions_verif_bind_modules_report		= "Modulkötés és verziókezelés",
    	versions_bind_modules_test_headers		= "Kért változatok; Használt verziók; Ismert változatok; CURRENT: Hibák az aktív modulban; SZIMULÁCIÓ: Az aktív modul hibái",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Dokumentációk, feladatok és módosítások",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() A modulok és a központi könyvtárak rendezett listája.",
    	versions_sort_central_modules_headers	= "Cím; változata; dátum; Fordítások / Nyelvek",
    	versions_sort_central_modules_counts	= "ezt: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Teszt a menedzsment az verziók.",
    	versions_versions_management_headers	= "keresett; változatban; folyamat; Hozzászólások",
    	versions_add_deprecated_err				= "Elavult funkció <b>%1(...)</b>. Helyezze vissza <b>%2(...)</b> a modulba <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Teszt: elavult funkció. Helyezze vissza a modulba.",
    } -- versions.i18n.hu
    versions.i18n.vi = {
    	-- Các văn bản, lỗi và danh mục chính của công cụ
    	versions_module_with_error_err			= "Mô-đun có lỗi",
    	versions_with_internal_error			= "Mô-đun có lỗi nội bộ",
    	versions_with_internal_error_cat		= "Mô-đun có lỗi nội bộ",
    	versions_with_usage_error				= "Mô-đun có lỗi sử dụng",
    	versions_with_usage_error_cat			= "Mô-đun có lỗi sử dụng",
    	versions_err_module_miss_i18n_i_cat		= "Mô-đun thiếu bản dịch i18n",
    	versions_module_miss_i18n_mini_err		= "Lỗi nội bộ: Bảng i18n chỉ có <b>%1</b> dịch.",
    	versions_running_times_title			= "versions.running_times() Thời gian thực hiện và tài liệu tham khảo cho Lua-coders.",
    	versions_luatables_counts				= "<b>%1</b> biến, <b>%3</b> Subtables, <b>%2</b> chức năng",
    	versions_table_dont_exists				= "Bảng <b>%1</b> không tồn tại.",
    	versions_table_listlimit_levelmaxi		= "Giới hạn mức recursive_limit = <b>%1</b> ",
    	versions_table_listlimit_max_n			= "Giới hạn độ dài max_n = <b>%1</b> ",
    	versions_antiCrash_tests_title			= "versions.anti_crash() Kiểm tra: trong trường hợp lỗi khi chạy, không ghi đè lên trang.",
    	versions_antiCrash_reference_label		= "Khảo",
    	versions_with_usage_error_cat			= "Mô-đun có lỗi sử dụng",
    	versions_module_with_error_err			= "Mô-đun có lỗi",
    	versions_with_internal_error_cat		= "Mô-đun có lỗi nội bộ",
    	-- Quản lý phiên bản
    	versions_versions_no_select_altern_err	= "Lỗi phiên bản: không có lựa chọn nào thay thế <b>%1</b> của mô-đun <b>%2</b>.",
    	versions_versions_too_select_altern_err = "Lỗi phiên bản: <b>%1</b> lựa chọn thay thế <b>%2</b> của mô-đun <b>%3</b>.",
    	versions_versions_select_not_used_err	= "Lỗi phiên bản: bộ chọn <b>%1</b> không có trong lựa chọn thay thế <b>%2</b> của mô-đun <b>%3</b>.",
    	versions_versions_missing_module_err	= "Lỗi phiên bản: mô-đun không khả dụng cho phiên bản <b>%1</b> của mô-đun <b>%2</b>.",
    	versions_main_module_missing_err		= "Không tìm thấy mô-đun chính.",
    	versions_select_unknown_module_err		= "Lỗi nội bộ: Mô-đun:<b>%1</b> mất tích được thay thế bởi bình thường Mô-đun:<b>%2</b>.",
    	versions_I18N_module_no_base_err		= "Mô-đun dịch <b>%1</b> không có phiên bản cơ bản.",
    	versions_no_versions_module_err			= "Mô-đun <b>%1</b> không nằm trong hệ thống phiên bản.",
    	versions_all_versions_tests				= "Các phiên bản cảnh báo: <b>%1</b>, bình thường: <b>%2</b>, danh sách: <b>%3</b>.",
    	versions_all_versions_check				= "Phiên bản: thiếu: <b>%1</b>, ẩn số: <b>%2</b>, bình thường: <b>%3</b>, vượt quá: <b>%4</b>, tất cả đã chọn: <b>%5</b>.",
    	versions_missing_versions_err			= "Mô-đun <b>%1</b> bị thiếu trong mô-đun chính <b>%2</b>.",
    	versions_replaced_versions_err			= "Mô-đun <b>%1</b> thay thế mô-đun phụ bị thiếu trong mô-đun chính <b>%2</b>.",
    	versions_unknownversions_err			= "Mô-đun <b>%1</b> không được biết trong mô-đun chính <b>%2</b>.",
    	versions_module_miss_i18n_txt_err		= "Lỗi nội bộ: Văn bản <b>%1</b> thiếu bản dịch ngôn ngữ <b>%2</b>, và / hoặc những người khác.",
    	versions_module_miss_i18n_count_err		= "Lỗi nội bộ: Có khoảng cách <b>%1</b> trong số <b>%2</b> bản dịch.",
    	versions_module_miss_i18n_none_err		= "OK, không có bản dịch bị thiếu.",
    	versions_module_miss_i18n_trad_err		= "Lỗi nội bộ: thiếu bản dịch cho đối số <b>i18n.%1.%2</b>.",
    	-- Tiêu đề kiểm tra
    	versions_all_G_and_loaded_list_title	= "versions.all_G_and_loaded_list() Các đối tượng trong không gian toàn cầu _G",
    	versions_central_changes_headers		= "chính; giá trị; tài khoản; trình độ",
    	versions_support_desk_title				= "Thông tin hỗ trợ: Phiên bản <b>%1</b>",
    	versions_versions_management_report		= "versions.versions_management_report() Báo cáo quản lý phát hành",
    --	versions_bind_modules_tests_title		= "versions.bind_modules_test() Kiểm tra quản lý phiên bản mô-đun",
    	versions_verif_bind_modules_report		= "Kiểm soát phiên bản và ràng buộc mô-đun",
    	versions_bind_modules_test_headers		= "Các phiên bản được yêu cầu; Các phiên bản được sử dụng; Các phiên bản đã biết; CURRENT: Lỗi trong mô-đun đang hoạt động; Mô phỏng: Lỗi trong mô-đun đang hoạt động",
    	versions_tasks_changes_report			= "versions.tasks_changes_report() Tài liệu, nhiệm vụ và sửa đổi",
    	versions_sort_central_modules_title		= "versions.sort_central_modules_report() Sắp xếp danh sách các mô-đun và thư viện trung tâm.",
    	versions_sort_central_modules_headers	= "Tiêu đề; phiên bản; ngày; Bản dịch / Ngôn ngữ",
    	versions_sort_central_modules_counts	= "điều này: + <b>%2</b>/<b>%3</b> T/L, ",
    	versions_versions_management_title		= "versions.versions_support_test() Kiểm tra hỗ trợ phiên bản.",
    	versions_versions_management_headers	= "tìm kiếm; phiên bản; quá trình; bình luận",
    	versions_add_deprecated_err				= "Hàm không được chấp nhận <b>%1(...)</b>. Thay thế bằng <b>%2(...)</b> trong mô-đun <b>%3</b>.",
    	versions_deprecated_function_tests		= "versions.deprecated_function() Test: Chức năng lỗi thời. Thay thế nó trong mô-đun.",
    } -- versions.i18n.vi
    
    versions.ModuleNS = mw.site.namespaces.Module.name .. ":"
    
    function versions.bind_all_i18n() -- Bind all i18n translations from all sub-modules in reverse order.
    --	Translate all translations in the exact reverse order, using the memorised binding order.
    --	Then upper modules happens later and can adapt translations.
    	local t = "\n* versions.bind_all_i18n() "
    	for i = lua_table.level_count(versions.central_libraries_sort), 1, -1 do -- in reverse order
    		sub_module_name = versions.central_libraries_sort[i]
    		local get = versions.bind_main_and_sub_modules_get[sub_module_name] -- Use the get descriptor of the sub_module.
    		-- Add i18n translations from the sub-module itself:
    		if (type(get.title) == "string") and (type(get.i18n) == "table") then
    			versions.add_one_i18n("", get.title, get.i18n) -- Add i18n translations with previews one's.
    			t = t .. "\n*" .. viewers.ta("title", get.title)
    			t = t .. viewers.ta("#i18n", lua_table.level_count(get.i18n) )
    		end
    		-- Add i18n translations from an eventual /I18N sub-module:
    		if (type(get.subI18N) == "string") then
    			local get, module = versions.get_one_module_or_library(get.subI18N)
    			if (type(get.title) == "string") and (type(get.i18n) == "table") then
    				versions.add_one_i18n("", get.title, get.i18n) -- Add i18n translations with previews one's.
    				t = t .. "\n*" .. viewers.ta("title", get.title)
    				t = t .. viewers.ta("#i18n", lua_table.level_count(get.i18n) )
    			end
    		end
    	end
    	return t
    end -- t = versions.bind_all_i18n() -- Bind all sub-modules of the main module.
    
    function versions.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n.
    	-- The main module call this function to load needed sub-modules and translations.
    	local res = "\n* versions.bind_the_main_module() "
    	local frame = mw.getCurrentFrame()
    	local title = frame:getTitle() -- main module, example "Auteur"
    	local get, main_module = versions.get_one_module_or_library(title) -- Get the main module.
    	-- Table to collect loaded sub-modules names in binding order and i18n translations in reverse order.
    	versions.mainversion = title
    	versions.central_libraries_sort = versions.central_libraries_sort or {}
    	table.insert(versions.central_libraries_sort, title) -- Record first the main module name.
    	versions.bind_main_and_sub_modules_get = versions.bind_main_and_sub_modules_get or {}
    	versions.bind_main_and_sub_modules_get[title] = get -- Record the get descriptor of the main module.
    	--
    	-- After get the main module, get the versions for their management.
    	-- The main module can use or not the versions management.
    	versions.main_module = main_module
    	if type(main_module) == "table" and type(main_module.version) == "table" then -- For main modules using versions management
    		versions.main_versions = main_module.version
    	end
    	local main_versions = versions.main_versions -- nil if the main module do not uses the versions management.
    	--
    	if not versions.main_module then -- The main module is not found.
    		res = res .. viewers.styles_color_error( viewers.form9user("versions_main_module_missing_err") )
    	end
    	langs.main_i18n = langs.main_i18n or versions.main_i18n or {}
    	versions.main_i18n = langs.main_i18n
    	return res
    end -- function versions.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n.
    
    function versions.bind_all_sub_modules_test() -- Test : Bind all sub-modules of the main module.
    	versions.bind_all_sub_modules_track = "TEST"
    	local memo = viewers.save_configs("versions.bind_all_sub_modules_test") -- Save global configuration before eventual changes.
    	local sub_modules = versions.sub_modules
    	local iftest = true
    	local t = "\n* versions.bind_all_sub_modules() TEST Bind all sub-modules of the main module."
    	t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_tries</b> :" .. lua_table.rough_view(sub_modules.sub_tries)
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = sub_modules.sub_tries,
    		title_memo = "versions.bind_all_sub_modules() Bind all sub-modules of the main module",
    		headers = " insub;		sub;		sought;		known;	errors ",
    		headers_class = "wikitable alternative center sortable",
    	--	track_on = true,
    	}
    	--
    	tab_view.test_group = sub_modules.sub_tries
    	tab_view.headers = " insub;		sub;		sought;		sub_modules.sub_tries known;	errors "
    	function tab_view.form_one_case(case, all_cases) -- Convert a case from test_group to rowGroup.
    		return { case.insub, case.sub, case.sought, case.known, case.errors or "", }
    	end
    	local tt, sub_tries = versions.bind_all_sub_modules(sub_modules, iftest) -- Bind all sub-modules of the main module.
    	--
    	t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_tries</b> :" .. lua_table.rough_view(sub_modules.sub_tries)
    	tab_view.test_group = sub_modules.sub_tries
    	tab_view.headers = " insub;		sub;		sought;		sub_modules.sub_tries known;			errors "
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	--
    	t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_used</b> :" .. lua_table.rough_view(sub_modules.sub_used)
    	tab_view.test_group = sub_modules.sub_used
    	tab_view.headers = " insub;		sub;		sought;		sub_modules.sub_used known;			errors "
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	--
    	viewers.restore_configs(memo, "versions.bind_all_sub_modules_test") -- Restore global configurations after eventual changes.
    	return t
    end -- t = versions.bind_all_sub_modules_test()
    
    versions.bind_all_sub_modules_track = "SOURCE"
    versions.sub_modules = {}
    versions.sub_modules.sub_tries = { -- TEST: Bind all sub-modules of the main module.
    	-- Normal cases: all known = "Box1, Box3 * Group;Group2;Group4 * Item;Item5;Item7"
    	Main	= { versionName = "Main",	sought = "Box1;Group2;Item5", known = "Box1;Box3 * Group;Group2;Group4 * Item5;Item7", },
    	Box1	= { versionName = "Box1",	sought = "Group2;Item5",	known = "Group;Group2;Group4 * Item5;Item7", },
    	Box3	= { versionName = "Box3",	sought = "Group2;Item",		known = "Group2;Group4 * Item;Item5", },
    	Group2	= { versionName = "Group2", sought = "Item",			known = "Item;Item5,Item7", },
    	Group4	= { versionName = "Group4", sought = "Item5",			known = "Item;Item5,Item7", },
    	-- Errors cases:
    	Box1_ms = { versionName = "Box1",	sought = "Group2",			known = "Group;Group2;Group4 * Item5;Item7", }, -- missing sought
    	Box3_es = { versionName = "Box3",	sought = "Group2;ItemERR",	known = "Group2;Group4 * Item;Item5", }, -- erroneous sought
    	Group2_mk = { versionName = "Group2", sought = "Item",			known = "Item5,Item7", }, -- missing known
    	Group4_ek = { versionName = "Group4", sought = "Item5",			known = "Item;ItemERR,Item7", }, -- erroneous known
    	Box3_ks = { versionName = "Box3",	sought = "Group2;ItemERR",	known = "Group2;Group4 * Item;Item5", }, -- known repairs erroneous sought
    }
    
    -- versions.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n.
    function versions.bind_all_sub_modules(sub_modules, iftest) -- Bind all sub-modules of the main module.
    	local t = "\n* versions.bind_all_sub_modules() Bind all sub-modules of the main module."
    	t = t .. "\n* versions.bind_all_sub_modules_track : " .. versions.bind_all_sub_modules_track
    	-- Method: Record in a stack the sought sub-modules for the main_module.
    	-- For each try of sub-module, add it in stack. That extend the stack along the procces.
    	-- For each error, when found, add it the errors stack. At the end prioritize them and display only the most significant.
    	-- To report that display sought known and used sub-modules like in the stack, in colors to show typical errors.
    	-- To test these process, try normal and erroneous cases.
    	-- These process are like a small expert system.
    	-- The main module call this function to load needed sub-modules and translations.
    	-- Later run versions.bind_reverse_i18n_translations() -- Bind all i18n translations in reverse order, from modules and their /I18N sub-modules
    	local sub_modules = sub_modules
    	local iftest = iftest or false
    	local actual_init, sub_modules_stack
    	local main_module, main_versions, ModuleNS
    	local sub_tries, i_tries, sub_used, i_used
    	local sought, known = "", ""
    --	Select and activate the right scenario, actual or for test.
    	if iftest then -- TEST: Bind all sub-modules of the main module.
    		versions.bind_all_sub_modules_track = "TEST"
    		sub_modules.ModuleNS = "Module:"
    		if (type(sub_modules) ~= "table") and (type(versions.sub_modules) == "table") then sub_modules = versions.sub_modules end
    		sub_modules = mw.clone(sub_modules)
    		sub_tries = sub_modules.sub_tries or {}
    		sub_modules.sub_used = {}
    		i_tries = sub_modules.i_tries or {}
    		sub_modules.i_used = {}
    		main_versions = sub_tries.Main -- from main test, with versions.versionName = "Main" as example
    	else -- ACTUAL: Bind all sub-modules of the main module.
    		versions.bind_all_sub_modules_track = "ACTUAL"
    		main_module = versions.main_module
    		main_versions = versions.main_versions
    		sub_modules = {}
    		sub_modules.ModuleNS = mw.site.namespaces.Module.name .. ":"
    		sub_modules.sub_tries = {}
    		sub_modules.sub_used = {}
    		sub_modules.i_tries = {}
    		sub_modules.i_used = {}
    		sub_tries = sub_modules.sub_tries or {}
    		sub_tries.Main = main_module.version -- from main actual, with versions.versionName = "Central-s-fr" as example
    		if (type(main_module.version) ~= "table") then -- Start the version management binding for the main module.
    		-- ACTUAL: Bind all sub-modules of the main module.
    			main_versions = sub_tries.Main
    		end
    		if (type(main_module.version) == "table") then -- Start the version management binding for the main module.
    			-- ACTUAL: Bind all sub-modules of the main module.
    			sub_tries.Main = main_module.version -- with versions.versionName = "Central-s-fr" as example
    		end
    	end
    	-- Get initial sought and known sub_modules
    	local function viewers_sub_to_i_sub(sub) -- Formats a sequence table from a keyed table.
    		local tosub = {}
    		for key, elem in pairs(sub) do
    			elem[insub] = key
    			table.insert(tosub, elem)
    		end
    		return tosub
    	end
    	t = t .. "\n* bind_sub_modules() start: "
    	local sought_t = string.gsub(sought or "", " ", ";") -- ";" .. .. ";"
    	local sought_tab = mw.text.split(sought_t, ";", true)
    	local sought_maxn = table.maxn(sought_tab)
    	local known_tab = mw.text.split(main_versions.known or known or "", "*", true)
    	local known_maxn = table.maxn(known_tab) -- local known_maxn = #known_tab
    	local used = ";"
    	t = t .. "\n* list versioning sought.bind_sub_modules : "
    	.. viewers.ta("main_versions.versionName", main_versions.versionName)
    	.. viewers.ta("main_versions.sought", main_versions.sought) .. viewers.ta("sought_maxn", sought_maxn)
    	.. "<br>" .. viewers.ta("main_versions.known", main_versions.known) .. viewers.ta("known_maxn", known_maxn)
    	local sub_tries = {} -- Duplicate sub_tries to not disturb original sub_modules.sub_tries
    	for key, elem in pairs(sub_modules.sub_tries) do -- alternatives = known_tab[i]
    		local try = mw.clone(elem) -- Duplicate sub_tries to not disturb original sub_modules.sub_tries
    		sub_tries[key] = try
    	end
    	local normal, altern, alternatives, kind, altern_tab
    	local elem, module, normal, alias, name_I18N, version
    	for i, try in  pairs(sub_tries) do -- alternatives = known_tab[i]
    		local sought_t = string.gsub(try.sought or "", " ", ";") -- ";" .. .. ";"
    		local known_tab = mw.text.split(try.known or "", "*", true)
    		local known_maxn = table.maxn(known_tab) -- local known_maxn = #known_tab
    		try.errors = ""
    		alternatives = try.known
    		alternatives = ";" .. mw.text.trim(alternatives) .. ";" -- normalize versions between ";"
    		local altern_tab = mw.text.split(alternatives, "*", true) -- see _Example
    		for i, alternate in ipairs(altern_tab) do
    			local sought_tab = mw.text.split(sought_t, ";", true)
    			local sought_maxn = table.maxn(sought_tab)
    			normal = "" ; version = ""
    			for v, altern in ipairs(sought_tab) do
    				altern = tostring(altern)
    				altern = mw.text.trim(altern)
    				if v == 1 then -- Permit to select normal version in case of none others match.
    					normal = altern
    					kind = "normal"
    				end
    				-- Try others alternate versions
    				local try = { insub = normal, versionName = altern, ["sought"] = sought, ["known"] = known, }
    				try.errors = ""
    				local insert_try = false
    				if v == 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then
    			--		sub_modules.sub_used = {} -- Bind all sub-modules used in the main module.
    				end
    				if v > 1 then -- and viewers.is_in_sp(altern, sought, ";")
    					version = altern
    					kind = "version"
    				end
    				if not viewers.is_in_sp(altern, sought, ";") then
    					try.errors = try.errors .. "; altern_is_not_in_sought"
    				end
    				if viewers.is_in_sp("WantedError", known, ";") then
    	--	{ insub = "Box2", versionName = "Group4", sought = "Item4;Item", known = "Item2;WantedError;Item3", }, -- Example of test case
    					try.errors = (try.errors or "") .. "altern_is_WantedError"
    					try.known = "Item2;Item3" -- PREVENT A RECURSIVE LOOP IN STACK
    				end
    				if try.versionName == "Box3" then
    					try.versionName = "Box345" -- PREVENT A RECURSIVE LOOP IN STACK
    					try.errors = try.errors .. "; altern_is_Box3"
    				end
    				if try.insub == "Group2" then
    					try.errors = try.errors .. "; altern_is_WantedError"
    				end
    				if viewers.is_in_sp(altern, known, ";") then -- Try another sub_module
    					local new_try = nil
    					if iftest then -- In test of versions management
    						if (type(sub_tries[altern]) == "table") then new_try = sub_tries[altern] end
    					else -- In normal run of versions management
    						--	Get a module or a library, then form and record a descriptor of it.
    						local get, module = versions.get_one_module_or_library( sub_modules.ModuleNS .. altern )
    						if (type(get.module) == "table") and (type(get.moduleName) == "string") then -- Verify main module and versions management ability.
    							new_try = { insub = altern, versionName = get.moduleName, ["sought"] = get.module.version.sought, ["known"] = get.module.version.known, errors = "" }
    							insert_try = true
    						end
    					end
    					if new_try and lua_table.level_count(sub_tries) < 111 then -- Limit the number of sub_modules to 111
    						sub_modules.sub_tries[altern] = new_try
    						sub_modules.i_tries = viewers_sub_to_i_sub(sub_modules.sub_tries) -- Formats a sequence table from a keyed table.
    						sub_modules.sub_used[altern] = new_try
    						sub_modules.i_used = viewers_sub_to_i_sub(sub_modules.sub_tries) -- Formats a sequence table from a keyed table.
    						sought = sought .. ";" .. new_try.sought -- this sub_modules extend sought for inner sub_modules
    						known = known .. " * " .. new_try.known -- this sub_modules extend known for inner sub_modules
    					else
    						try.errors = try.errors .. "; Limit the number of sub_modules to 111"
    					end
    				end
    			end
    		end
    	end -- for i = known_maxn, 1, -1 do -- alternatives = known_tab[i]
    	--
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = sub_modules.sub_tries,
    		title_memo = "versions.bind_all_sub_modules() Bind all sub-modules of the main module",
    		headers = " insub;		sub;		sought;		known;	errors ",
    		headers_class = "wikitable alternative center sortable",
    	--	track_on = true,
    	}
    	tab_view.test_group = sub_modules.i_tries
    	tab_view.headers = " insub;		sub;		sought;		sub_modules.i_tries known;			errors "
    	--
    	tab_view.test_group = sub_modules.i_used
    	tab_view.headers = " insub;		sub;		sought;		sub_modules.i_used known;			errors "
    	--
    	if iftest	then versions.bind_all_sub_modules_test_report = t -- TEST: Bind all sub-modules of the main module.
    				else versions.bind_all_sub_modules_actual_report = t end -- TEST: Bind all sub-modules of the main module.
    	return t, sub_modules.sub_used
    end -- t, sub_modules = versions.bind_all_sub_modules(sub_modules, iftest)
    
    versions.bindable_libraries = { -- New libraries to record in package.loaded[]
    	["activity"]	= "The <b>activity</b> library supports Lua-coders sub-tasks for central modules in international interactions.",
    	["datas"]		= "The <b>datas</b> library formats some viewers for tables(in lines and columns), luatables...",
    	["drop_box"]		= "The <b>drop_box</b> library formats Drop-boxes as objects, inside the viewers library",
    	["events"]		= "The <b>events</b> library formats events like errors, warnings and categories.",
    	["langs"]		= "The <b>langs</b> library supports i18n translations.",
    	["lua_table"]	= "The <b>lua_table</b> library enhances the previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table.",
    	["modes"]		= "The <b>modes</b> library supports modes and their options, like p.read(frame).",
    	["tableview"]	= "The <b>tableview</b> library formats tableviews as objects, inside the viewers library",
    	["tracker"]		= "The <b>tracker</b> library implements parametrable track objects to debug the Lua code, inside the activity library.",
    	["versions"]	= "The <b>versions</b> library installs all central libraries, bind modules, libraries and i18n translations. Also support versions management.",
    	["viewers"]		= "The <b>viewers</b> library formats some viewers for tables(in lines and columns), Drop-boxes, luatables...",
    	["mathroman"]	= "The <b>mathroman</b> library converts roman numbers and detect errors. It is here as an example of very small central library.",
    }
    
    function versions.get_one_module_or_library(title, given_module) -- Get a module or a library, then form and record its descriptor.
    --	local get, module = versions.get_one_module_or_library("Module:Centralizer") -- basic example of use
    	local get, module, required, loaded = {}
    	if type(title) ~= "string" then
    		get.title = "abnormal title : " .. tostring(title)
    		get.is_nil = true
    		return get
    	end -- If not loaded, return only an empty get
    	if (type(given_module) == "table") or (type(given_module) == "function") then
    		module = given_module
    	else -- to require a new module
    		loaded = versions.pcallRequire(title) -- require() must not fail and block the page if the module do not exists.
    		if (type(loaded) == "table") or (type(loaded) == "function") then module = loaded -- The module is well loaded in package.loaded
    		else return get end -- If not loaded, return only get.isTitled and get.title
    	end
    	get.title = title -- like Module:Author, or the versioning library
    	get.module = module -- like {...}
    	get.is_nil = not module -- like true or false
    	get.is_loaded = true and package.loaded[title] -- true if the module is in package.loaded
    	get.is_function = (type(module) == "function") -- true if the module is a function
    	get.is_table = (type(module) == "table") -- true if the module is a table
    	get.i18n = module.i18n -- i18n table of the module
    	get.version = module.version -- table including module.version.known and module.version.sought
    	get.is_library = (type(module)=="table") and not (type(module)=="function") and not (string.find(title, versions.ModuleNS, 1, true) )
    	get.hasi18n = (type(module) == "table") and (type(get.i18n) == "table") -- true if the object has a i18n translations table
    	get.versionName = string.gsub(get.title or "", versions.ModuleNS, "") -- without Module:		like versioning or Author
    	get.versionTitle = versions.ModuleNS .. get.versionName -- normalize title					like Module:Author
    	get.is_module = string.find(get.title, versions.ModuleNS) -- true if the object is				like Module:Author
    	get.isI18N = true and string.find(get.title, "/I18N") -- true if the title contains /I18N		like Module:Author/I18N
    	get.withoutI18N = string.gsub(get.versionName, "/I18N", "") -- version without /I18N			like versioning or Module:Author
    	get.versionI18N = get.withoutI18N .. "/I18N" -- version with /I18N								like Module:Author/I18N
    	get.nowstamp = os.date("%Y%m%d%H%M%S") -- like YYYYMMDDhhmmss from module
    	-- Special for ISmodule, ISlibrary, ISfunction
    	if get.is_library then
    		get.revistamp = get.nowstamp
    		get.TitleI18N = versions.ModuleNS .. "Library/" .. get.withoutI18N .. "/I18N" --	like Module:Library/versioning/I18N
    		get.pagename = TitleI18N -- Locate translations										like Module:Library/versioning/I18N
    		get.i18nRoot = get.versionName -- Where locate translations are						like versioning
    	elseif get.is_module then
    		get.revistamp = mw.getCurrentFrame():preprocess( "{{REVISIONTIMESTAMP:" .. get.title .. "}}" )
    		get.pagename = "Module:" .. get.versionName -- Locate translations					like Module:Centralizer/I18N
    		get.i18nRoot = get.pagename -- Where locate translations are						like Module:Author
    		get.TitleI18N = versions.ModuleNS .. get.withoutI18N .. "/I18N" --				like Module:Centralizer/I18N
    	else
    		get.revistamp = mw.getCurrentFrame():preprocess( "{{REVISIONTIMESTAMP:" .. get.title .. "}}" )
    	end
    	get.versionName = string.gsub(get.title or "", versions.ModuleNS, "") -- full version name with perhaps /I18N
    	get.simplename = string.gsub(get.versionName, "/I18N", "") -- delete "/I18N" if any
    	get.viewI18N = get.simplename
    	if type(module) == "function" then
    		get.is_function = true -- ISfunction
    		get.is_module = false
    		get.is_library = false
    		get.functionName = get.simplename --												like tostring
    		get.pagename = "function:" .. get.simplename --										like function:tostring
    	elseif string.find(get.title, versions.ModuleNS) then -- If the module title begin with "Module:"
    		get.is_function = false
    		get.is_module = true -- ISmodule
    		get.is_library = false
    		get.moduleName = get.title -- complete the title with "Module:"						like Module:Centralizer
    		get.subI18N = get.title .. "/I18N" -- eventual sub-module "/I18N"					like Module:Centralizer/I18N
    		get.pagename = versions.ModuleNS .. get.simplename --								like Module:Centralizer
    		if get.isI18N then get.pagename = get.pagename .. "/I18N" end --					like Module:Centralizer/I18N
    		if get.isI18N then get.viewI18N = get.simplename .. "/I18N" end --					like Central/I18N
    	else -- If the module is a library
    		get.is_function = false
    		get.is_module = false
    		get.is_library = true -- ISlibrary
    		get.libraryName = get.title -- standard library name								like versioning
    		get.versionName = get.libraryName --												like versioning
    		get.pagename = versions.ModuleNS .. "Library/" .. get.title --					like Module:Library/versioning
    		get.subI18N = get.pagename .. "/I18N" -- /I18N sub-module							like Module:Library/versioning/I18N
    		if get.isI18N then get.pagename = get.subI18N end --								like Module:Library/versioning/I18N
    		if get.isI18N then get.viewI18N = get.simplename .. "/I18N" end --					like versioning/I18N
    	end
    	if get.isI18N and (type(get.module) == "table") and (type(get.module.i18n) == "table") then get.sub_i18n = get.module.i18n end
    	-- stamp, date and time
    	if not get.revistamp then get.revistamp = os.date("%Y%m%d %H%M%S") end
    	local function days(stamp) -- approximate the number of days from 0000-01-01
    		local day = 0
    		if (type(stamp) == "string") and (string.len(stamp) > 7) then
    			day = tonumber(string.sub(stamp,1,4)) * 365 +
    			tonumber(string.sub(stamp,5,6)) * 30 +
    			tonumber(string.sub(stamp,7,8))
    		end
    		return day
    	end
    	if get.revistamp then
    		get.days_revis = days(get.revistamp)
    		get.days_now = days(get.nowstamp)
    		get.delay = get.days_now - get.days_revis
    		get.revistime = string.sub(get.revistamp,1,4) .. "-" .. string.sub(get.revistamp,5,6) .. "-" .. string.sub(get.revistamp,7,8)
    			.. " " .. string.sub(get.revistamp,-6,-5) .. ":" .. string.sub(get.revistamp,-4,-3)
    		get.shortdays = string.sub(get.revistamp or "", 3, 8)
    		get.shorttime = string.sub(get.revistime or "", -9, -1)
    		if get.delay < 25 -- time4
    			then get.shortVersion = "v" .. get.shorttime -- short version in "vDD hh:mm" until around 25 days
    			else get.shortVersion = "v" .. get.shortdays -- later in date vYYMMDD
    		end
    		get.versionDate = get.revistime
    		get.versionNumber = get.shortVersion
    		get.versionName = string.gsub(get.title or "", versions.ModuleNS, "") -- full version name with perhaps /I18N
    		get.versionDate = get.revistime
    		if type(get.module.version) == "table" then -- For central modules or libraries only:
    			get.module.versionName = get.versionName -- Record in each module to later IDENTIFY any module. See task T119978, "own module name"
    			get.module.versionDate = get.versionDate -- Record in each module to later DATE any module. See task T119978, "own module name"
    		end
    	end
    	if get.version then
    		get.sought = get.version.sought or get.version.selector or ""
    		get.known = get.version.known or get.version.all_versions or ""
    		--
    		local str = string.gsub(get.sought, " ", ";")
    		get.sought_tab = mw.text.split(str, ";", true)
    		get.sought_count = lua_table.level_count(get.sought_tab)
    		--
    		local str = string.gsub(get.known, "*", ";")
    		get.known_tab = mw.text.split(str, ";", true)
    		get.known_count = lua_table.level_count(get.known_tab)
    	end
    	-- Record the get descriptor with others
    	versions.loaded_modules_and_libraries = versions.loaded_modules_and_libraries or {}
    	if get.i18n then table.insert(versions.loaded_modules_and_libraries, get) end
    	--
    	versions.bind_main_and_sub_modules_get = versions.bind_main_and_sub_modules_get or {}
    	versions.bind_main_and_sub_modules_get[get.title] = get
    	return get, module
    end -- get, module = versions.get_one_module_or_library(title, given_module)
    
    function versions.add_one_i18n(t, module_name, module_tab) -- Add with others an i18n translations table and list all differences of translations.
    	local t = t or ""
    	local main_i18n = langs.main_i18n or versions.main_i18n or versions.memo_i18n
    	local i18n, lang_N, text_N = {} ,0, 0
    	local translations_differences = {}
    	function versions.detect_transDiff(trans1, trans2) -- Collect all differences of translations
    		if trans1.dtrans and trans2.dtrans and (trans1.dlang == trans2.dlang) and (trans1.dkey == trans2.dkey) and (trans1.dtrans ~= trans2.dtrans) then
    			table.insert(translations_differences, { ["trans1"] = trans1, ["trans2"] = trans2 }) -- build a table with only languages codes
    		end -- Only fast collect to treat later if needed.
    	end
    	if type(module_tab) == "table" and type(module_tab.i18n) == "table"	 then -- and type(module_tab.i18n) == "table" then
    		i18n = module_tab.i18n or {} -- i18n
    		lang_N, text_N = 0, 0
    		for lang, trans in pairs(i18n) do -- For all languages of the mixed module or library
    			if main_i18n[lang] then -- the language already exists, add or replace imported fields
    				lang_N = lang_N + 1
    				if type(trans) == "table" then -- if the language to add is really in a table
    					for key, val in pairs(trans) do -- For all imported fields
    						versions.detect_transDiff( -- Collect all differences of translations
    							{ dlang = lang, dkey = key, dfile = "previous", dtrans = main_i18n[lang][key] },
    							{ dlang = lang, dkey = key, dfile = module_name, dtrans = val} )
    						main_i18n[lang][key] = val -- add or replace a field and its translation
    						text_N = text_N + 1
    					end
    				end
    				t = t .. viewers.form9user(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N)
    			--	t = t .. viewers.form9tests(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N)
    			else -- add the table and all is fields if it is not already in langs.main_i18n
    				if mw.language.isKnownLanguageTag(lang) then -- only for languages known in wikis
    					lang_N = lang_N + 1
    					main_i18n[lang] = mw.clone(trans)
    					text_N = text_N + lua_table.level_count(trans)
    					t = t .. viewers.form9user(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N)
    				--	t = t .. viewers.form9tests(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N)
    				end
    			end
    		end
    	end
    	t = t .. viewers.ta("lang_N", lang_N) .. viewers.ta("lang_N", text_N)
    	return t, lang_N, text_N
    end -- function versions.add_one_i18n(t, module_name, module_tab)
    
    function versions.pcallRequire(version) -- require() must not fail and block the page.
    	if type(version) == "string" then
    		version = string.gsub( version, versions.ModuleNS, "" ) -- normalize for always one "Module:"
    		local bug = "Erreur Lua dans Module:Centralizer-s-fr à la ligne 5778 : attempt to call field 'gsub' (a nil value)."
    		version = versions.ModuleNS .. version -- example Module:Centralizer/I18N
    	end
    	local success, module = pcall( require, version ) -- pcall or xpcall can run any function without blocking page.
    	if not success then module = nil end
    	return module
    end
    
    function versions.setup_central_libraries(bindable_libraries, opt) -- Install central bindable libraries in package.loaded
    	-- Record centralisable libraries if they are not included in standard mw.Extension:Scribunto
    	-- RunOnce : Do not repeat this function to not disturb subsequent processes.
    	local bindable_libraries = bindable_libraries or versions.bindable_libraries
    	versions.central_libraries_sort = versions.central_libraries_sort or {}
    	local sorted_bind_libraries = versions.central_libraries_sort
    --	Record central libraries from _G space to package.loaded, using setup.
    	local sorted_bind_libraries = {}
    	activity	= central_library.new("activity", activity) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, activity) -- Record all libraries
    	args		= central_library.new("args", args) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, args) -- Record all libraries
    	central_library = central_library.new("central_library", central_library) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, central_library) -- Record all libraries
    	datas		= central_library.new("datas", datas) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, datas) -- Record all libraries
    	drop_box	= central_library.new("drop_box", drop_box) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, drop_box) -- Record all libraries
    	events		= central_library.new("events", events) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, events) -- Record all libraries
    	langs		= central_library.new("langs", langs) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, langs) -- Record all libraries
    	lua_table	= central_library.new("lua_table", lua_table) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, lua_table) -- Record all libraries
    	mathroman	= central_library.new("mathroman", mathroman) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, mathroman) -- Record all libraries
    	modes		= central_library.new("modes", modes) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, modes) -- Record all libraries
    	tableview	= central_library.new("tableview", tableview) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, tableview) -- Record all libraries
    	tracker		= central_library.new("tracker", tracker) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, tracker) -- Record all libraries
    	versions		= central_library.new("versions", versions) -- Lock in _G and package.loaded
    	table.insert(sorted_bind_libraries, versions) -- Record all libraries
    	viewers		= central_library.new("viewers", viewers) -- Lock in _G and package.loaded
    	local libname_libraries = {}
    	for i, obj in pairs(sorted_bind_libraries) do -- Record the get descriptor with others
    		obj.libname = obj.libname or obj.name -- or obj.infos.libname
    		if (type(obj) == "table") and (type(obj.infos) == "table") and (type(obj.infos.libname) == "string") then
    			obj.libname = obj.infos.libname
    			table.insert(libname_libraries, obj)
    		end
    	end
    	table.sort(libname_libraries, function (a, b) return ( a["libname"] < b["libname"] ) end )
    	versions.sorted_bind_libraries = libname_libraries
    	versions.sorted_bind_libraries_t = viewers.ta("\n* #versions.sorted_bind_libraries", lua_table.level_count(versions.sorted_bind_libraries) )
    	local title, description = "", ""
    	local object, library, get = {}, {}, {}, {}, {}
    	for i, object in ipairs(libname_libraries) do -- Record the get descriptor with others
    	--	object = package.loaded[name]
    		if (type(object) == "table") and (type(object.i18n) == "table") then
    			library = object
    			title = library["libname"]
    			get = versions.get_one_module_or_library(title, library) -- Get a module or a library, then form and record its descriptor.
    			library.description = library["describ_version"]
    		end
    	end
    	-- Check and sort new libraries by name
    	local sorted_libraries = {}
    	local central_libraries = {}
    	for libname, lib in pairs(package.loaded) do
    		lib.libname = libname
    		lib.infos = lib.infos or {}
    		lib.infos.libname = lib.libname
    		table.insert( sorted_libraries, { lib } )
    		if (type(lib) == "table") and (type(lib.i18n) == "table") and (type(libname) == "string") then
    			table.insert( central_libraries, { lib } )
    		end
    	end
    	table.sort(sorted_libraries, function (a, b) return (a.libname or "m") < (b.libname or "m") end ) -- alphabetic sort of objects keys
    	versions.central_libraries = central_libraries
    	local t = "\n* setup_central_libraries : "
    	for i, lib in pairs(central_libraries) do t = t .. viewers.ta( tostring(i), tostring(lib.libname) ) end
    	versions.sorted_libraries_list = t
    	versions.sorted_libraries = sorted_libraries
    end -- function versions.setup_central_libraries(bindable_libraries, opt)
    
    -- - - - ------------------ - - - - ------------------ - - - - -----------------------------
    --	Guideline for modules, arguments, options and default values 20180908.
    --	In all cases the main module protects all original tables, including for itself.
    --	Permit modules without versions for many existing modules. Modules are also simply tables for data-modules or PageData in Json.
    --	3 central functions bind sub-modules, translations and arguments in 3 new tables.
    --	All arguments can have options and default values, like "prop_default" for "prop" to use it in case of tests or missing value.
    --	Arguments and there options come from submodules and the main module changes them.
    --	TODO : They have default values, like "prop_default" for "prop" to use it in case of tests or missing value.
    --	TODO : arguments can come from any submodules, in any order. The main module must redefine them for any cases.
    
    --	function versions.bind_arguments(main_versions, loaded_pack) -- The main module must redefine arguments for any cases.TODO 20180908
    function versions.bind_arguments(main_versions, loaded_pack) -- The main module must redefine arguments for any cases.TODO 20180909
    	local main_versions = main_versions or versions.main_versions
    	local t = "\n* <b>versions.bind_arguments()<b>: Tests of redefine arguments for any cases."
    	local loaded_pack = loaded_pack or versions.loaded_modules_track()
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	local args_changes = {}
    	for i, get in pairs(loaded_pack) do -- for all known sub-modules
    		if (type(get.is_table) == "table") then -- For all types of modules
    			for one_arg, args in pairs(args_known) do -- for all arguments in one module
    				for i, get in pairs(one_arg) do -- for all properties of an argument
    					one_arg.module = one_arg.module or "no module"
    					one_arg.arg = one_arg.arg or "no arg"
    					one_arg.change = one_arg.change or "no change"
    					one_arg.results = one_arg.results or "no results"
    					one_arg.errors = one_arg.errors or "no errors"
    				--	if (type(one_arg) == "table") then table.insert(args_changes, one_arg) end
    				--	return { case.module, case.arg, case.change, case.results, case.errors } -- example of case to view
    				--	["birthyear"] = { ["typ"] = "dat", ["keyword"] = "birthyear",	["prop"] = "P569", ["format"] = "year", }, in Centralizer
    				end
    				table.insert(args_changes, one_arg)
    			end
    		end
    	end
    	versions.args_changes = args_changes -- argschanges Library:modes Group
    	return args_changes, t -- argschanges Library:modes Group
    end -- t = t .. versions.bind_arguments(main_versions, loaded_pack)
    --	The library:modes supports modes and their options, like p.read(frame). en
    --	La biblioteca:modos admite modos y sus opciones, como p.read(frame). es
    --	La bibliothèque:modes prend en charge les modes et leurs options, comme p.read(frame). fr
    --	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Test options from modes", -- argschanges
    --	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Prueba de opciones de modos", -- argschanges
    --	versions_bind_arguments_tests_title = "modes.options_from_args_tests() Test des options de modes", -- argschanges
    --	res = res .. drop_box.new(selector, "versions_bind_arguments_tests_title", modes.options_from_args_tests)
    --	res = res .. drop_box.new(selector, "versions_bind_arguments_tests_title", versions.bind_arguments_tests)
    
    function versions.bind_arguments_tests(t, loaded_pack) -- The main module must redefine arguments for any cases.TODO 20180909
    	local memo = viewers.save_configs("versions.bind_arguments_tests") -- Save global configuration before eventual changes.
    	
    	--	The test case is a module with sub_modules and libraries, which can have arguments.
    	--	Central has 1 sub-module and 10 libraries :
    	--	All these need structured with stable [ args, sub-modes , i18n ]
    	--	Central : with args + 1 sub-modes + libraries with args
    	--	math_roman : with args + tests cases and authority bases
    	--	datas : with args = props + tests cases
    	
    	local t = t or "\n* <b>versions.bind_arguments()<b>: Tests of redefine arguments for any cases."
    	local result_cases = result_cases or versions.args_changes or {}
    	local tests_cases = {
    		["birthyear"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "birthyear",	["prop"] = "P569", ["format"] = "year", },
    		["deathyear"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "deathyear",	["prop"] = "P570", ["format"] = "year", },
    		["lastname"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", },
    		["firstname"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "firstname",	["prop"] = "P735", },
    	}
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = tests_cases,
    		title_memo = "versions_bind_arguments_tests_title",
    		headers_class = "wikitable alternative center sortable",
    		tests_title	 = "versions.bind_arguments() Tests of redefine arguments for any cases. **",
    		headers = "module; arg; change; results; errors", -- "OK or error/s"
    		rowGroup = {},
    	--	ccc = {}, -- to remember
    	}
    	-- Runs tests cases and formats a table view with lines and columns.s
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		case.arg = viewers.value(case.arg)
    		case.module = viewers.value(case.module)
    		case.change = viewers.value(case.change)
    		case.results = viewers.value(case.results)
    		case.errors = viewers.value(case.errors)
    	--	headers =	"module; arg; change; results; errors", -- "OK or error/s"
    		return { case.module, case.arg, case.change, case.results, case.errors }
    	end -- errors in result
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "versions.bind_arguments_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- t = t .. versions.bind_arguments_tests(t, loaded_pack)
    
    function versions.bind_reverse_i18n_translations(main_versions, loaded_pack)
    --	Bind all i18n translations from libraries, modules, sub-modules and their /I18N translations sub-modules.
    --	Bind all translations in the exact reverse order of sub-modules binding. Then upper modules can adapt translations.
    	local main_versions = main_versions or versions.main_versions
    	local t = "\n* <b>versions.bind_reverse_i18n_translations()<b>"
    	for i, get in pairs(versions.loaded_modules_and_libraries) do
    		if (type(get.title) == "string") and (type(get.module) == "table") then
    			versions.add_one_i18n("", get.title, get.module) -- Add with previews an i18n translations table
    			t = t .. "\n*" .. viewers.ta("title", get.title)
    			t = t .. viewers.ta("#i18n", lua_table.level_count(get.i18n) )
    		end
    	--	Bind i18n sub-modules, for each its internal i18n then its /I18N sub-module.
    		if (type(get.subI18N) == "string") and (type(get.module) == "table") then
    			versions.add_one_i18n("", get.subI18N, get.module) -- Add with previews an i18n translations table
    			t = t .. viewers.ta("#i18n", lua_table.level_count(get.i18n) )
    		end
    	end
    	return t
    end -- t = versions.bind_reverse_i18n_translations(main_versions, loaded_pack)
    
    function versions.tab_elem_report(tab, key) -- simple text report of versions elements
    	local mode = mode or 1
    	local t = ""
    	if (type(tab) == "table") and (type(key) == "number") then
    		for i, elem in ipairs(tab) do
    			t = t .. "\n* " .. viewers.ta("i", i) .. viewers.ta("title", elem.title)
    			t = t .. viewers.ta("versionName", elem.versionName) .. viewers.ta("versionNumber", elem.versionNumber)
    			t = t .. viewers.ta("versionDate", elem.versionDate) .. viewers.ta("i18n_varstabs", elem.i18n_varstabs)
    		end
    	end
    	if (type(tab) == "table") and (type(key) == "string") then
    		for k, elem in pairs(tab) do
    			if not tonumber(key) then
    				t = t .. "\n* " .. viewers.ta(key, k)
    				t = t .. viewers.ta("versionName", elem.versionName) .. viewers.ta("versionNumber", elem.versionNumber)
    				t = t .. viewers.ta("versionDate", elem.versionDate) .. viewers.ta("i18n_varstabs", elem.i18n_varstabs)
    			end
    		end
    	end
    	return t
    end -- function versions.tab_elem_report(tab, key)
    
    versions.deprecated_functionGroup = versions.deprecated_functionGroup or {}
    function versions.deprecated_function(old, new, kind, use, main_version) -- Deprecated function. Replace it in the module.
    	local res = ""
    	if type(langs.user_lang) == "string" then
    		res = events.add_err("versions_add_deprecated_err", old, new, Central.version.versionName)
    		events.add_cat("modes_no_source_arguments_cat")
    	end
    	versions.deprecated_functionGroup = versions.deprecated_functionGroup or {}
    	versions.deprecated_functionGroup[old] = {
    		["old"] = old, ["new"] = new, ["kind"] = (kind or "kind"), ["use"] = "run",
    		["central_version"] = Central.version.versionName,
    	}
    	return res
    end -- versions.deprecated_function("old", "versions.deprecated_function", "kind", "code", Central.version.versionName) -- Deprecated function. Replace it in the module.
    
    function versions.sort_central_modules_report(t) -- Sorted list of central modules and libraries
    --	versions_sort_central_modules_title = "versions.sort_central_modules_report() Sorted list of central modules and libraries.",
    --	versions_sort_central_modules_headers = "Title; Version; Date; Translations / Languages",
    	local memo = viewers.save_configs("versions.sort_central_modules_report") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>versions.sort_central_modules_report()</b> -- Sorted list of central modules and libraries."
    	local loaded_sorted = {}
    	for key, elem in pairs(versions.loaded_modules_and_libraries) do
    		if elem.hasi18n and elem.is_library then table.insert(loaded_sorted, elem) end
    		if elem.hasi18n and elem.is_module then table.insert(loaded_sorted, elem) end
    --		if versions.loaded_modules_and_libraries[elem.subI18N] then elem.has_I18N = true end
    	end
    	-- loaded_modules_and_libraries
    	local loaded_pack, loaded_txt, modu = versions.loaded_modules_and_libraries
    	versions.loaded_modules_track = "\n* versions.loaded_modules_track : " .. viewers.ta("#versions.loaded_modules_and_libraries", lua_table.level_count(versions.loaded_modules_and_libraries) )
    	t = t .. versions.loaded_modules_track
    	table.sort(versions.loaded_modules_and_libraries, function (a, b) return ( a.pagename < b.pagename ) end )
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = versions.loaded_modules_and_libraries, -- versions.loaded_modules_and_libraries,
    		title_memo = "versions_sort_central_modules_title", -- "versions.sort_central_modules_report() Sorted list of central modules and libraries.",
    		headers = "versions_sort_central_modules_headers", -- "Title; Version; Date; Translations / Languages",
    		form_elem_detail = "versions_sort_central_modules_counts", -- "this + %2/%3 T/L, "
    	}
    	function tab_view.form_one_case(get) -- Convert a case from test_group to rowGroup.
    		local subI18N = ""
    		get.counts = get.counts or "get.counts"
    		if get.i18n then -- get.i18n
    			local vers18 = get.versionName --; if not get.isI18N then vers18 = "" end
    			if get.is_module then get.pagename = "Module:" .. get.versionName end -- Locate translations example in Module:Centralizer/I18N
    			if get.is_library then get.pagename = "Library:" .. get.versionName end -- Locate translations example in Module:Library/versioning/I18N
    			local tabname = get.i18nRoot .. ".i18n"
    			local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(tabname, "versions_sort_central_modules_counts", "user")
    		--	get.counts = viewers.form9user("versions_sort_central_modules_counts", strings_c, tables_c) .. t
    			get.counts = viewers.form9user("this: + %1/%2 T/L, ", strings_c, tables_c)
    		--	get.counts = get.counts .. viewers.form9user("versions_sort_central_modules_counts", strings_c, tables_c)
    			if get.has_I18N then get.counts = get.counts .. "<br>+ i18n in: <b>" .. get.viewI18N .. "</b>" end -- version_I18N
    			if get.versionName and get.pagename then
    			end
    			return { get.viewI18N, get.shortVersion, get.versionDate, get.counts } -- get.pagename,
    			-- "Title; Version; Date; Translations / Languages",
    		end
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "versions.sort_central_modules_report") -- Restore global configurations after eventual changes.
    	return t
    end -- function versions.sort_central_modules_report(t)
    
    function versions.tasks_changes_report(t) -- The tests function uses mode and options to include edit or tests.
    	local res = t or ""
    	res = res .. "\n* List of blocking tasks: " .. versions.tasks_changes_report_normal()
    	return res
    end -- function versions.tasks_changes_report(t)
    
    --	function versions.init(frame, mode_name, args_known, options_for_modes, QITEM)
    function versions.init(frame, Central_version, mode_name, args_known, options_for_modes, QITEM)
    	-- Initializes translations, bind_libraries, bind_sub_modules, get arguments, modes, options.
    	-- Imports arguments from wikidata, module and template with increasing priorities.
    	local res, t = "", ""
    	versions.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n.
    	langs.main_i18n_complete = false -- Mask any views to avoid failures until enough init.
    	Central_version = Central_version or langs.Module_Central_version -- or p.Module_Central_version
    	versions.setup_central_libraries(versions.bindable_libraries) -- Actual installation of central bindable libraries in package.loaded
    	versions.bind_all_sub_modules() -- Bind all sub-modules of the main module.
    	res = res .. modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM)
    	if type(langs) == "table" then langs.main_i18n = langs.main_i18n or versions.main_i18n or {} end -- Same pointers insure later same contents.
    	-- Bind all i18n translations from libraries, modules and their /I18N translations sub-modules
    	local loaded_pack = versions.loaded_modules_and_libraries
    	versions.bind_reverse_i18n_translations(main_versions, loaded_pack) -- Bind all i18n translations from modules and their /I18N translations sub-modules
    	ARGS = tracker.initadd({ ["name"] = "ARGS", limit = 2, }) -- Initialize a track and its track lines.
    	ARGS.add(ARGS, 1, "versions.init before import_arguments") -- ARGS.t
    --	res = res .. langs.init_content_page_user_lang() -- content_lang, page_lang, user_lang, "versions.init")
    	local mix = modes.init_args_mode_options(mix, mode_name, args_template) -- Import and mix args mode and options -- S170710mix
    --	["QITEM"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "QITEM",	["prop"] = "QITEM", prop_default = "Q34743", },
    	local args_known = args_known or modes.args_known or p.args_known or {}
    	for key, one_arg in pairs(args_known) do
    		local argskwn = args_known[key]
    		if type(one_arg) == "table" then
    			if type(one_arg.default_item == "string") then datas.prop_default = one_arg.default_item end -- "Q34743" -- Rudyard Kipling **
    		end
    	end
    	local mix = mix or {}
    	modes.mix = mix -- To easy get, track and test the init_args_mode_options process
    	local mix = modes.init_args_mode_options(mix, mode_name, args_template) -- S170703amo MAMO.t
    --	res = res .. langs.init_content_page_user_lang() -- content_lang, page_lang, user_lang, "versions.init")
    	langs.main_i18n_complete = true -- Unmask all views after enough init.
    	res = res .. versions.detect_MediaWiki_changes()
    	return res
    end -- res = res .. versions.init(frame, Central_version, mode_name, args_known, options_for_modes, QITEM)
    
    function versions.versions_support_test(t) -- Test : List all loaded modules
    	local memo = viewers.save_configs("versions.versions_support_test") -- Save global configuration before eventual changes.
    	local t = (t or "") .. "\n* <b>versions.versions_support_test</b> : Test : List all loaded modules."
    	t = t .. "\n* The selector = <b> Box3, Group, Item1 </b> means: check these modules versions among those available."
    --	t = t .. "<br>" .. lua_table.form_sub_counts("versions.i18n")
    	local loaded_tests = { -- loaded_tests
    		-- Cases to look for the main module
    		{ key = "Box", versionName = "Box", versionDate = "2015-12-02 02:02",
    			request = "normal modules", comment = 'normal module for Box, with alias like : <code>local Box = require("Box")</code>',
    			i18n = { en = { a = "a" } }, sought = "Box", known = "Box", loaded_list = ";Box;", },
    		--
    		{ key = "Box/I18N", versionName = "Box", versionDate = "2016-05-07 18:36",
    			request = "normal with /I18N", comment = "I18N translations for Box",
    			i18n = { en = { a = "a" } }, sought = "Box", known = "Box", loaded_list = ";Box;Box/I18N;", },
    		--
    		{ key = "Box3", versionName = "Box2", versionDate = "2016-05-07 11:11",
    			request = "normal replace known alternate", comment = "alternate version module for Box",
    			i18n = { en = { a = "a" } }, sought = "Box2", known = "Box;Box2", loaded_list = ";Box;Box/I18N;Box2;Box2/I18N;", },
    		--
    		{ key = "Box2/I18N", versionName = "Box2", versionDate = "2016-05-07 19:19",
    			request = "missing actual module", comment = "I18N translations without basic module. Formats an alert.",
    			i18n = { en = { a = "a" } }, sought = "Box", known = "Box2;Box3", loaded_list = ";Box3;Box3/I18N;Box2;Box2/I18N;", },
    		-- Cases to look for sub-modules
    		{ key = "Group", versionName = "Box", I18N = "Group/I18N",
    			request = "normal sub-module", comment = "normal module for Group",
    			i18n = { en = { a = "a" } }, sought = "Group", known = "Group", loaded_list = ";Group;Group/I18N;", },
    		--
    		{ key = "Group4", versionName = "Box", versionDate = "2015-12-11 11:11",
    			request = "unknown sought version", comment = "Mask this to test missing sought version",
    			i18n = { en = { a = "a" } }, sought = "Box;Group", known = "Box", loaded_list = ";Box;", },
    		--
    		{ key = "Group/I18N", versionName = "Box", versionDate = "2016-05-07 22:2",
    			request = "sub-module not exists", comment = "I18N translations for the normal module Group",
    			i18n = { en = { a = "a" } }, sought = "Box;Group", known = "Box * Group", loaded_list = ";Box;", },
    		-- Cases to look for /I18N sub-modules
    		{ key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05",
    			request = "normal sub-module with normal /18N", comment = "normal alternate sub-module Group for Group2",
    			i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box;Box/I18N;Box2;Box2/I18N;", },
    		--
    		{ key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05",
    			request = "unknown module for /18N sub-module", comment = "normal alternate sub-module Group for Group2",
    			i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box;Box/I18N;Box2;Box2/I18N;", },
    		--
    		{ key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05",
    			request = "missing module Box for /18N sub-module", comment = "normal alternate sub-module Group for Group2",
    			i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box/I18N;Box2;Box2/I18N;", },
    		--
    		{ key = "Jocker", versionName = "Jocker", versionDate = "2015-12-21 11:33",
    			request = "not central module, without i18n", comment = "Any module can have no i18n table.",
    			sought = "Box", known = "Box", loaded_list = ";Box;", }, -- i18n = { en = { a = "a" } },
    		--
    		{ key = "Jocker", versionName = "Jocker", versionDate = "2015-12-21 11:33",
    			request = "unknown and not sought actual module", comment = "Any module can be outside of the central system.",
    			i18n = { en = { a = "a" } }, sought = "Jocker.2", known = "Jocker.2", loaded_list = ";Box;", },
    	}
    	t = t .. "\n* <b>loaded_vers</b> : Table of all loaded modules, or simulation."
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = loaded_tests,
    		title_memo = "versions_versions_management_title", -- "versions.versions_support_test() List all loaded modules."
    		headers = "versions_versions_management_headers", -- "sought; versions; process; comments",
    		headers_class = "wikitable alternative center sortable",
    	--	track_on = true,
    	}
    	function tab_view.form_one_case(vers_test) -- Convert a case from test_group to rowGroup.
    		local vers = vers_test
    		local x, vers_err = versions.versions_management_report(vers) -- Detect versions management errors and warnings after bind_sub_modules
    		vers.sought = viewers.simple_list(vers.sought)
    		local vers_sought = ";" ..	string.gsub( (vers.sought or "-s-"), ";", ",<br>" ) .. ";" -- names in column
    		local vers_used = viewers.simple_list(vers.sub_used)
    		vers_used = ";" ..string.gsub( (vers_used or "-u-"), ";", ",<br>" ) .. ";" -- names in column
    		local vers_known = ";" ..	string.gsub( (vers.known or ""), ";", "; " ) .. ";" -- add spaces
    		local vers_loaded_list = ";" .. (vers.versionName or "versionName") .. ";"
    		.. (vers.sought or "sought") .. ";" .. (vers.known or "known") .. ";"
    		vers_loaded_list = vers.loaded_list or vers_loaded_list or "empty loaded list"
    		vers_loaded_list = viewers.simple_list(vers_loaded_list)
    		vers_loaded_list = ";" .. string.gsub(vers_loaded_list, ";", "; " ) .. ";" -- add spaces
    		local vers_results = "<b>" .. (vers.request or "vers.request") .. "</b>"
    		.. "<br>sought: " .. (vers.sought or "") .. " in the main module: <b>" .. vers.versionName .. "</b>"
    		.. "<br>" .. (vers_err or "")
    		.. "<br>known: " .. (vers_known or "")
    		.. "<br>loaded list: " .. vers_loaded_list
    	--	.. "<br>comment: " .. (vers.comment or "")
    		local case = { vers_sought, vers_used, vers_results, vers.comment }
    		return case
    	end
    	t = t .. "\n* " .. viewers.ta("Number of versions simulated:", lua_table.level_count(loaded_tests) )
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "versions.versions_support_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function versions.versions_support_test(t)
    
    function versions.versions_management_report(versions) -- Detect versions management errors and warnings after bind_sub_modules
    --	Todo : Use colors to easier look at errors on sough/known in versions_management_report()
    	local memo = viewers.save_configs("versions.versions_management_report") -- Save global configuration before eventual changes.
    	local t = "\n* <b>versions.versions_management_report()</b>: Versions management details: "
    	local versions, errs, cats = versions, "", ""
    	t = t .. "\n* To debug later to_debug_on_20170531 Rical "
    	if 1 then
    		viewers.restore_configs(memo, "versions.versions_management_report") -- Restore global configurations after eventual changes.
    		return t
    	end
    	if type(versions) ~= "table" then versions = versions.main_versions end
    	local sought_report = viewers.simple_list(versions.sought)
    	local known_report = viewers.simple_list(versions.known)
    	local loaded_report = viewers.simple_list(versions.loaded_list)
    	local used_report = viewers.simple_list(versions.sub_used)
    	local all_once_sort = viewers.simple_list(sought_report .. ";" .. known_report .. ";" .. used_report) -- .. ";" .. loaded_report)
    	local missing_report = ""
    	local replaced_report = ""
    	local unknown_report = ""
    	local all_once_tab = mw.text.split(all_once_sort, ';') -- table of words
    	for i, name in ipairs(all_once_tab) do -- list all used names, only one each, in alphabetic order
    		local name_I18N = string.find(name, "/I18N")
    		-- List erroneous versions which are sought but not found:
    		if viewers.is_in_sp(name, sought_report, ";") and not viewers.is_in_sp(name, known_report, ";") and not name_I18N then
    			missing_report = missing_report .. name .. ";"
    			errs = errs .. ";" .. events.add_err("versions_missing_versions_err", name, versions.versionName ) .. ";"
    			local main_report_Example = "Central-proj-fr.wikisource.org"			-- red error display to_debug_on_20170529 Rical
    			local sought_report_Example = "Central-s-fr;Mathroman2;TestRequire"		-- red error display to_debug_on_20170529 Rical
    			local known_report_Example = "Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4"
    			cats = cats .. events.add_cat("versions_with_usage_error_cat")		-- "Module with usage error"
    		end
    		-- List warning versions which are missing and replaced by normal:
    		if viewers.is_in_sp(name, used_report, ";") and not viewers.is_in_sp(name, sought_report, ";") and not name_I18N then
    			replaced_report = replaced_report .. name .. ";"
    			errs = errs .. ";" .. events.add_err("versions_replaced_versions_err", name, versions.versionName ) .. ";"
    			cats = cats .. events.add_cat("versions_with_usage_error_cat")
    		end
    		if viewers.is_in_sp(name, all_once_sort, ";") and not viewers.is_in_sp(name, known_report, ";") and not name_I18N then
    			unknown_report = unknown_report .. name .. ";" -- found but not known
    			errs = errs .. ";" .. events.add_err("versions_unknownversions_err", name, versions.versionName ) .. ";"
    			cats = cats .. events.add_cat("versions_with_usage_error_cat")
    		end
    	end
    	local loaded_report = viewers.simple_list(loaded_report)
    	local used_report = viewers.simple_list(used_report)
    	local missing_report = viewers.simple_list(missing_report)
    	local replaced_report = viewers.simple_list(replaced_report)
    	local unknown_report = viewers.simple_list(unknown_report)
    	t = t .. "<br/>" .. viewers.ta("sought_report", sought_report)
    	t = t .. "<br/>" .. viewers.ta("known_report", known_report)
    	t = t .. "<br/>To understand:"
    	t = t .. "<br/>" .. viewers.ta("loaded_report", loaded_report)
    	t = t .. "<br/>" .. viewers.ta("used_report", used_report)
    	t = t .. "<br/>" .. viewers.ta("missing_report", missing_report)
    	t = t .. "<br/>" .. viewers.ta("replaced_report", replaced_report)
    	t = t .. "<br/>" .. viewers.ta("unknown_report", unknown_report)
    	viewers.restore_configs(memo, "versions.versions_management_report") -- Restore global configurations after eventual changes.
    	return t, errs
    end -- function versions.versions_management_report(versions)
    
    function versions.sort_and_list_objects(obj_to_list) -- List all objects in _G global space and in package.loaded
    	local t, tt, hh = "", "", "" -- t or "\n* <b>versions.all_G_and_loaded_list()</b> List all objects in _G global space and in package.loaded. "
    	local t, hh, sort_key = "", "", {}
    	if (type(obj_to_list) ~= "table") then return hh, t end
    	local sorted_objects = {}
    	for key, obj in pairs(obj_to_list) do table.insert( sorted_objects, { ["key"] = tostring(key), ["obj"] = obj } ) end
    	if lua_table.level_count(sorted_objects) > 0 then
    		table.sort(sorted_objects, function (a, b) return (a.key < b.key) end ) -- alphabetic sort of objects keys
    		for i, elem in pairs(sorted_objects) do
    			local title = elem.key -- obj_to_list[key]
    			local obj = elem.obj -- obj_to_list[key]
    		--	viewers.styles_colors = "add delete discreet error invoke normal warning wikidata"
    		--	viewers.styles_formats = "big bold small up"
    			local o = versions.get_one_module_or_library(obj, obj) -- (objt, title) Get checked values and types of central objects
    			if o.is_table and (type(obj.add) == "function") then t = t .. viewers.styles(title, "discreet") -- function tracker.initadd() styles
    			elseif o.is_string then t = t .. viewers.styles(title, "normal") -- "value from MediaWiki"
    			elseif o.is_function then t = t .. viewers.styles(title, "error") -- "MediaWiki library"
    			elseif o.hasi18n then t = t .. viewers.styles(title, "add bold") -- "central module or library"
    			elseif o.is_table then t = t .. viewers.styles(title, "add") -- "MediaWiki library"
    			else t = t .. "<b>[ " .. tostring(title) .. " ]</b> " end -- others
    			t = t .. ", "
    		end
    	end
    	hh = hh .. "\n* Styles for objects types: " ..viewers.styles("central library", "add bold")..", "
    	hh = hh .. viewers.styles("library", "add")..", " ..viewers.styles("function", "error")..", " ..viewers.styles("track", "discreet")..", "
    	hh = hh .. "<b>[ others ]</b>, " .. viewers.ta("objects number", lua_table.level_count(sort_key) )
    	return t
    end -- function versions.versions_management_report(versions)
    
    function versions.all_G_and_loaded_list(t) -- List all objects in _G global space and in package.loaded
    	local memo = viewers.save_configs("versions.all_G_and_loaded_list") -- Save global configuration before eventual changes.
    	local t, tt, listobjs = "", "", "" -- t or "\n* <b>versions.all_G_and_loaded_list()</b> List all objects in _G global space and in package.loaded. "
    	local function sort_and_list_objects(obj_to_list)
    		local t, listobjs, sorted_objects = "", "", {}
    		if (type(obj_to_list) ~= "table") then return " * NO TABLE OF OBJECTS * ", t end
    		for key, obj in pairs(obj_to_list) do table.insert( sorted_objects, { ["key"] = tostring(key), ["obj"] = obj } ) end
    		if lua_table.level_count(sorted_objects) > 0 then
    			table.sort(sorted_objects, function (a, b) return (a.key < b.key) end ) -- alphabetic sort of objects keys
    			for i, elem in pairs(sorted_objects) do
    				local title = elem.key -- obj_to_list[key]
    				local obj = elem.obj -- obj_to_list[key]
    			--	viewers.styles_colors = "add delete discreet error invoke normal warning wikidata"
    			--	viewers.styles_formats = "big bold small up"
    				local o = versions.get_one_module_or_library(obj, obj) -- (objt, title) Get checked values and types of central objects
    				if o.is_table and (type(obj.add) == "function") then t = t .. viewers.styles(title, "discreet") -- function tracker.initadd() styles
    				elseif o.is_string then t = t .. viewers.styles(title, "normal") -- "value from MediaWiki"
    				elseif o.is_function then t = t .. viewers.styles(title, "error") -- "MediaWiki library"
    				elseif o.hasi18n then t = t .. viewers.styles(title, "add bold") -- "central module or library"
    				elseif o.is_table then t = t .. viewers.styles(title, "add") -- "MediaWiki library"
    				else t = t .. "<b>[ " .. tostring(title) .. " ]</b> " end -- others
    				t = t .. ", "
    			end
    		else return " * EMPTY TABLE OF OBJECTS * " end
    		listobjs = listobjs .. "\n* Styles for objects types: " ..viewers.styles("central library", "add bold")..", "
    		listobjs = listobjs .. viewers.styles("library", "add")..", " ..viewers.styles("function", "error")..", " ..viewers.styles("track", "discreet")..", "
    		listobjs = listobjs .. "<b>[ others ]</b>, " .. viewers.ta("objects number", lua_table.level_count(sorted_objects) )
    		return listobjs, t
    	end
    	listobjs, tx = sort_and_list_objects(_G)
    	t = t .. "\n* Objects in <b>_G</b> global space: " .. listobjs ..	 "<br>" .. tx
    	listobjs, tx = sort_and_list_objects(package.loaded)
    	t = t .. "\n* Objects in <b>package.loaded</b>: " .. listobjs .. "<br>" .. tx
    	viewers.restore_configs(memo, "versions.all_G_and_loaded_list") -- Restore global configurations after eventual changes.
    	return t
    end -- function versions.all_G_and_loaded_list(t)
    
    function versions.central_library(objt, title) -- Get checked values and types of central objects
    	local o = {}
    	local i18n = langs.main_i18n or versions.main_i18n or versions.memo_i18n
    	o.val = objt
    	if (title == objt) then
    		-- Look at the object without any change
    	else -- try to require() the object
    		if type(o.title) ~= "string" then
    			local frame = mw.getCurrentFrame()
    			o.title = frame:getTitle() -- get the main module name
    		end
    	end
    	o.is_nil = (o.type == "nil")
    	o.type = type(o.val)
    	o.is_number = (type(o.val) == "number")
    	if o.is_number then o.number = o.val ; return o else o.number = nil end -- o.number =
    	o.is_string = (type(o.val) == "string")
    	if o.is_string then o.table = o.val ; return o else o.table = nil end -- o.string =
    	o.is_table = (type(o.val) == "table")
    	if o.is_table then
    		o.table = o.val
    		o.title = o.table.libname or o.table.name -- like Module:Author, or the versioning library
    		o.ModuleNS = mw.site.namespaces.Module.name .. ":"
    	else o.table = nil end -- o.table =
    	-- Module or Library
    	if (type(o.title) == "string") then
    		o.title = string.find( o.title, versions.ModuleNS, 1, true)
    	end
    	if o.table and not o.title and (type(o.table.infos) == "table") then
    		o.title = o.table.libname or o.table.name or o.table.infos.libname or o.table.infos.name -- i18n langs
    	end
    	o.is_function = (type(o.val) == "function")
    	if o.title then
    		if o.is_function then o.func = o.val ; return o else o.func = nil end -- o.function =
    		o.is_module = o.is_table and (1 == string.find( o.title, versions.ModuleNS, 1, true) ) -- true if the object is a library
    		if o.is_module then o.module = o.val else o.module = nil end -- o.module =
    		o.is_loaded = o.val and ( o.val == package.loaded[o.title] )
    		o.is_G = o.val and ( o.val == _G[o.title] )
    		o.is_library = o.is_table and not (string.find( o.title, versions.ModuleNS, 1, true) ) -- true if the object is a library
    		if o.is_library then o.library = o.val else o.library = nil end
    		o.hasi18n = o.is_table and (type(o.val.i18n) == "table") -- i18n langs
    		if o.hasi18n then o.i18n = o.val.i18n else o.i18n = nil end -- o.i18n =
    		if o.is_library and o.hasi18n then o.is_central_library = true end -- o.i18n =
    		o.isI18N = true and string.find( o.title, "/I18N") -- true if the title contains /I18N		like Module:Author/I18N
    	end
    	return o
    end -- function versions.central_library(objt, title)
    
    function versions.all_G_and_loaded_list(t) -- List all objects in _G global space and in package.loaded
    	local memo = viewers.save_configs("versions.all_G_and_loaded_list") -- Save global configuration before eventual changes.
    	local t, tt, listobjs = "", "", "" -- t or "\n* <b>versions.all_G_and_loaded_list()</b> List all objects in _G global space and in package.loaded. "
    	local function sort_and_list_objects(obj_to_list)
    		local t, listobjs, sorted_objects = "", "", {}
    		if (type(obj_to_list) ~= "table") then return " * NO TABLE OF OBJECTS * ", t end
    		for key, obj in pairs(obj_to_list) do table.insert( sorted_objects, { ["key"] = tostring(key), ["obj"] = obj } ) end
    		if lua_table.level_count(sorted_objects) > 0 then
    			table.sort(sorted_objects, function (a, b) return (a.key < b.key) end ) -- alphabetic sort of objects keys
    			for i, elem in pairs(sorted_objects) do
    				local title = elem.key -- obj_to_list[key]
    				local obj = elem.obj -- obj_to_list[key]
    			--	viewers.styles_colors = "add delete discreet error invoke normal warning wikidata"
    			--	viewers.styles_formats = "big bold small up"
    				local o = versions.central_library(obj, obj) -- (objt, title) Get checked values and types of central objects
    				if o.is_table and (type(obj.add) == "function") then t = t .. viewers.styles(title, "discreet") -- function tracker.initadd() styles
    				elseif o.is_string then t = t .. viewers.styles(title, "normal") -- "value from MediaWiki"
    				elseif o.is_function then t = t .. viewers.styles(title, "error") -- "MediaWiki library"
    				elseif o.hasi18n then t = t .. viewers.styles(title, "add bold") -- "central module or library"
    				elseif o.is_table then t = t .. viewers.styles(title, "add") -- "MediaWiki library"
    				else t = t .. "<b>[ " .. tostring(title) .. " ]</b> " end -- others
    				t = t .. ", "
    			end
    		else return " * EMPTY TABLE OF OBJECTS * " end
    		listobjs = listobjs .. "\n* Styles for objects types: " ..viewers.styles("central library", "add bold")..", "
    		listobjs = listobjs .. viewers.styles("library", "add")..", " ..viewers.styles("function", "error")..", " ..viewers.styles("track", "discreet")..", "
    		listobjs = listobjs .. "<b>[ others ]</b>, " .. viewers.ta("objects number", lua_table.level_count(sorted_objects) )
    		return listobjs, t
    	end
    	listobjs, tx = sort_and_list_objects(_G)
    	t = t .. "\n* Objects in <b>_G</b> global space: " .. listobjs ..	 "<br>" .. tx
    	listobjs, tx = sort_and_list_objects(package.loaded)
    	t = t .. "\n* Objects in <b>package.loaded</b>: " .. listobjs .. "<br>" .. tx
    	viewers.restore_configs(memo, "versions.all_G_and_loaded_list") -- Restore global configurations after eventual changes.
    	return t
    end -- function versions.all_G_and_loaded_list(t)
    
    function versions.delay_time(t1, t2, diff) -- Compute the delay from t1 to t2, or adjust t2 at t1 + diff.
    	local t1, t2, diff = tostring(t1), tostring(t2), tostring(diff)
    	local t = t or "\n* <b>versions.delay_time()</b> Compute the delay from t1 to t2, or adjust t2 at t1 + diff."
    	-- Adjust year+- month+- day+- h+- min+- s+- until OK.
    	return t1, t2, diff, t
    --	local t1, t2, diff, t = versions.delay_time(t1, t2, diff)
    end -- function versions.delay_time(t1, t2, diff)
    
    function versions.is_ISO_8601_time_format_like(time_in, form) -- Compute the delay from t1 to t2, or adjust t2 at t1 + diff.
    --	See ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 heures de décalage) = 1977-04-22T06:00:00Z local time
    	local nowtime = os.date("%Y-%m-%d %H:%M:%S") -- in ISO 8601 time format like : 1977-04-22T01:00:00
    	local nowtable = os.date("*t") or {} -- in ISO 8601 time format like : 1977-04-22T01:00:00
    	local nowclock_rest = os.clock(nowtable) or {} -- seconds from time 00:00
    	if nowtable.day then
    		local nowclock = {} -- seconds from time 00:00
    		nowclock.second = math.floor(nowclock_rest / 60) ; nowclock_rest = nowclock_rest - (nowclock.second * 60) ;
    		nowclock.minute = math.floor(nowclock_rest / 60) ; nowclock_rest = nowclock_rest - (nowclock.minute * 60) ;
    		nowclock.hour	= math.floor(nowclock_rest / 24) ; nowclock_rest = nowclock_rest - (nowclock.hour * 24)	  ;
    		nowtable.hour = nowclock.hour ; nowtable.minute = nowclock.minute ; nowtable.second = nowclock.second ;
    	--	if nowclock.minute < 10 then nowclock.minute = "0" .. nowclock.minute end
    	--	if nowclock.hour < 10	then nowclock.hour	 = "0" .. nowclock.hour end
    		if nowtable.day < 10	then nowtable.day	 = "0" .. nowtable.day end
    		if nowtable.month < 10	then nowtable.month	 = "0" .. nowtable.month end
    		if nowtable.year < 10	then nowtable.year	 = "0" .. nowtable.year end
    		if nowtable.year < 100	then nowtable.year	 = "0" .. nowtable.year end
    		if nowtable.year < 1000 then nowtable.year	 = "0" .. nowtable.year end
    		nowtime = nowtable.year .."-"..nowtable.month .."-"..nowtable.day .."-"..nowtable.hour .."-"..nowtable.minute .."-"..nowtable.second
    	end
    	--	See: http://www.lua.org/manual/5.1/manual.html#pdf-os.date
    	--	If format starts with '!', then the date is formatted in Coordinated Universal Time. After this optional character, if format is the string "*t", then date returns a table with the following fields: year (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), and isdst (daylight saving flag, a boolean).
    	local form = form or "1789-12-31T23:59:55-11:44"
    	if (type(time_in) ~= "string") then time_in = nowtime end
    	if not time_in then time_in = nowtime end
    	local startime = "2017-05-14 00:00:00"
    	local form = string.gsub(form, "44", string.sub(startime, 15, 16) ) -- shift_minute, 00 for UTC
    	local form = string.gsub(form, "11", string.sub(startime, 15, 16) ) -- shift_hour, 00 for UTC
    	local form = string.gsub(form, "55", string.sub(startime, 15, 16) ) -- second
    	local form = string.gsub(form, "59", string.sub(startime, 15, 16) ) -- minute
    	local form = string.gsub(form, "23", string.sub(startime, 12, 13) ) -- hour
    	local form = string.gsub(form, "31", string.sub(startime, 9, 10) ) -- day
    	local form = string.gsub(form, "12", string.sub(startime, 6,  7) ) -- month
    	local time_out = string.gsub(form, "1789", string.sub(startime, 1, 4) ) -- year
    	return time_out, nowtime
    end --	local time_out, nowtime = versions.is_ISO_8601_time_format_like(time, form)
    
    function versions.MediaWiki_version() -- Formats MediaWiki_version, in error color if it changes.
    	local currentVersion = tostring(mw.site.currentVersion)
    	local vers, time, color, discreet, currentview = "0.0", "0000", "color", "discreet", "currentview"
    	for k, vrs in pairs( versions.MediaWiki_Versions ) do
    		if vrs.verstime > time then
    			time = vrs.verstime
    			vers = vrs.versid
    		end
    	end -- typical record:
    --	{ site = "fr.wikisource", verstime = "2018-02-16T01:11:36", versid = "1.31.0-wmf.21 (828e6cc)", seen_time = "2018-02-18T05:17:00", },
    	color = viewers.styles_color_error(currentVersion)
    	discreet = viewers.styles_color_discreet(currentVersion)
    	currentview = currentVersion
    	if currentVersion ~= versions.MediaWiki_version_memo then currentview = color end
    	currentview = viewers.ta("[[ Special:Version | Local MediaWiki version ]]", currentview .. " time=" .. time)
    	versions.MediaWiki_version_memo = vers
    	versions.MediaWiki_version_time = time
    	versions.MediaWiki_version_color = color
    	versions.MediaWiki_version_discreet = discreet
    	versions.MediaWiki_version_currentview = currentview
    	return currentview
    end -- function versions.MediaWiki_version()
    
    function versions.wiki_modules_users_stat() -- Modules, users and stats in this wiki.
    	local mwuri = mw.uri.new()
    	local t = ""
    	-- Main module version
    	t = t .. "\n*. <b>Modules</b>: "
    	t = t .. viewers.ta("Main module", tostring(versions.mainversion) )
    	t = t .. viewers.ta("Proto version", tostring(Central.version.versionName ) )
    	t = t .. viewers.ta("Modules in this wiki", tostring(mw.site.stats.pagesInNamespace( 828 ) ) )
    	-- Central module version
    	t = t .. "\n*. <b>Central module version</b>: "
    	local VersCentral = Central.version -- Get the Central.version details
    	t = t .. viewers.ta("versionName", tostring(VersCentral.versionName) )
    	t = t .. viewers.ta("versionNumber", tostring(VersCentral.versionNumber) )
    	t = t .. viewers.ta("versionDate", tostring(VersCentral.versionDate) )
    	t = t .. viewers.ta("taskDescription", tostring(VersCentral.taskDescription) )
    	-- Users
    	t = t .. "<br/>\n* <b>Users activities</b>: "
    	t = t .. viewers.ta("activeUsers", tostring(mw.site.stats.activeUsers ) )
    	t = t .. viewers.ta("Administrators(sysop)", tostring(mw.site.stats.usersInGroup( "sysop" ) ) )
    	t = t .. viewers.ta("bots(bot)", tostring(mw.site.stats.usersInGroup( "bot" ) ) )
    	t = t .. viewers.ta("patrollers(patroller)", tostring(mw.site.stats.usersInGroup( "patroller" ) ) )
    	t = t .. viewers.ta("bureaucrats(bureaucrat)", tostring(mw.site.stats.usersInGroup( "bureaucrat" ) ) )
    	t = t .. "\n* [[Special:Statistics | Statistics on users and content]] "
    	t = t .. " mw [[:mw:Special:ListGroupRights]] " -- https://www.MediaWiki.org/wiki/Special:ListGroupRights
    	-- Wivivi : Where vikipedia is read in which language ? https://stats.wikimedia.org/wikimedia/animations/pageviews/wivivi.html
    	t = t .. "\n* [https://stats.wikimedia.org/wikimedia/animations/pageviews/wivivi.html <b>Wivivi</b>: In which language do you read Wikipedia?] "
    	-- Last revision
    	t = t .. "<br/>\n* <b>Last revision</b>: "
    	t = t .. viewers.ta("REVISIONTIMESTAMP", modes.frame:preprocess( "{{REVISIONTIMESTAMP}}" ) )
    	t = t .. viewers.ta("REVISIONUSER", modes.frame:preprocess( "{{REVISIONUSER}}" ) )
    	-- Languages
    	t = t .. "<br/>\n* <b>Languages</b>: "
    	t = t .. viewers.ta("PAGELANGUAGE", modes.frame:preprocess( "{{PAGELANGUAGE}}" ) )
    --		t = t .. viewers.ta("PAGELANGUAGE", mw.getCurrentFrame():expandTemplate{ title = 'PAGELANGUAGE' } ) https://gerrit.wikimedia.org/r/#/c/189324/
    	t = t .. viewers.ta("CONTENTLANGUAGE", modes.frame:preprocess( "{{CONTENTLANGUAGE}}" ) )
    	--
    	t = t .. "\n* <b>User language</b>: "
    	-- T173207: Implement Lua alternative to {{int:Lang}}.
    	t = t .. viewers.ta("⧼Lang⧽", "⧼Lang⧽" )
    	t = t .. viewers.ta("⧼es⧽", "⧼es⧽" )
    	-- https://fr.wikisource.org/w/index.php?title=MediaWiki:Lang/en&action=edit
    	-- https://vi.wikipedia.org/w/index.php?title=MediaWiki:Lang/en&action=edit
    	-- To support {{int:Lang}} for central modules. Equivalent to calling mw.getCurrentFrame():preprocess("{{int:Lang}}") in Lua.
    	t = t .. viewers.ta("{{int:Lang}}", modes.frame:preprocess( "{{int:Lang}}" ) )
    	t = t .. viewers.ta("USERLANG", modes.frame:preprocess( "{{USERLANG}}" ) )
    	t = t .. viewers.ta("UILANGCODE", modes.frame:preprocess( "{{UILANGCODE}}" ) )
    	t = t .. viewers.ta("USERLANG", modes.frame:preprocess( "{{USERLANG}}" ) )
    	t = t .. viewers.ta("USERLANGUAGE", modes.frame:preprocess( "{{USERLANGUAGE}}" ) )
    	t = t .. viewers.ta("USERIFCODE", modes.frame:preprocess( "{{USERIFCODE}}" ) )
    	t = t .. "\n* <b>Scribunto</b>: "
    	t = t .. ", [[ mw:Extension:Scribunto | Extension:Scribunto ]]"
    	t = t .. viewers.ta("[http://tylerneylon.com/a/learn-lua/ Lua] [[ mw:Extension:Scribunto/Lua_reference_manual | manual ]], [http://www.lua.org/manual/5.1/manual.html version] : ", _VERSION )
    	--
    	t = t .. "\n* <b>Server mw.uri.new</b>: "
    	t = t .. viewers.ta("protocol", mwuri.protocol )
    	t = t .. viewers.ta("user", mwuri.user )
    	t = t .. viewers.ta("password", mwuri.password )
    	t = t .. viewers.ta("main_title", modes.main_title )
    	t = t .. viewers.ta("label", mwuri.label )
    --	local label = modes.args_final.label or modes.main_title or modes.args_final.QITEM or modes.args_final.itemid
    	t = t .. viewers.ta("text", mwuri.text )
    	t = t .. viewers.ta("host", mwuri.host )
    	t = t .. viewers.ta("port", mwuri.port )
    	t = t .. viewers.ta("path", mwuri.path )
    	t = t .. viewers.ta("query", mwuri.query )
    	t = t .. viewers.ta("fragment", mwuri.fragment )
    	t = t .. viewers.ta("userInfo", mwuri.userInfo )
    	t = t .. viewers.ta("hostPort", mwuri.hostPort )
    	t = t .. viewers.ta("authority", mwuri.authority )
    	t = t .. viewers.ta("queryString", mwuri.queryString )
    	t = t .. viewers.ta("relativePath", mwuri.relativePath )
    --	t = t .. mwuri:parse( "uri:parse : user, ( userInfo ), host-Port = hostPort" )
    	return t
    end -- function versions.wiki_modules_users_stat(t)
    
    function versions.running_times(no_view, res, time1, time2, time3, time4) -- Formats running times and references for Lua-coders.
    	-- Last update example:
    	-- Execution time and page: 2017-04-27 10:01:50 UTC , url = https://fr.wikisource.org/wiki/Module:Centralizer-s-fr/Documentation
    	-- Running times: , start in page = 171 mS , import + 0 mS , form result + 0 mS , tests + 522 mS , duration = 522 mS
    	local res = "" -- res or "\n* versions.running_times() Modules, users and stats in this wiki"
    	res = res .. "\n* <b>" .. viewers.form9user("versions_running_times_title") .. "</b>"
    	-- "\n* versions.running_times() Temps d'exécution et références pour les Lua-codeurs."
    	local mwuri = mw.uri.new()
    	res = res .. "\n* " .. versions.MediaWiki_version() -- Modules, users and stats in this wiki.
    	res = res .. "\n* " .. versions.wiki_modules_users_stat() -- Modules, users and stats in this wiki.
    	modes.time4 = os.clock()
    	if no_view then return default_res end
    	local time4 = time4 or modes.time4
    	local time3 = time3 or modes.time3 or time4
    	local time2 = time2 or modes.time2 or time3
    	local time1 = time1 or modes.time1 or time2
    	if time2 < time1 then time2 = time1 end
    	if time3 < time2 then time3 = time2 end
    	if time4 < time3 then time4 = time3 end
    	local nowtime = os.date("%Y-%m-%d %H:%M:%S")
    	local mwtitle = mw.title.getCurrentTitle()
    	local url = tostring(mwtitle:canonicalUrl( ))
    	local time2d = time2 - time1
    	local time3d = time3 - time2
    	local time4d = time4 - time3
    	local duration = time2d + time3d + time4d
    	time1  = tostring(math.floor( time1	 * 1000 )) .. " mS"
    	time2d = tostring(math.floor( time2d * 1000 )) .. " mS"
    	time3d = tostring(math.floor( time3d * 1000 )) .. " mS"
    	time4d = tostring(math.floor( time4d * 1000 )) .. " mS"
    	duration = tostring(math.floor( duration * 1000 )) .. " mS"
    	res = res .. "\n* <b>Execution time and page</b>: " .. nowtime .. " UTC, " .. viewers.ta("url", url) -- prefixedText
    	res = res .. "\n* <b>Running times</b>: "
    	res = res .. viewers.ta("start in page", time1) .. viewers.ta("import", time2d, "+")
    	res = res .. viewers.ta("form result", time3d, "+") .. viewers.ta("tests", time4d, "+") .. viewers.ta("duration", duration)
    --	Inside the viewer drop_box.form(), a function in test or in report has a nil result
    	return res
    end -- function versions.running_times(no_view, res, time1, time2, time3, time4)
    
    --	cut_libraries
    
    
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    --	The Library:viewers supports Lua-coders sub-tasks and inter-wikis central modules.
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    
    --	These Module:Centralizer/I18N translations for viewers library update and complete Module:Centralizer translations.
    viewers.i18n = {}
    viewers.i18n.br = {
    	-- Principaux textes, erreurs et catégories des outils
    	viewers_test_no_values					= "Test: sans valeurs",
    	viewers_test_the_value_is_table			= "Test: la valeur est une table",
    	viewers_test_all_types_values			= "Test: valeurs de tous types",
    	viewers_Dropbox_label_Unwrap			= "Dérouler/Enrouler",
    	viewers_page_tests_title				= "Tests et informations liées à cette page :",
    	viewers_section_title_page				= "Tests de cette page",
    	viewers_section_title_module			= "Tests de ce module",
    	viewers_section_title_internal			= "Tests internes",
    --	Ne pas traduire ces noms de bibliothèques
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "Cette section manque de titre",
    	viewers_dropdown_missing_title			= "Titre manquant pour cette boite déroulante",
    	-- Titres des tests
    	viewers_page_tests_title				= "Tests et informations liées à cette page :",
    	viewers_module_tests_title				= "Tests et informations liées à ce module :",
    	viewers_internal_tests_title			= "Tests internes de non régression :",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Test: former un tableau avec lignes et colonnes.",
    	viewers_tab_view_form_elem_detail		= "détail = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Erreur interne: tableview.new() échec anormal.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Tests de codage et conversions de dates",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Tests de date vers jour, mois, année ou ère",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Test: Trier une liste de mots sans répétition",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Test: sauver et restaurer, équilibre des configurations",
    	viewers_save_restore_balance_headers	= "i; où; enregistre; restaure; erreurs",
    } -- viewers.i18n.br
    viewers.i18n.de = {
    	-- Haupttexte, Fehler und Kategorien von Werkzeugen
    	viewers_test_no_values					= "Test: ohne Werte",
    	viewers_test_the_value_is_table			= "Test: Der Wert ist eine Tabelle",
    	viewers_test_all_types_values			= "Test: Werte aller Arten",
    	viewers_Dropbox_label_Unwrap			= "Erweitern / Wrap",
    	viewers_page_tests_title				= "Tests und Informationen zu dieser Seite:",
    	viewers_section_title_page				= "Tests dieser Seite",
    	viewers_section_title_module			= "Tests dieses Moduls",
    	viewers_section_title_internal			= "Interne Tests",
    --	Übersetzen Sie diese Bibliotheken nicht
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "Dieser Abschnitt fehlt der Titel",
    	viewers_dropdown_missing_title			= "Titel fehlt für diese Dropdown-Box",
    	-- Titel der Tests
    	viewers_page_tests_title				= "Tests und Informationen zu dieser Seite:",
    	viewers_module_tests_title				= "Tests und Informationen zu diesem Modul:",
    	viewers_internal_tests_title			= "Interne Regressionstests:",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Test: Bilden Sie eine Tabelle mit Zeilen und Spalten.",
    	viewers_tab_view_form_elem_detail		= "Detail = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Interner Fehler: tableview.new() abnormaler Fehler.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Codierungstests und Datumskonvertierungen",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Datum Tests zu Tag, Monat, Jahr oder Zeit",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Test: Sortiere eine Liste von Wörtern ohne Wiederholung",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Test: Speichern und Wiederherstellen, Balance der Konfigurationen",
    	viewers_save_restore_balance_headers	= "i; wo; registrieren; wiederherzustellen; Fehler",
    } -- viewers.i18n.de
    viewers.i18n.en = {
    	-- Main string, errors and categories of tools
    	viewers_test_no_values					= "Test: without values",
    	viewers_test_the_value_is_table			= "Test: the value is a table",
    	viewers_test_all_types_values			= "Test: values of all types",
    	viewers_Dropbox_label_Unwrap			= "Unwrap/Wrap",
    	viewers_page_tests_title				= "Testing and information related to this page:",
    	viewers_section_title_page				= "Tests of this page",
    	viewers_section_title_module			= "Tests of this module",
    	viewers_section_title_internal			= "Internal tests",
    --	Do not ranslate these libraries names
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_dropdown_missing_title			= "Missing title for this drop_box",
    	-- Titles of tests
    	viewers_module_tests_title				= "Testing and information related to this module:",
    	viewers_internal_tests_title			= "Internal regression tests:",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Test: Formats a table with lines and columns.",
    	viewers_tab_view_form_elem_detail		= "detail = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Internal error : tableview.new() abnormal fail.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Tests of coding and conversion of dates",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Tests of date to day, month, year or era",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Test: Sort a list of words without repetition",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Test: save and restore, balance of configurations",
    	viewers_save_restore_balance_headers	= "i;where;save;restore;errors",
    } -- viewers.i18n.en
    viewers.i18n.es = {
    	-- Textos principales, errores y categorías de instrumentos
    	viewers_test_no_values					= "Prueba: sin valores",
    	viewers_test_the_value_is_table			= "Prueba: el valor es una tabla",
    	viewers_test_all_types_values			= "Prueba: valores de todos los tipos",
    	viewers_Dropbox_label_Unwrap			= "Desenvolver/Envolver",
    	viewers_page_tests_title				= "Pruebas y información relacionada con esta página:",
    	viewers_section_title_page				= "Pruebas de esta página",
    	viewers_section_title_module			= "Pruebas de esta módulo",
    	viewers_section_title_internal			= "Pruebas internas",
    --	No traduzca estos nombres de bibliotecas
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "This section misses of title",
    	viewers_dropdown_missing_title			= "Falta el título para este drop_box",
    	-- Titres des pruebas
    	viewers_page_tests_title				= "Pruebas y información relacionada con esta página:",
    	viewers_module_tests_title				= "Pruebas y información relacionada con esto módulo:",
    	viewers_internal_tests_title			= "Pruebas de no regresión internas:",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Prueba: Formar una tabla con líneas y columnas.",
    	viewers_tab_view_form_elem_detail		= "detalle = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Error interno: tableview.new() error anormal.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Pruebas de codificación y conversión fechas",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Pruebas de fecha a día, mes, año o época",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Prueba: Ordenar una lista de palabras sin repetición",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Prueba: guardar y restaurar, equilibrio de configuraciones",
    	viewers_save_restore_balance_headers	= "i; dónde; guardar; restaurar; errores",
    } -- viewers.i18n.es
    viewers.i18n.fr = {
    	-- Principaux textes, erreurs et catégories des outils
    	viewers_test_no_values					= "Test: sans valeurs",
    	viewers_test_the_value_is_table			= "Test: la valeur est une table",
    	viewers_test_all_types_values			= "Test: valeurs de tous types",
    	viewers_Dropbox_label_Unwrap			= "Dérouler/Enrouler",
    	viewers_page_tests_title				= "Tests et informations liées à cette page :",
    	viewers_section_title_page				= "Tests de cette page",
    	viewers_section_title_module			= "Tests de ce module",
    	viewers_section_title_internal			= "Tests internes",
    --	Ne pas traduire ces noms de bibliothèques
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "Cette section manque de titre",
    	viewers_dropdown_missing_title			= "Titre manquant pour cette boite déroulante",
    	-- Titres des tests
    	viewers_page_tests_title				= "Tests et informations liées à cette page :",
    	viewers_module_tests_title				= "Tests et informations liées à ce module :",
    	viewers_internal_tests_title			= "Tests internes de non régression :",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Test: former un tableau avec lignes et colonnes.",
    	viewers_tab_view_form_elem_detail		= "détail = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Erreur interne: tableview.new() échec anormal.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Tests de codage et conversions de dates",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Tests de date vers jour, mois, année ou ère",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Test: Trier une liste de mots sans répétition",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Test: sauver et restaurer, équilibre des configurations",
    	viewers_save_restore_balance_headers	= "i; où; enregistre; restaure; erreurs",
    } -- viewers.i18n.fr
    viewers.i18n.hu = {
    	-- Principaux textes, erreurs et catégories des outils
    	viewers_test_no_values					= "Teszt: érték nélkül",
    	viewers_test_the_value_is_table			= "Teszt: az érték egy táblázat",
    	viewers_test_all_types_values			= "Teszt: minden típusú érték",
    	viewers_Dropbox_label_Unwrap			= "Nagyítás / Wrap",
    	viewers_page_tests_title				= "Az oldalhoz kapcsolódó tesztek és információk:",
    	viewers_section_title_page				= "Az oldal tesztelése",
    	viewers_section_title_module			= "A modul tesztelése",
    	viewers_section_title_internal			= "Belső vizsgálatok",
    --	Ne fordítsa le ezeket a könyvtárak nevét
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "Ez a rész hiányzik a cím",
    	viewers_dropdown_missing_title			= "Ennek a legördülő mezőnek hiányzik a címe",
    	-- Titres des tests
    	viewers_page_tests_title				= "Az oldalhoz kapcsolódó tesztek és információk:",
    	viewers_module_tests_title				= "A modulhoz kapcsolódó tesztek és információk:",
    	viewers_internal_tests_title			= "Belső regressziós tesztek:",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Teszt: Táblázat létrehozása sorokkal és oszlopokkal.",
    	viewers_tab_view_form_elem_detail		= "részlet = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Belső hiba: tableview.new() abnormális hiba.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Kódolási tesztek és dátum konverziók",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Dátum vizsgálat napra, hónapra, évre vagy korszakra",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Teszt: Az ismétlődő szavak listájának rendezése",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Teszt: mentés és visszaállítás, konfigurációk egyensúlya",
    	viewers_save_restore_balance_headers	= "i; ahol; Regisztráljon; helyreállítása; hibák",
    } -- viewers.i18n.hu
    viewers.i18n.vi = {
    	-- Principaux textes, erreurs et catégories des outils
    	viewers_test_no_values					= "Kiểm tra: không có giá trị",
    	viewers_test_the_value_is_table			= "Kiểm tra: giá trị là một bảng",
    	viewers_test_all_types_values			= "Kiểm tra: giá trị của tất cả các loại",
    	viewers_Dropbox_label_Unwrap			= "Mở rộng / Gói",
    	viewers_page_tests_title				= "Kiểm tra và thông tin liên quan đến trang này:",
    	viewers_section_title_page				= "Kiểm tra trang này",
    	viewers_section_title_module			= "Kiểm tra mô-đun này",
    	viewers_section_title_internal			= "Kiểm tra nội bộ",
    --	Không dịch các tên thư viện này
    	viewers_section_title_library_activity	= "Library:activity",
    	viewers_section_title_library_datas		= "Library:datas",
    	viewers_section_title_library_langs		= "Library:langs",
    	viewers_section_title_library_lua_table = "Library:lua_table",
    	viewers_section_title_library_mathroman = "Library:mathroman",
    	viewers_section_title_library_modes		= "Library:modes",
    	viewers_section_title_library_versions	= "Library:versions",
    	viewers_section_title_library_wiewers	= "Library:wiewers",
    	viewers_section_title_is_missing		= "Phần này thiếu tiêu đề",
    	viewers_dropdown_missing_title			= "Thiếu tiêu đề cho hộp thả xuống này",
    	-- Tiêu đề kiểm tra
    	viewers_page_tests_title				= "Kiểm tra và thông tin liên quan đến trang này:",
    	viewers_module_tests_title				= "Kiểm tra và thông tin liên quan đến mô-đun này:",
    	viewers_internal_tests_title			= "Kiểm tra hồi quy nội bộ:",
    	viewers_tableView_default_headers		= "A; B; C; D; E",
    	viewers_tableView_tests_title			= "tableview.new() Kiểm tra: tạo thành một bảng với các hàng và cột.",
    	viewers_tab_view_form_elem_detail		= "chi tiết = <b>%1</b> | <b>%2</b> | <b>%3</b> | <b>%4</b> | %5.",
    	viewers_tableView_tests_err				= "Lỗi nội bộ: tableview.new() lỗi bất thường.",
    	viewers_format_time_tests_title			= "viewers.formatDate() Kiểm tra mã hóa và chuyển đổi ngày",
    	viewers_parts_of_date_tests_title		= "viewers.date_to_part() Kiểm tra ngày đến ngày, tháng, năm hoặc thời đại",
    	viewers_simpleList_tests_title			= "viewers.simple_list() Kiểm tra: Sắp xếp danh sách các từ không lặp lại",
    	viewers_save_restore_balance_title		= "viewers.save_restore_balance_report() Kiểm tra: lưu và khôi phục, cân bằng cấu hình",
    	viewers_save_restore_balance_headers	= "i; nơi; đăng ký; khôi phục; lỗi",
    } -- viewers.i18n.vi
    
    function viewers.is_in(word, text) -- The word is it in the text, even inside another word?
    	local bug = "Erreur Lua dans Module:Centralizer-s-fr à la ligne 7444 : attempt to call field 'find' (a nil value)."
    	local i = string.find(text or "", word or "", 1, true)
    	return (i and true)
    end
    
    function viewers.is_in_sp(word, text, sep) -- The word is it in the text, beetwen spaces or separators, not inside another word?
    	sep = sep or " " -- default separator is space. But could be * ; , or even any string.
    	if type(word) ~= "string" then word = "" end
    	if type(text) ~= "string" then text = "" end
    	local i = string.find(sep .. text .. sep, sep .. word .. sep, 1, true)
    	if i then i = true else i = false end
    	return i
    end
    
    function viewers.is_def(x) -- x is defined or no. x est défini ou non
    	return (type(x) == "string") and (x ~= "") and (x ~= " ") and (x ~= "nil")
    end
    
    function viewers.value(value, form) -- Formats a string to discribe a value like: true, 123.456, "abcd", func(), table{}.
    	local typ, view = type(value), "-" -- options: ' nonil noquote '
    	if typ == "boolean" then
    		if value == true then view = "true" else view = "false" end
    	elseif typ == "function" then view = "func()"
    	elseif typ == "number" then view = tostring(value)
    	elseif typ == "string" then
    		if viewers.is_in('noquote', form) then view = value
    		else view = '"' .. value .. '"' end
    	elseif typ == "table" then view = "table{}"
    	elseif typ == "nil" then view = "nil"
    		if viewers.is_in('nonil', form) then view = "" end
    	end
    	return view
    end -- function viewers.value(value, form)
    
    function viewers.phab_task(task, comment) -- Forms a link to a Phabricator task.
    	local t = "" -- example: "[[phab:T135845|T135845 Convert]]"
    	if ( type(comment) ~= "string" ) then comment = "" end
    	-- The task id is a string with "T" and a number. We check this syntax:
    	if ( type(task) == "string" ) and ( string.find("T", "%s", 1, true) == 1 ) and tonumber( string.sub( s, 2, -1 ) ) then task = task else task = "T000" end
    	t = "[[phab:" .. task .. "|" .. task .. " " .. comment .. "]]"
    	return t -- replace anywhere : "[[phab:" by "viewers.phab_task(task, comment)" then update all
    end -- t = t .. ;viewers.phab_task(task, comment) -- Forms a link to a Phabricator task.
    
    function viewers.ta(txt, val, sep) -- Formats an argument and its value in a documentation. The text is "nil" if the value is nil.
    	if val == nil then val = "nil" end
    	if sep == nil then sep = "=" end
    	return tostring(txt) .. " " .. tostring(sep) .. " <b>" .. tostring(val) .. "</b> " .. ", "
    end
    
    function viewers.tam(txt, val, sep) -- Formats an argument and its value, or mask it if nil.
    	if not val then return "" end
    	return viewers.ta(txt, val, sep)
    end
    
    -- Fonctional styles in central modules.
    viewers.usual_colors = { -- Available usual fonctional styles for central modules and those using them.
    	["add"]		= "blue",		-- Usual fonctional style for add in blue; blue/yellow are more accessible, see T156048.
    	["delete"]	= "#C0C000",	-- Usual fonctional style for delete in yellow; blue/yellow are more accessible, see T156048.
    	["discreet"]= "#B0B0B0",	-- Usual fonctional style for discreet in light grey.
    	["error"]	= "#AA6688",	-- Usual fonctional style for error in modified red.
    	["invoke"]	= "#804020",	-- Usual fonctional style for invoke args in brown.
    	["mask"]	= "white",		-- Usual fonctional style for mask standard in white.
    	["normal"]	= "black",		-- Usual fonctional style for other standard in black.
    	["warning"] = "#804020",	-- Usual fonctional style for warnings in brown.
    	["wikidata"]= "green",		-- Usual fonctional style for wikidata in green.
    }
    viewers.usual_colors_memo = "add delete discreet error invoke mask normal warning wikidata"
    
    function viewers.usual_color(t, usual) -- Fonctional style for available usual cases.
    	if type(usual) ~= "string" then usual = "normal" end
    	local t = tostring(t)
    	-- template style:		'<span style="color:black;"									  >	  usual	  </span>' -- template style
    	local usual_in_style =	'<span style="color:' .. viewers.usual_colors["normal"] .. ';" >' .. t .. '</span>' -- default style
    	if viewers.usual_colors[usual] then -- Adapt the style of usual, if it exists.
    		  usual_in_style =	'<span style="color:' .. viewers.usual_colors[ usual	 ] .. ';" >' .. t .. '</span>' -- actual style
    	end -- Style for add in blue; blue/yellow are more accessible, see T156048.
    	return usual_in_style
    end -- function viewers.usual_color(t, usual)
    
    viewers.styles_colors = "add delete discreet error invoke normal warning wikidata"
    viewers.styles_formats = "big bold small up"
    function viewers.styles(t, styles) -- Fonctional styles for usual cases.
    	local t = tostring(t)
    	local styles_split = mw.text.split(styles, "%s")
    	for i, style in ipairs(styles_split) do
    		if viewers.is_in_sp(style, viewers.styles_colors) then
    			t = viewers.usual_color(t, style)
    		end
    		if viewers.is_in_sp(style, viewers.styles_formats) then
    			if style == "big" then t = "<big>" .. t .. "</big>" end
    			if style == "bold" then t = "<b>" .. t .. "</b>" end
    			if style == "small" then t = "<small>" .. t .. "</small>" end
    			if style == "up" then t = "<up>" .. t .. "</up>" end
    		end
    	end
    	return t
    end -- function viewers.styles(t, opt)
    
    -- These corresponding functions change the colors of a displayed text for available functional styles:
    function viewers.styles_color_add(t) return viewers.usual_color(t, "add") end
    
    function viewers.styles_color_delete(t) return viewers.usual_color(t, "delete") end
    
    function viewers.styles_color_discreet(t) return viewers.usual_color(t, "discreet") end --For attentive readers only.
    function viewers.styles_color_error(t) return viewers.usual_color(t, "error") end
    
    function viewers.styles_color_colargs(t) return viewers.usual_color(t, "colargs") end
    
    function viewers.styles_color_mask(t) return viewers.usual_color(t, "mask") end
    
    function viewers.styles_color_normal(t) return viewers.usual_color(t, "normal") end
    
    function viewers.styles_color_warning(t) return viewers.usual_color(t, "warning") end
    
    function viewers.styles_color_wikidata(t) return viewers.usual_color(t, "wikidata") end
    --	Formats also functional styles for boxes
    
    function viewers.styles_small_caps(t) -- Display a text in small-caps style.
    	return '<span style="font-variant: small-caps">' .. t .. '</span>'
    end
    
    -- Extract a part of date following a pre-defined format which starts with separator
    function viewers.date_split(date, format)
    	-- local dd, mmmm, yyyy, era = viewers.date_split(a.birthdate, " dd mmmm yyyy")
    	local dd, mmmm, yyyy, era
    	local format_split = mw.text.split(format, "%s")
    	local split = mw.text.split(date, "%s")
    	for i, date_part in ipairs(split) do
    		if format_split[i] == "dd" then dd = tonumber(date_part) end
    		if format_split[i] == "mmmm" then mmmm = date_part end
    		if format_split[i] == "yyyy" then yyyy = tonumber(date_part) end
    		if format_split[i] == "era" then era = date_part end
    	end
    	return dd, mmmm, yyyy, era
    end -- function viewers.date_split(date, format)
    
    -- Extract a part of date following a pre-defined format which starts with separator
    function viewers.date_to_part(date, part)
    	-- local t, err = viewers.date_to_part(a.birthyear, " dd mmmm yyyy", "yyyy")
    	part = part or "yyyy"
    	local dd, mmmm, yyyy, era
    	local found = false
    	--	local err = "modes_date_to_part_not_found_err"
    	if not found then
    		dd, mmmm, yyyy, era = viewers.date_split(date, "dd mmmm yyyy")
    		if dd and mmmm and yyyy and not era then
    			found = true
    		end
    	end
    	if not found then
    		dd, mmmm, yyyy, era = viewers.date_split(date, "mmmm dd yyyy")
    		if dd and mmmm and yyyy and not era then
    			found = true
    		end
    	end
    	if not found then
    		dd, mmmm, yyyy, era = viewers.date_split(date, "yyyy era")
    		if not dd and not mmmm and yyyy then
    			if era == "BCE" then yyyy = - yyyy end
    			found = true
    		end
    	end
    	if not found then
    		dd, mmmm, yyyy, era = viewers.date_split(date, "mmmm yyyy")
    		if not dd and mmmm and yyyy and not era then
    			--	modes_date_months_names				= "January, February, March, April, May, June, July, August, September, October, November, December",
    			--	modes_date_months_names				= "Enero, Febrero, Marzo, Abril, Mayo, Junio​​, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre",
    			--	modes_date_months_names				= "Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre",
    			found = true
    		end
    	end
    	if not found then
    		dd, mmmm, yyyy, era = viewers.date_split(date, "yyyy")
    		if not dd and not mmmm and yyyy and not era then
    			found = true
    		end
    	end
    	-- + cccc = roman number ?
    	if found then
    		if part == "yyyy" then return yyyy or "" end
    		if part == "mmmm" then return mmmm or "" end
    		if part == "dd" then return dd or "" end
    		if part == "era" then return era or "" end
    	end
    	return "" -- tostring(dd)..tostring(mmmm)..tostring(yyyy)..tostring(era)
    --	A faire : Titus Livius (Q2039), format de dates : P569 = date of birth = 59 BCE, P570 = date of death = 17
    --	Socrate (470-399 av. J.-C.).
    end -- function viewers.date_to_part(date, part)
    
    
    function mw.text.sortCommaList(list, sep1, sep2, sep3) -- Sort without repeat a list with separators like "Central01;versions 2.4;tools;two words"
    	versions.deprecated_function("mw.text.sortCommaList", "viewers.simple_list")
    	return viewers.simple_list(list, sep1, sep2, sep3, sep4)
    end
    
    function viewers.simple_list(list, sep1, sep2, sep3, sep4) -- Remove repeats in a string list with separators. Can also sort.
    	-- sep1 is used in final list. sep1 to sep4 can be "sort" or "trim".
    	-- wanted.
    	local t = t or ""
    	local sort, trim = false, false
    	if sep1 == "sort" then sep1 = "" ; sort = true end
    	if sep2 == "sort" then sep2 = "" ; sort = true end
    	if sep3 == "sort" then sep3 = "" ; sort = true end
    	if sep4 == "sort" then sep4 = "" ; sort = true end
    	if sep1 == "trim" then sep1 = "" ; trim = true end
    	if sep2 == "trim" then sep2 = "" ; trim = true end
    	if sep3 == "trim" then sep3 = "" ; trim = true end
    	if sep4 == "trim" then sep4 = "" ; trim = true end
    	if type(list) ~= "string" then list = "" end
    	if type(sep1) ~= "string" then sep1 = "" end -- Default separators value
    	if type(sep2) ~= "string" then sep2 = "" end
    	if type(sep3) ~= "string" then sep3 = "" end
    	if type(sep4) ~= "string" then sep4 = "" end
    --	Patterns: Dot (.) always matches all characters, including newlines.
    --	Patterns: Quantifiers (*, +, ?, and -) may only be applied to individual characters.
    	if viewers.is_in(sep1, ".*+?-/") then sep1 = "%" .. sep1 end
    	if viewers.is_in(sep2, ".*+?-/") then sep2 = "%" .. sep2 end
    	if viewers.is_in(sep3, ".*+?-/") then sep3 = "%" .. sep3 end
    	if viewers.is_in(sep4, ".*+?-/") then sep4 = "%" .. sep4 end
    	local listtab = mw.text.split(list or "", sep1, true) -- names between commas
    	local listtabOut = {}
    	local listtabSingle = {}
    	local list2 = ""
    	local t = " * t = "
    	for i, name in ipairs(listtab) do -- list all names, only one each, in alphabetic order
    		if trim then name = mw.text.trim(name) end -- do not keep spaces inside each name
    		if not listtabSingle[name] then
    			listtabSingle[name] = name
    			list2 = list2 .. name .. sep1
    		end
    	end
    	if sort then
    		table.sort(listtabSingle, function (a, b) return (a < b) end ) -- sort in alphabetic order
    	end
    	t = t .. " * list2 = " .. list2 .. " * "
    	local output = string.sub( list2, 1, (-string.len(sep1)-1) ) -- without last sep1 or ;
    	return output -- .. t
    end -- function viewers.simple_list(list, sep1, sep2, sep3)
    
    function viewers.simple_list_test(t) -- Formats whole the result for users and MediaWiki tests cases. S170801rtc
    	local memo = viewers.save_configs("viewers.simple_list_test") -- Save global configuration before eventual changes.
    	t = t or "\n* viewers.simple_list_test(t) Formats whole the result for users and MediaWiki tests cases."
    	local t, tt = t or "\n* viewers.simple_list_test(t) Tests: Formats whole the result for users and MediaWiki tests cases.", "-"
    	local tt, errors = tests_groups.errors_init(tests_groups.allstatus)
    	t = t .. "\n* ".. (tt or "*tt*")
    	local tests_groups = {}
    	tests_groups.gettests_groups_recursive_limit = 11 -- To protect against unsought loops in recursive tests_groups.
    	tests_groups.main_groupname = "mathroman.testsGroups"
    	tests_groups.main_groupname = "tests_groups.main_tests_groups"
    	local kept_groups, tt = tests_groups.gettestsgroups(tests_groups.main_groupname) -- Get groups of tests cases for MW and users.
    	tests_groups.kept_groups = kept_groups
    	t = t .. "\n* ".. (tt or "-tt-")
    	local result_cases = {}
    	local result_cases = tests_groups.getcases(kept_groups) -- Run testcases for MediaWiki.
    	tests_groups.result_cases = result_cases
    	local mw_cases, tt = tests_groups.getTestProvider(result_cases, n)
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = tests_groups,
    		tests_title	 = "tests_groups_getTestProvider_tests_title", -- Implement getTestProvider in central modules
    		headers = "tests_groups_testcase_tests_headers", -- "Digital number; Roman value; Correct; Error(s)"
    		headers = "case.name; args{}; expect{}; result{}; errors in result{} from expect{}", -- OK or error/s
    		keys = "name;args;expect;result;errors",
    		rowGroup = {},
    		ccc = {},
    	}
    	-- Runs tests cases and formats a table view with lines and columns.s
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		case = tests_groups.run_one_case(case) -- Run one case for users and MediaWiki tests cases.getTestProvider_tests
    		case.res1 = case.result[1] or "res1" -- DEBUG : mathroman.int2roman() can fail without blocking page.
    		case.err2 = case.result[case.errorsKey] or "err2" -- DEBUG : mathroman.int2roman() can fail without blocking page.
    		case.errors = case.errors or status.OK
    		case.errors = viewers.ta("case.res1", case.res1) .. viewers.ta("case.err2", case.err2) .. viewers.ta("case.errors", case.errors)
    	--	headers = "case.name; args{}; expect{}; result{}; errors in result{} from expect{}", -- OK or error/s
    		return { case.name, lua_table.rough_view(case.args), lua_table.rough_view(case.expect), lua_table.rough_view(case.result), case.errors }
    	end -- errors in result
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "viewers.simple_list_test") -- Restore global configurations after eventual changes.
    	return t
    end -- t = t .. viewers.simple_list_test(t)
    
    function viewers.simple_list_test(t) -- Test of : Sort without repeat a list with separators like "Central01;versions 2.4;tools;two words"
    	local memo = viewers.save_configs("viewers.simple_list_test") -- Save global configuration before eventual changes.
    	local t = t or ""
    	t = t .. "\n* Test <b>viewers.simple_list(list, sep1, sep2, sep3)</b>: "
    	t = t .. '\n* Remove repeats in a string list with separators. Can also sort.'
    	local function simpleList_test1(t, input, sep1, sep2, sep3, sep4)
    		local output = tostring( viewers.simple_list(input, sep1, sep2, sep3, sep4) )
    		t = t .. viewers.table_row() .. viewers.table_dat(viewers.value(input)) .. viewers.table_dat(viewers.value(sep1)) .. viewers.table_dat(viewers.value(sep2))
    		t = t .. viewers.table_dat(viewers.value(sep3)) .. viewers.table_dat(viewers.value(sep4)) .. viewers.table_dat(viewers.value(output))
    		return t
    	end
    	t = t .. viewers.table_head() .. viewers.table_col("input") .. viewers.table_col("sep1") .. viewers.table_col("sep2") .. viewers.table_col("sep3") .. viewers.table_col("sep4") .. viewers.table_col("output")
    	t = simpleList_test1(t, "abc;def;abc", ";", "-", "|")
    	t = simpleList_test1(t, "xyz;def;abc", ";", "sort")
    	t = simpleList_test1(t, "abc-def=abc", "-", "=")
    	t = simpleList_test1(t, "abc - def = abc", "-", "=", "sort")
    	t = simpleList_test1(t, "abc - def = abc", "-", "=", "sort", "trim")
    	t = simpleList_test1(t, ";;", ";", ";", ",")
    	t = simpleList_test1(t, "abc/def;abc", ";", "/")
    	t = simpleList_test1(t, "abc;def/abc/def;abc;def;abc", ";", "/", "-")
    	t = simpleList_test1(t, "abc;def;abc", ";", ";", "")
    	t = t .. viewers.table_end()
    	viewers.restore_configs(memo, "viewers.simple_list_test") -- Restore global configurations after eventual changes.
    	return t
    end -- viewers.simple_list_test(t)
    -- for _test1 search also _test1 simpleList_test1 date_to_part_test1
    
    function viewers.form_one_case(case) -- Convert a case from test_group to rowGroup.
    	case.res1 = case.result[1] or "res1" -- DEBUG : mathroman.int2roman() can fail without blocking page.
    	case.err2 = case.result[case.errorsKey] or "err2" -- DEBUG : mathroman.int2roman() can fail without blocking page.
    	case.errors = case.errors or status.OK
    	case.errors = viewers.ta("case.res1", case.res1) .. viewers.ta("case.err2", case.err2) .. viewers.ta("case.errors", case.errors)
    --	headers = "case.name; args{}; expect{}; result{}; errors in result{} from expect{}", -- OK or error/s
    	return { case.name, lua_table.rough_view(case.args), lua_table.rough_view(case.expect), lua_table.rough_view(case.result), case.errors }
    end -- errors in result
    
    function viewers.day_to_stamp(jj, mm, aaaa)
    	local t = "@" .. tostring( jj*86400 + mm*30*86400 + (aaaa-1970)*31556926 )
    	return t
    end
    
    function viewers.day_to_UTC(jj, mm, aaaa)
    	jj = tonumber(jj)
    	if not jj then jj = "2" else jj = string.sub("0000" .. tostring(jj), -2, -1 ) end
    	mm = tonumber(mm)
    	if not mm then mm = "2" else mm = string.sub("0000" .. tostring(mm), -2, -1 ) end
    	aaaa = tonumber(aaaa)
    	if not aaaa then aaaa = "2000" else aaaa = string.sub("0000" .. tostring(aaaa), -4, -1 ) end
    	return aaaa .. "-" .. mm .. "-" .. jj
    end
    
    function viewers.parts_of_date_tests(t)
    	local memo = viewers.save_configs("viewers.parts_of_date_tests") -- Save global configuration before eventual changes.
    	local function date_to_part_test1(t, nom, date, part)
    		local t = t .. viewers.table_row() .. viewers.table_dat(nom) .. viewers.table_dat(date) .. viewers.table_dat(part) .. viewers.table_dat(tostring(viewers.date_to_part(date, part)))
    		return t
    	end
    	local t = t or "\n* <b>date_to_part</b> :"
    	t = t .. "\n* Verify each value of part of date:"
    	t = t .. viewers.table_head() .. viewers.table_col("Example") .. viewers.table_col("date") .. viewers.table_col("part") .. viewers.table_col("value")
    	t = date_to_part_test1(t, "Socrate birth", "470 BCE", "era")
    	t = date_to_part_test1(t, "Tite-Live birth", "59 BCE", "yyyy")
    	t = date_to_part_test1(t, "Tite-Live death", "17", "yyyy")
    	t = date_to_part_test1(t, "empty", "", "yyyy")
    	t = date_to_part_test1(t, "Revolution", "14 July 1789", "mmmm")
    	t = date_to_part_test1(t, "Walk on Moon", "20 July 1969", " ")
    	t = date_to_part_test1(t, "English date", "July 20 1969", "yyyy")
    	t = date_to_part_test1(t, "English date", "July 20 1969", "mmmm")
    	t = date_to_part_test1(t, "Nelson Mandela birth", "July 1918", "yyyy")
    	t = date_to_part_test1(t, "Nelson Mandela death", "5 Decembre 2013", "dd")
    	t = t .. viewers.table_end()
    	-- see https://fr.wikipedia.org/wiki/Discussion:ISO_8601#Av._J.C._:_contradiction_avec_l.27article_anglais
    	-- see https://fr.wikipedia.org/w/index.php?title=ISO_8601&diff=next&oldid=12449725
    	-- see ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 heures de décalage) = 1977-04-22T06:00:00Z local time
    	-- os.date( format, time ) get datetime
    	viewers.restore_configs(memo, "viewers.parts_of_date_tests") -- Restore global configurations after eventual changes.
    	return t
    end -- function viewers.parts_of_date_tests(t)
    
    function viewers.form_image(file, size, options) -- Formats an image from its file name, to the size in pixels
    	if type(file) ~= "string" then file = "Victor Hugo.jpg" end
    	if not ( (type(size) == "string") or (type(size) == "number") ) then size = "15" end
    	if type(options) ~= "string" then options = "" end
    	return '[[File:' .. file .. '|' .. size .. 'px|' .. options .. ']]' -- options must begin with "|"
    end -- local image = viewers.form_image(file, size)
    
    function viewers.trans9vars(translations, ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string.
    	local t, S9, repl, val, charN = "", "", "", "", ""
    	if type(ref) ~= "string" then ref = "a;b;c;d;e;f;g" end
    	if type(translations) ~= "table" then
    		t = viewers.form9tests( tostring(ref), ...)
    		return t
    	end
    	if type(translations[ref]) == "string" then ref = translations[ref] end
    	args = {...}
    	t = ref
    	if lua_table.level_count(args) > 0 then
    		local n = 1
    		for n = 9, 1, -1 do
    			S9 = tostring(n)
    			charN = string.find(t, "%".. S9, 1, true)
    			if charN then -- If reference has %0 to %9
    				repl = tostring( args[n] or "" )
    				t = string.sub(t, 1, charN - 1) .. repl .. string.sub(t, charN + string.len( "%".. S9 )	 )
    			end
    		end
    	end
    	t = string.gsub(t, p.version.versionName, langs.Central_version or Central.Central_version or "versionName")
    	return t
    end -- function viewers.trans9vars(translations, key, ...)
    
    function viewers.form9tests(ref, ...) -- Formats reference_key;v1;v2;v3;... for tests.
    	local t = tostring(ref)
    	for i, var in pairs( { ... } ) do
    		if var then t = t .. ";" .. viewers.value(var) end -- tostring() or viewers.value() ?
    	end
    	return t
    end
    
    function viewers.form9en(ref, ...) -- Replace %1 to %9 by arguments. Always in english
    	if not langs.main_i18n_complete then return "" end -- Avoid to fail in init phase.
    	local t, n = "", 0
    	if type(ref) ~= "string" then t = viewers.form9tests("form9en", ...)
    	elseif type(versions.memo_i18n.en[ref] == "string") then t = viewers.trans9vars(versions.memo_i18n.en, ref, ...)
    	else t = viewers.form9tests(ref, ...) end -- Default text to help to locate a bug
    	return t
    end -- function viewers.form9en(ref, ...)
    
    function viewers.form9content(ref, ...) -- replace %1 to %9 by v1 to v9 in the content translation of ref, else in ref
    	if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures.
    	local form, n = "", 0
    	if type(ref) ~= "string" then form = viewers.form9tests("form9content", ...) end
    	if (type(langs.content_translations) == "table") then -- Only after versions.bind_reverse_i18n_translations()
    		if langs.content_translations[ref] then -- Normal case
    			form = form .. viewers.trans9vars(langs.content_translations, ref, ...)
    		elseif versions.memo_i18n.en[ref] then -- try english translation in case another lang mises of translation
    			form = form .. viewers.trans9vars(versions.memo_i18n.en, ref, ...)
    		else form = form .. viewers.form9tests(ref, ...) end
    	else form = form .. viewers.form9tests(ref, ...) end
    	return form
    end -- function viewers.form9content(ref, ...)
    
    function viewers.form9page(ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string.
    	if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures.
    	local form, n = "", 0
    	if type(ref) ~= "string" then form = viewers.form9tests("form9page", ...) end
    	local form, n = "", 0
    	if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures.
    	if (type(langs.page_translations) == "table") then -- Only after versions.bind_reverse_i18n_translations()
    		if langs.page_translations[ref] then -- Normal case
    			form = form .. viewers.trans9vars(langs.page_translations, ref, ...)
    		elseif versions.memo_i18n.en[ref] then -- try english translation in case another lang mises of translation
    			form = form .. viewers.trans9vars(versions.memo_i18n.en, ref, ...)
    		else form = form .. viewers.form9tests(ref, ...) end
    	else form = form .. viewers.form9tests(ref, ...) end
    	return form
    end -- function viewers.form9page(ref, ...)
    
    function viewers.form9user(ref, ...) -- Replace %1 to %9 by arguments, without any ambiguity in any string.
    	if not langs.main_i18n_complete then return "" end -- Avoid to fail in init phase.
    --	langs.main_i18n = langs.main_i18n or versions.main_i18n or {}
    --	versions.main_i18n = langs.main_i18n --
    	local i18n = langs.main_i18n or versions.main_i18n or versions.memo_i18n
    	if type(langs.main_i18n) ~= "table" then
    --		langs.main_i18n = versions.memo_i18n ; versions.main_i18n = versions.memo_i18n
    	end
    	local t, trans, n = "", "", 0
    	if type(ref) ~= "string" then return viewers.form9tests("form9user", ...) end
    	if (type(langs.user_translations) == "table") then -- Normal translation
    		if langs.user_translations[ref] then trans = langs.user_translations[ref] end -- Normal ref to translate
    		t = viewers.trans9vars(langs.user_translations, ref, ...)
    	elseif i18n.en[ref] then -- If a lang mises of translations, try English.
    		ref = i18n.en[ref] -- Normal ref to translate
    		t = viewers.trans9vars(i18n.en, ref, ...)
    	else t = viewers.form9tests(ref, ...) end -- Default text to help to locate a bug
    	return t
    end -- function viewers.form9user(ref, ...)
    
    function viewers.form9user_test(t) -- Tests of viewers.form9user_test().
    	local memo = viewers.save_configs("viewers.form9user_test") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>viewers.form9user_test(t, ref, ...)</b>:"
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ "translate_form9user_no_translation", },
    			{ "viewers_test_no_values", },
    			{ "translate_form9user_a_value_is_table", {}, },
    			{ "langs_form9user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" }, },
    			{ "replace: abc%1efg%2ijk", "<b>D</b>", "<b>H</b>", },
    			{ "repeat: a=%1 b=%2 c=%1 d=%2", "<b>1</b>", "<b>2</b>", },
    			{ "altern: 1%13%25", "<b>2</b>", "<b>4</b>", },
    			{ "list: %0<%1<%2<%3<%4<%5<%6<%7<%8<%9", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99", },
    			{ "mix: %1, %5, %2, %4, %3, ", "A", "B", "C", "D", "E", },
    			{ "missing args: yes=%1 no=%5 no=%9 yes=%2", "args[1]", "args[2]", },
    			{ "MATRIX 4 * 5<br>"
    			.. "{ %1%5, %1%6, %1%7, %1%8, %1%9 }<br>"
    			.. "{ %2%5, %2%6, %2%7, %2%8, %2%9 }<br>"
    			.. "{ %3%5, %3%6, %3%7, %3%8, %3%9 }<br>"
    			.. "{ %4%5, %4%6, %4%7, %4%8, %4%9 }<br>", "a", "b", "c", "d", "1", "2", "3", "4", "5", },
    		},
    		title_memo = "activity_MW_Versions_report_title",
    		headers = " input string and args; viewers.form9user_test ",
    	--	headers_class = "wikitable alternative center sortable",
    		rowGroup = {},
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local ref = case[1]
    		local form9user, t9 = viewers.form9user( lua_table.to_list(case) )
    		return { ref, form9user, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "viewers.form9user_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function viewers.form9user_test(t)
    
    function viewers.trans99vars(translations, ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string.
    	local S99, repl, val, charN
    	if type(translations) ~= "table" then return viewers.form9tests(ref, ...) end
    	if type(ref) ~= "string" then ref = "langs_translations_key_missing" end
    	if type(translations[ref]) == "string" then ref = translations[ref] end
    	args = {...}
    	if lua_table.level_count(args) > 0 then
    		local n = 1
    		for n = 99, 1, -1 do
    			S99 = tostring(n)
    			if n < 10 then S99 = "0" .. S99 end
    			charN = string.find(ref, "%".. S99, 1, true)
    			if charN then -- If reference has %01 to %99
    				repl = tostring( args[n] or "" )
    				ref = string.sub(ref, 1, charN - 1) .. repl .. string.sub(ref, charN + string.len( "%".. S99 )	)
    			end
    		end
    	end
    	return ref
    end -- function viewers.trans99vars(translations, ref, ...)
    
    function viewers.form99content(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string.
    	local form = viewers.trans99vars(langs.content_translations, ref, ...)
    	return form
    end
    
    function viewers.form99page(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string.
    	local form = viewers.trans99vars(langs.page_translations, ref, ...)
    	return form
    end
    
    function viewers.form99user(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string.
    	local form = viewers.trans99vars(langs.user_translations, ref, ...)
    	return form
    end
    
    function viewers.form99user_test(t) -- Tests of viewers.form9user_test().
    	local memo = viewers.save_configs("viewers.form99user_test") -- Save global configuration before eventual changes.
    	local t = t or "\n* <b>viewers.form99user_test(t)</b>:"
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = {
    			{ "langs_form99user_no_tranlation", },
    			{ "viewers_test_no_values", },
    			{ "langs_form99user_a_value_is_table", {}, },
    			{ "langs_form99user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" }, },
    			{ "replace: abc%01fg%02jk", "<b>DE</b>", "<b>HI</b>", },
    			{ "repeat: a=%01 b=%02 c=%01 d=%02", "<b>01</b>", "<b>02</b>", },
    			{ "altern: 01%0145%0289", "<b>23</b>", "<b>67</b>", },
    			{ "list: %00<%01<%02<%03<%04<%05<%06<%07<%08<%09", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99", },
    			{ "mix: %01, %05, %02, %04, %03, ", "A", "B", "C", "D", "E", },
    			{ "missing args: yes=%01 no=%05 no=%09 yes=%02", "args[1]", "args[2]", },
    			{ "matrix: %10<br>"
    			.. "{ %01%05, %01%06, %01%07, %01%08, %01%09 }<br>"
    			.. "{ %02%05, %02%06, %02%07, %02%08, %02%09 }<br>"
    			.. "{ %03%05, %03%06, %03%07, %03%08, %03%09 }<br>"
    			.. "{ %04%05, %04%06, %04%07, %04%08, %04%09 }<br>", "a", "b", "c", "d", "1", "2", "3", "4", "5", "MATRIX 4 * 5", },
    		},
    		title_memo = "langs_form99user_tests_title", -- "in viewers.form99user() Test: Replace %01 to &%;29 by tostring( argN ) from arguments",
    		headers = " input string and args; viewers.form9user_test ",
    	--	headers_class = "wikitable alternative center sortable",
    		rowGroup = {},
    		--	track_on = true,
    	}
    	function tab_view.form_one_case(case) -- Convert a case from test_group to rowGroup.
    		local ref = case[1]
    		local form99user, t99 = viewers.form99user( lua_table.to_list(case) )
    		return { ref, form99user, }
    	end
    	t = t .. tableview.new(tab_view) -- Runs tests cases and formats a table view with lines and columns.
    	viewers.restore_configs(memo, "viewers.form99user_test") -- Restore global configurations after eventual changes.
    	return t
    end -- function viewers.form99user_test(t)
    
    function viewers.form_main_version(main_versions)
    	if (type(main_versions) ~= "table") then main_versions = versions.main_versions end
    	if (type(main_versions) ~= "table") then main_versions = { versionName = "versionName", versionNumber = "0.0", } end
    	local t = ""
    	if type(main_versions) == "table" then
    		t = main_versions.versionName .. " " .. main_versions.versionNumber .. ", "
    	end
    	return t
    end
    
    function viewers.discreet_main_version(main_versions)
    	return viewers.styles_color_discreet( viewers.form_main_version(main_versions) )
    end
    
    function viewers.doc_section(selector, section, style, mask_sections) -- Begin of section in viewers.doc_page(), viewers.doc_module()...
    	local t = ""
    	local selector, section, style = selector, section, style
    	section = viewers.form9user(section) -- like viewers_section_title_page or viewers_section_title_internal function viewers.form9user(
    	if mask_sections then return t end
    	if selector == "never" then return t end
    	local select = (selector == true) or (selector == title) or viewers.is_in_sp(selector, "allwaysview alltestsview enforcerun failinref nocontent")
    	if type(style) ~= "string" then style = "h3" end
    	local n = tonumber( string.sub(style, 2, 2) )
    	style = "" ; for i = 1, n do style = style .. "=" end
    	t = t .. "\n" .. style .. section .. " " .. style .. "\n" -- style OK
    --	t = t .. "\n* ModuleCentralizer only tests sections doc_section"
    	return t
    end -- res = res .. viewers.doc_section(selector, "viewers_section_title_page", "h2", mask_sections) -- example
    
    function drop_box.dh( opt )
    	if (type(opt) == "string") and (type(drop_box.css_options[opt]) == "string")
    	then val = drop_box.css_options[opt] end -- val can be nil for cssview, we admit it.
    	return val
    end
    dh = drop_box.dh
    
    function drop_box.html(title, content_or_func) -- Builds the drop box at the html level.
    	local memo = viewers.save_configs("drop_box.html") -- Save global configuration before eventual changes.
    	local t = "\n* drop_box.html() -- Builds the drop box at the html level."
    	local drop_box_html = drop_box_html_start .. drop_box_html_medium .. drop_box_html_end .. drop_box_look_like
    	t = t .. drop_box_html_start .. drop_box_html_content
    	viewers.restore_configs(memo, "drop_box.html") -- Restore global configurations after eventual changes.
    	return drop_box_html_start
    end -- t = t .. drop_box.html(title, content) -- Builds the drop box at the html level.
    
    function drop_box.new_title() -- Support desk title of the docDropbox of the edit box.
    	local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("langs.main_i18n", "langs_main_i18n_languages_count", "user")
    	local report_main_discreet = viewers.styles_color_discreet( viewers.form_main_version(main_versions) )
    	local title = viewers.form9user("versions_support_desk_title", report_main_discreet, strs_on_tabs, tables_c)
    	-- "Support desk for %1 : %2 translations in %3 languages"
    	return title
    end -- function drop_box.new_title()
    
    drop_box.css_options = { -- Conventional CSS parameters : See -- https://en.wikisource.org/wiki/Template:drop_box#Parameters
    	["cssview"] = false, -- cssview : display values of options
    	["bg1"] = "#FFFFFF", -- bg1 : the background-color for the header
    	["fs1"] = "100%", -- font-size: 100%;
    	["fw1"] = "left", -- fw1 : the font-weight for the heading
    	["ta1"] = "left", -- ta1 : the text-align for the heading
    	["tc1"] = "black", -- tc1 : the text-color for the heading
    	--
    	["bg2"] = "#FFFFFF", -- bg2 : the background-color for the content
    	["fs2"] = "100%", -- font-size: 100%;
    	["fw2"] = "left", -- fw2 : the font-weight for the body
    	["ta2"] = "left", -- ta2 : the text-align for the body
    	["tc2"] = "black", -- tc2 : the text-color for the body
    }
    
    --	t  = drop_box.form(dropit.title, dropit.content, dropit)
    function drop_box.form(title, content, dropit) -- Easy drop_box style from a list of named options.
    	local memo = viewers.save_configs("drop_box.form") -- Save global configuration before eventual changes.
    	local dropit = mw.clone(dropit) -- Save global configuration before eventual changes.
    	local t = "\n* drop_box.form:"
    --	if type(content) == "function" then content = ( content(title, content, dropit) ) end -- and use it as content form function
    	t = t .. viewers.ta("title", tostring(title) )
    	t = t .. viewers.ta("content", tostring(content) )
    	t = t .. viewers.ta("dropit", tostring(dropit) )
    	if type(title) == "function" then
    		title = title() -- function drop_box.new_title()
    	elseif type(title) ~= "string" then title = "viewers_dropdown_missing_title" end
    	title = viewers.form9user(title)
    	local dropit = dropit or {}
    	t = t .. viewers.ta("\n* title", tostring(title) )
    	t = t .. viewers.ta("#dropit", lua_table.level_count(dropit) )
    	local opt = mw.clone(drop_box.css_options) -- Save global configuration before eventual changes.
    	dropit = { -- Conventional css parameters : from -- https://en.wikisource.org/wiki/Template:drop_box#Parameters
    		image = nil,
    		cssview = dropit.cssview, -- cssview : display values of options
    		fw1 = dropit.fw1 or opt.fw1, -- "left", -- fw1 : the font-weight for the heading
    		fw2 = dropit.fw2 or opt.fw2, -- "left", -- fw2 : the font-weight for the body
    		fs1 = dropit.fs1 or opt.fs1, -- "100%", -- font-size: 100%;
    		fs2 = dropit.fs2 or opt.fs2, -- "100%", -- font-size: 100%;
    		bg1 = dropit.bg1 or opt.bg1, -- "#FFFFFF", -- bg1 : the background-color for the heading
    		bg2 = dropit.bg2 or opt.bg2, -- "#FFFFFF", -- bg2 : the back.clicground-color for the body
    		ta1 = dropit.ta1 or opt.ta1, -- "left", -- ta1 : the text-align for the heading
    		ta2 = dropit.ta2 or opt.ta2, -- "left", -- ta2 : the text-align for the body
    		float = dropit.float or opt.float, -- "none", -- float : should the box be floated? (left, right, or none)
    		width = dropit.width or opt.width, -- "99%", -- width : the width of the box, e.g. 33%
    		border_radius = dropit.border_radius or opt.border_radius, -- "0px 0px 0px 0px", -- border-radius: "15px 50px 30px 5px" : add rounded corners to an element.
    		style = dropit.style or opt.style, -- "0px 0px 0px 0px", -- style : HTML/CSS affectionados only: any other css style arguments for the whole box
    		--	<div id="NavFrame10" class="NavFrame" style="clear:both; margin-bottom:1em; width:99%; border-style:solid; border-radius:0px 0px 0px 0px; border-color:#AAAAAA; background-color:#FFFFFF;" title="▼	  /▶  ">
    		hidden = dropit.hidden or opt.hidden, -- "true", -- hidden : set this to any string (e.g. hidden=true) to have the box hidden by default
    		headType = dropit.headType or opt.fw1, -- "h4", -- headType : allows you to set the box header to (say) "h4", which means it will be included in the table of contents. This is provided as an explicit parameter because if you just surround the title with header tags, e.g.	<h4>Box 1.1</h4>
    		tc1 = dropit.tc1 or opt.tc1, -- "black", -- tc1 : the text-color for the heading
    		tc2 = dropit.tc2 or opt.tc2, -- "black", -- tc2 : the text-color for the body
    		border_color = dropit.border_color or opt.border_color, -- "#AAAAAA", -- border-color : the text-color for the heading and the body
    	--	display = dropit.display or opt.display, -- "block", -- display: block : results without line break.
    		display = dropit.display or opt.display, -- "inline", -- display: inline : results with free line break.
    		margin_all = dropit.margin_all or opt.margin_all, -- "0px", -- margin
    		margin_bottom = dropit.margin_bottom or opt.margin_bottom, -- "1em", -- margin-bottom
    		--
    		height = dropit.height or opt.height, -- "1.6em", -- height
    		label = dropit.label or opt.label, -- "&#x25bc; &nbsp; /&#x25b6; &nbsp; ", -- = "Unwrap/Wrap",
    		--	▼ = &#x25bc; -- ▶ = &#x25b6; https://fr.wikipedia.org/wiki/Table_des_caract%C3%A8res_Unicode/U25A0
    		--	label = label or viewers.form9user("viewers_drop_box_label_Unwrap"), -- = "Unwrap/Wrap" translations
    	}
    	dropit.title = dropit.title or title
    	dropit.content = dropit.content or content or
    	"\n* Inside the viewer drop_box.form(), a function in test or in report has a nil result."
    --	if type(dropit.content) == "function" then dropit.content = ( dropit.content() ) end -- and use it as content form function
    	if type(dropit.content) == "function" then dropit.content = ( dropit.content() ) end -- and use it as content form function
    	if type(dropit.image) == "string" then
    		dropit.image = ''
    		.. '<div class="NavPic" style=" background-color:' .. dropit.bg1 .. '; " >'
    			.. '[[File:' .. dropit.image .. '|22px]]'
    		.. '</div>' -- &nbsp;
    	else
    		dropit.image = ''
    	end
    	local d = dropit
    --	res = res .. "</b>"
    	local t = "</b>"
    	if dropit.cssview then
    		t = t .. '\n* List values of <b>CSS if cssview</b>: '
    		for key, elem in pairs(dropit) do
    			if (key ~= "content") and (key ~= "title") then t = t .. viewers.ta(key, elem) end
    		end
    	end
    	-- drop_box from https://fr.wikisource.org/wiki/Modèle:Boîte déroulante = drop_box from template on 20180505 OK.
    --	p_template_drop_box_name		= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	local dropbox_title = 'Boîte déroulante'
    	--[ [
    --	local dropbox_title = viewers.form9content("p_template_drop_box_name")
    	t = t .. mw.getCurrentFrame():expandTemplate{ title = dropbox_title, args = {
    		["label"] = d.label,			["titre"] = d.title, ["contenu"] = d.content,
    		["margeHaut"] = d.margin_all,	["margeBas"] = d.margin_bottom,
    		["hauteur"] = d.height,		--	["width"] = d.width, -- not in html V5
    		["couleurFond"] = d.bg1,		["couleurBordure"] = d.tc1,
    		["alignT"] = d.ta1,				["align"] = d.ta2,
    		["arrondi"] = d.border_radius,	["couleurBordure"] = d.border_color,
    	--	Keep default values for : br, image, alignB, hauteur, margeHaut, margeBas
    	} }
    	--] ]
    	drop_box.Dropbox_t = t
    	viewers.restore_configs(memo, "drop_box.form") -- Restore global configurations after eventual changes.
    	return t
    end -- function drop_box.form(title, content, dropit)
    
    function drop_box.new(selector, title, content_or_func, ...) -- Formats a drop_box for a doc or a group of tests. Take apart dropit options.
    	-- From 20180503 a bug (in Module:Centralizer or MediaWiki) some Dropboxes display twice : modes.get_args_report.
    	-- From 20180503 a bug (in Module:Centralizer or MediaWiki) See CentralManual display twice : modes.get_args_report.xml
    	--	selector = "allwaysview" -- To allways display one view. -- selector = "enforcerun" -- To debug one box with INTERNAL ERROR.
    	local memo = viewers.save_configs("drop_box.new") -- Save global configuration before eventual changes.
    	local t = ""
    	local args = {...}
    	local content_or_func_error = viewers.form9user("\n* Error : Abnormal content for drop_box.new(%1, %2).\n*", selector, title, content_or_func) -- , %3
    	if selector == "never" then return "" end
    	if not ( (selector == true) or (selector == title) or viewers.is_in_sp(selector, "allwaysview alltestsview enforcerun failinref nocontent") ) then return "" end
    	if (type(title) ~= "string") then title = "Default_title" end
    	local dropit = nil -- dropit to change the look of the drop_box
    	--	Style options in dropit{}: ta1, image, ta2, margin_bottom, width, border_radius, border_color, bg1)
    	for i, args_tab in ipairs(args) do -- Get the dropit options for the drop_box.
    		modes.recursiveLoop = (modes.recursiveLoop or 0) + 1
    		if modes.recursiveLoop > 33 then return "" end
    		-- The last argument can be a dropit to change the look of the drop_box
    		if (i == lua_table.level_count(args) ) and (type(args_tab) == "table") and (args_tab["dropit"] == "dropit") then
    			dropit = mw.clone( args_tab )
    		end
    	end
    	local dropit = dropit or {} -- for antiCrash
    	if type(title) ~= "string" then title = "viewers_dropdown_missing_title" end
    	dropit.selector = selector
    	dropit.title = title
    	dropit.args = { ... } -- optional arguments for the content_or_func function
    	local func_from_name = nil
    	dropit.content = content_or_func -- string or function
    	if type(content_or_func) == "string" then func_from_name = lua_table.from_subnames_object(content_or_func) end -- Get the last sub-table from its sub-names.
    	dropit.content_error = ""
    	dropit.title = dropit.title .. ( dropit.title_errors or "" )
    	dropit.resultKind = "ref"
    	local success, result = true, ""
    	dropit.result = result
    	dropit.success = success
    	if type(func_from_name) == "function" then -- In case of named function:
    		dropit.func_name = content_or_func -- memorise its name
    	--	dropit.content = func_from_name -- and use it as content form function
    	end
    	local res = drop_box.form(dropit.title, dropit.content, dropit)
    	if not dropit.success then
    		dropit.content_ref = "content_error<ref>" .. viewers.styles_color_error( dropit.content_error) .. "</ref>"
    		dropit.content = dropit.content_ref
    	end
    	local list, count, level, split = lua_table.level_list(package.loaded) -- subtasks S170813lll
    	viewers.restore_configs(memo, "drop_box.new") -- Restore global configurations after eventual changes.
    --	res = t .. res
    	return res
    end -- function drop_box.new(selector, title, content, ...)
    
    
    -- Build a table, with headers for columns. Example:f
    -- ! style="text-align:left;"| Item
    -- {| class="wikitable" style="text-align: center; color: green;"
    -- {| border="1" style="border-crash:crash"
    -- {| class="wikitable sortable" border="1" mw-collapsible mw-crashd"
    -- |} end of table
    function viewers.table_head(t) return '\n{| class="' .. tostring( t or 'wikitable alternative center' ) .. '" | ' end -- Table columns headers -- or " "
    -- A triable table start with : {| class="wikitable sortable"
    -- A column become fix and not triable with : ||class="unsortable"|
    -- A row become fix and not triable with : |- class="sortbottom"
    function viewers.table_col(t) return '\n! scope="col" | ' .. tostring( t or " " ) end -- Table repeated or different columns headers
    function viewers.table_row(t) return "\n|- " .. tostring( t or " " ) end -- Table -- row
    function viewers.table_dat(t) return "\n| " .. tostring( t or " ") end -- Table data -- or " "
    function viewers.table_end(t) return "\n|}" end -- Table end
    
    viewers.default_test_group = {
    	{ "abc", 123, "A1, B2, C3" },
    	{ "equation", "y =", (11 * 7 + 3 * 12 + 1) },
    	{ "Matrix:", { "2.1.0", "v4-6, ISO_8601, FC14 h6" } },
    	{ "pi = ", "circle / diameter", 3.14, },
    	{ "quadrature", function() end, "convert a square to a circle" },
    }
    
    function tableview.form_one_case(case, tab_view) -- Default: Convert a case from test_group to rowGroup.
    	local tocase = case -- {}
    	return case
    end -- function tableview.form_one_case(case)
    
    function tableview.add_Row(case, tab_view) -- Default: Add a row to rowGroup.
    	if (type(case) == "table") and (type(tab_view) == "table") and (type(tab_view.rowGroup) == "table") then -- tab_view must be a table
    		tab_view.t = tab_view.t .. viewers.ta("add_Row-#rowGroup: ", lua_table.level_count(tab_view.rowGroup) ) -- track to debug
    		tab_view.t = tab_view.t .. viewers.ta("add_Row-#case: ", lua_table.level_count(case) ) -- track to debug
    		table.insert( tab_view.rowGroup, case)
    	elseif (type(case) == "table") and (type(tab_view) == "table") then
    	--	tab_view.rowGroup = {}
    		table.insert( tab_view.rowGroup, case)
    		tab_view.t = (tab_view.t or "") .. viewers.ta("add_Row-#rowGroup: ", lua_table.level_count(tab_view.rowGroup) ) -- track to debug
    		tab_view.t = tab_view.t .. viewers.ta("add_Row-#case: ", lua_table.level_count(case) ) -- track to debug
    	end
    end -- function tableview.add_Row(tab_view)
    
    function tableview.form_all_cases(tab_view) -- Default: Convert all tests cases from test_group to rowGroup.
    	local memo = viewers.save_configs("tableview.form_all_cases") -- Save global configuration before eventual changes.
    	local tab_view = tab_view
    	if (type(tab_view) ~= "table") then tab_view = {} end -- tab_view must be a table
    	if type(tab_view.test_group) ~= "table" then -- tab_view.test_group must be a table
    		tab_view.test_group = {}
    	end
    	tab_view.rowGroup = tab_view.rowGroup or {}
    	tab_view.track = tab_view.track or {} -- Begin tracking of errors and caracteristics of a tab_view case.
    	local trk = tab_view.track
    	if (type(tab_view) ~= "table") then trk.tab_view = tab_view end -- err tab_view is table ?
    	trk.min_in = 999999 ; trk.max_in = 0
    	trk.min_out = 999999 ; trk.max_out = 0
    	tab_view.t = tab_view.t or ""
    	trk.Start_test = tab_view.test_group -- err tab_view.test_group is table ?
    	trk.Start_test_N = lua_table.level_count(tab_view.test_group) -- size tab_view.test_group
    	trk.Start_row = tab_view.rowGroup -- err tab_view.test_group is table ?
    	trk.Start_row_N = lua_table.level_count(tab_view.rowGroup) -- size tab_view.test_group
    	tab_view.t = tab_view.t .. viewers.ta("start#test_group", lua_table.level_count(tab_view.test_group) ) -- track to debug
    	if type(tab_view.rowGroup) ~= "table" then tab_view.rowGroup = {} end
    	tab_view.t = tab_view.t .. viewers.ta("start#rowGroup", lua_table.level_count(tab_view.rowGroup) ) -- track to debug
    	for i, case in ipairs(tab_view.test_group) do
    	--	tab_view.t = tab_view.t .. viewers.ta("i", i)
    		if case.STOP == "STOP" then break end
    		trk.i = i
    		trk.case_in = case -- for table error ?
    		if type(case) ~= "table" then
    			case = { case }
    		end -- Cases must be tables of values.
    		trk.min_in = 99 ; trk.max_in = 0
    		trk.min_out = 99 ; trk.max_out = 0
    		if lua_table.level_count(case) < trk.min_in then trk.min_in = lua_table.level_count(case) end
    		if lua_table.level_count(case) > trk.max_in then trk.max_in = lua_table.level_count(case) end
    		if type(tableview.form_one_case) == "function" then -- Convert all tests cases from test_group to rowGroup.
    			case = tab_view.form_one_case(case, tab_view) -- Formats one case
    		else
    			case = case -- if tableView_form_one_case() is not defined, do not Formats the case
    		end
    		--	Keep all cells: Insert a masked text in all table cells, to not lost following cells.
    		if (type(case) == "table") and (type(tab_view.rowGroup) == "table") then -- Do not fail if case is nil or {}.
    			local headers_split = mw.text.split(tab_view.headers, ';', true) -- fr wikisource org
    			for i, header in ipairs(headers_split) do
    				header = mw.text.trim(header)
    				case[i] = case[i] or viewers.usual_color("-", "mask") -- "mask", "discreet", "error"
    			end
    		end
    		if type(case) ~= "table" then -- check case_out
    			case = { case }
    		end
    		if lua_table.level_count(case) < trk.min_out then trk.min_out = lua_table.level_count(case) end
    		if lua_table.level_count(case) > trk.max_out then trk.min_out = lua_table.level_count(case) end
    		tab_view.add_Row(case, tab_view) -- Default: Add a row to rowGroup.
    		trk.End_test = tab_view.test_group -- err tab_view.test_group is table ?
    		trk.End_test_N = lua_table.level_count(tab_view.test_group) -- err tab_view.test_group is table ?
    		trk.End_row = tab_view.rowGroup -- err tab_view.test_group is table ?
    		trk.End_row_N = lua_table.level_count(tab_view.rowGroup) -- err tab_view.test_group is table ?
    		tab_view.t = tab_view.t .. "\n* Start: "
    		tab_view.t = tab_view.t .. viewers.form9user("tb=<b>%1</b>, tbN=<b>%2</b>, min=<b>%3</b>, max=<b>%4</b>. ", tostring(trk.Start_test), trk.Start_test_N, trk.min_in, trk.max_in) -- track to debug
    		tab_view.t = tab_view.t .. viewers.form9user("i=<b>%1</b>, case_in=<b>%2</b>, case_out=<b>%3</b>, ", tostring(trk.i), type(trk.case_in), type(trk.case_out) )
    		trk.Start_test = tab_view.test_group -- err tab_view.test_group is table ?
    		trk.Start_test_N = lua_table.level_count(tab_view.test_group) -- size tab_view.test_group
    		trk.Start_row = tab_view.rowGroup -- err tab_view.test_group is table ?
    		trk.Start_row_N = lua_table.level_count(tab_view.rowGroup) -- err tab_view.test_group is table ?
    		tab_view.t = tab_view.t .. " ** End: "
    		tab_view.t = tab_view.t .. viewers.form9user("tb=<b>%1</b>, tbN=<b>%2</b>, min=<b>%3</b>, max=<b>%4</b>. ", tostring(trk.End_test), trk.End_test_N, trk.min_out, trk.max_out) -- track to debug
    		tab_view.track = trk
    	end
    	viewers.restore_configs(memo, "tableview.form_all_cases") -- Restore global configurations after eventual changes.
    end -- function tableview.form_all_cases(tab_view)
    
    function tableview.adapt_options(tab_view) -- Adapt all options for all uses.
    	local memo = viewers.save_configs("tableview.adapt_options") -- Save global configuration before eventual changes.
    	if type(tab_view) ~= "table" then tab_view = {} end -- tab_view must be a table
    	tab_view.t = (tab_view.t or "")
    	tab_view.headers = tab_view.headers or "viewers_tableView_default_headers"
    	tab_view.headers = viewers.form9user(tab_view.headers)
    	tab_view.form_elem_detail = tab_view.form_elem_detail or "viewers_tab_view_form_elem_detail" -- "detail = %1 | %2 | %3 | %4 | %5."
    	tab_view.headers_class = tab_view.headers_class or "wikitable alternative center"
    	--	headers_class = "wikitable alternative center sortable",
    	-- A triable table start with : {| class="wikitable sortable"
    	-- A column become fix and not triable with : ||class="unsortable"|
    	tab_view.tableStyle = tab_view.tableStyle or " " -- Style of the whole table view.
    	tab_view.test_group = tab_view.test_group or viewers.default_test_group
    	tab_view.t = (tab_view.t or "") .. viewers.ta("tableView.tab_view.test_group size: ", lua_table.level_count(tab_view.test_group) ) -- track to debug
    	tab_view.form_one_case = tab_view.form_one_case or tableview.form_one_case
    	tab_view.form_all_cases = tab_view.form_all_cases or tableview.form_all_cases
    	tab_view.add_Row = tab_view.add_Row or tableview.add_Row
    	tab_view.ccc = tab_view.ccc or tableview.ccc or {} -- To communicate and compute between cases
    	tab_view.rowGroup = tab_view.rowGroup or {} -- Only tab_view can change rowGroup to avoid effect from a tableview on the next
    	tab_view.track_on = tab_view.track_on or false
    	tab_view.t = tab_view.t .. viewers.ta("#tab_view.rowGroup", lua_table.level_count(tab_view.rowGroup) ) -- track to debug
    	viewers.restore_configs(memo, "tableview.adapt_options") -- Restore global configurations after eventual changes.
    	return tab_view
    end -- function tableview.adapt_options(tab_view)
    
    function tableview.form_whole_view(tab_view) -- Formats whole the tableview.new()
    	local memo = viewers.save_configs("tableview.form_all_cases") -- Save global configuration before eventual changes.
    	local t, err = "", ""
    	if (lua_table.level_count(tab_view.test_group) == 0) then
    		err = err .. viewers.ta("#tab_view.test_group", lua_table.level_count(tab_view.test_group) )
    	end
    	local t = viewers.table_head(tab_view.headers_class or "")
    	if (type(tab_view.headers) ~= "string") then
    		tab_view.headers = "tab_view; headers; missing"
    		err = err .. tab_view.headers
    	end
    	local head = mw.text.split( viewers.form9user(tab_view.headers), ";")
    	for i, header in ipairs(head) do -- Formats headers of the table.
    		t = t .. viewers.table_col(header or "")
    	end
    	tableview.form_all_cases(tab_view) -- Default: Convert all tests cases from test_group to rowGroup.
    	if (type(tab_view.rowGroup) ~= "table") then tab_view.rowGroup = {} end
    	if (lua_table.level_count(tab_view.rowGroup == 0) ) then
    		err = err .. "whole:"
    		err = err .. viewers.ta("#tab_view.test_group", lua_table.level_count(tab_view.test_group) )
    		err = err .. viewers.ta("#tab_view.rowGroup", lua_table.level_count(tab_view.rowGroup) )
    	end
    	for row_i, columns_i in ipairs(tab_view.rowGroup) do -- Formats the content of each of rows.
    		t = t .. viewers.table_row()
    		for col, val in ipairs(columns_i) do
    			t = t .. viewers.table_dat(val or "") -- each value in columns of row_i
    		end
    	end
    	t = t .. viewers.table_end()
    	if tab_view.track_on then t = t .. "tableView_form_whole_view: " .. tostring(err) end
    	if (err ~= "") and (tab_view.track_on) then t = t .. "tableView_form_whole_view: " .. tostring(err) end
    	viewers.restore_configs(memo, "tableview.form_whole_view")
    	return t
    end -- function tableview.form_whole_view(tab_view) -- S170610csc
    
    function tableview.new(tab_view) -- Formats a table with lines and columns. S170610tvf
    	local memo = viewers.save_configs("tableview.form_whole_view") -- Save global configuration before eventual changes.
    	if type(tab_view) ~= "table" then tab_view = {} end -- tab_view must be a table
    	tab_view.t = (tab_view.t or "") .. viewers.ta("tableView: ", "start")
    	local t = ""
    	local err = nil
    	tab_view = tableview.adapt_options(tab_view) -- Adapt all options for all uses, before all other adaptations.
    	if tab_view.track_on then t = t .. viewers.ta("#test_group", lua_table.level_count(tab_view.test_group) ) .. viewers.ta("#rowGroup", lua_table.level_count(tab_view.rowGroup) ) end
    	t = t .. tableview.form_whole_view(tab_view) -- Formats whole the tableview.new()
    	if tab_view.track_on then t = t .. viewers.ta("#test_group", lua_table.level_count(tab_view.test_group) ) .. viewers.ta("#rowGroup", lua_table.level_count(tab_view.rowGroup) ) end
    	if tab_view.track_on then t = t .. tab_view.t end
    	-- Counts of selected and sorted sub-tasks: , #test_group = 43 , #rowGroup = 0
    	viewers.restore_configs(memo, "tableview.form_whole_view") -- Restore global configurations after eventual changes.
    	return t, err, tab_view
    end -- t, err, tab_view = function tableview.new(tab_view)
    
    function viewers.doc_page(selector, mask_sections) -- Formats some Dropboxes of tests to document a page.
    	local res = ""
    	if not mask_sections then res = res .. viewers.doc_section(selector, "viewers_section_title_page", "h2", mask_sections) end
    	res = res .. drop_box.new(selector, "datas.available_props_report(t) Reports availables datas properties **", datas.available_props_report)
    --	res = res .. drop_box.new(selector, "modes_args_known_report_title", modes.args_known_report)
    	res = res .. drop_box.new(selector, "modes_get_args_report_title", modes.get_args_report)
    	res = res .. drop_box.new(selector, "modes_used_options_list_title", modes.used_options_list )
    	res = res .. drop_box.new(selector, "modes_list_all_args_main_title", modes.list_all_args_main)
    --	res = res .. "\n------ " -- This code interact with drop_box and debug the bug T20151215 2016-11-13 17:57.
    --	res = res .. drop_box.new(selector, "langs_translations_counts_title", langs.translations_counts) --	S170618ltc
    	res = res .. drop_box.new(selector, "luaTable_table_args_source_title", lua_table.structure, modes.args_source, "modes.args_source")
    	res = res .. drop_box.new(selector, "modes_args_known_structure_title", modes.args_known_structure)
    	return res
    end -- function viewers.doc_page(selector, mask_sections)
    
    function viewers.doc_module(selector, mask_sections) -- Formats some Dropboxes of tests to document a module.
    	local res = ""
    	if not mask_sections then res = res .. viewers.doc_section(selector, "viewers_section_title_module", "h2") end
    	res = res .. drop_box.new(selector, "modes_args_unknown_report_title", modes.args_unknown_report)
    	res = res .. drop_box.new(selector, "versions_support_desk_title", versions.form_support_desk_report)
    	res = res .. drop_box.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests)
    	res = res .. drop_box.new(selector, "modes_all_categories_list_title", modes.all_categories_list)
    	res = res .. drop_box.new(selector, "modes_all_errors_list_title", modes.all_errors_list)
    	return res
    end -- function viewers.doc_module(selector, mask_sections)
    
    function viewers.doc_internal(selector, mask_sections) -- Formats some Dropboxes of tests to document internal functions.
    	local res = ""
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:activity", "h3") end
    	res = res .. drop_box.new(selector, "activity_support_central_modules_title", activity.begin_central_modules_support) -- doc link
    	res = res .. drop_box.new(selector, "langs_translations_stats_report_title", langs.translations_statistics_report)
    	res = res .. drop_box.new(selector, "activity_phabricator_tasks_title", activity.phabricator_tasks_report) -- S170606act
    	res = res .. drop_box.new(selector, "activity_report_subtasks_title", activity.central_subtasks_report)
    	res = res .. drop_box.new(selector, "activity_display_central_libraries_title", activity.describe_central_libraries)
    	res = res .. drop_box.new(selector, "activity_MW_Versions_report_title", activity.MW_Versions_report)
    	res = res .. drop_box.new(selector, "activity_central_functions_report_title", activity.central_functions_report)
    	res = res .. drop_box.new(selector, "activity_check_html_bold_tags_title", activity.check_html_bold_tags)
    --	if 1 then return res end -- try to find : {{Centralizer|tests|itemid=Q535}} Erreur Lua : not enough memory
    --	activity_check_html_bold_tags_title			= "activity.check_html_bold_tags() Report imbalances of beginnings and ends of bold in code.",
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:datas", "h3") end -- .get_item(
    	res = res .. drop_box.new(selector, "datas.get_item() Report datas from mw.wikibase **", datas.get_item_report)
    --	res = res .. drop_box.new(selector, "datas_update_Special_PageData_title", datas.update_PageData)
    	--
    --	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:events", "h3") end
    --	function events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat)
    --	res = res .. drop_box.new(selector, "events_all_kinds_tests_title", events.all_kinds_test) -- 5 empty rows
    --	res = res .. drop_box.new(selector, "langs_selectLang_tests_title", langs.select_lang_test) -- lang %1 %2 %3
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:langs", "h3") end
    	res = res .. drop_box.new(selector, "langs_translations_counts_title", langs.translations_counts) --	S170618ltc
    --	res = res .. drop_box.new(selector, "langs_changing_translations_title", langs.changing_translations) -- no tabview
    	res = res .. drop_box.new(selector, "langs_missing_translations_title", langs.missing_translations) -- string.find nil
    	res = res .. drop_box.new(selector, "langs_dummy_languages_title", langs.dummy_languages)
    --	res = res .. drop_box.new(selector, "langs_mixed_translations_title", langs.i18n_lister)
    --	res = res .. drop_box.new(selector, "langs_abnormal_char_in_text_title", langs.abnormal_char_in_text ) -- false
    	res = res .. drop_box.new(selector, "langs_list_MediaWiki_languages_title", langs.list_MediaWiki_languages ) -- OK, show in table ?
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:lua_table", "h3") end
    --	local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests( -- subtasks S170813lll
    	res = res .. drop_box.new(selector, "lua_table_count_all_values_title", lua_table.count_tests ) -- lua_table.count_tests()
    --	function lua_table.count_tests(t) -- Count all objects or types or values in the table
    --	res = res .. drop_box.new(selector, "luaTable_fromsubnames_test_title", lua_table.fromsubnames_test ) -- nil
    	res = res .. drop_box.new(selector, "luaTable_rough_view_tests_title", lua_table.rough_view_test )
    	res = res .. drop_box.new(selector, "lua_table_structure_recursive_report", lua_table.structure_recursive_report)
    	res = res .. drop_box.new(selector, "luaTable_toList_tests_title", lua_table.to_list_tests, { ["dropit"] = "dropit", arggg = "dropit" } )
    	res = res .. drop_box.new(selector, "luaTable_toTable_tests_title", lua_table.to_table_test)
    	--
    	-- In central modules, the Library:mathroman is a simple example of central modules support for any library.
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:mathroman", "h3") end
    --	if not mask_sections then res = res .. viewers.doc_section(selector, "viewers_section_title_library_mathroman", "h3") end
    	res = res .. drop_box.new(selector, "mathroman_roman2int_tests_title", mathroman.roman2int_tests) -- Discreet main version
    	res = res .. drop_box.new(selector, "mathroman_int2roman_test_title", mathroman.int2roman_test) -- Discreet main version
    	--"enforcerun" "allwaysview"
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:modes", "h3") end -- function viewers.doc_section(
    --	if not mask_sections then res = res .. viewers.doc_section(selector, "viewers_section_title_library_modes", "h3") end
    --	res = res .. drop_box.new(selector, "datas.get_item() Report datas from mw.wikibase **", datas.get_item_report)
    --	res = res .. drop_box.new(selector, "modes_args_known_report_title", modes.args_known_report)
    	res = res .. drop_box.new(selector, "modes_get_args_report_title", modes.get_args_report)
    	res = res .. drop_box.new(selector, "modes_used_options_list_title", modes.used_options_list)
    --	res = res .. drop_box.new(selector, "modes.bind_args_known_one_lib_report(t) Report the binding of one library known args. **", modes.bind_args_known_one_lib_report)
    --	res = res .. drop_box.new(selector, "modes_used_options_list_title", modes.used_options_list )
    	res = res .. drop_box.new(selector, "versions_bind_arguments_tests_title", modes.options_from_args_tests)
    --	res = res .. drop_box.new(selector, "versions_bind_arguments_tests_title", versions.bind_arguments_tests)
    	res = res .. drop_box.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests)
    --	res = res .. drop_box.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests,
    	--	d.bg1="yellow", d.border_color="red", d.border_radius="10px 10px 10px 10px", image="Sanscrit dha.svg", } ) -- , cssview=true
    	res = res .. drop_box.new(selector, "modes_recursive_normal_tests_title", modes.recursive_normal_tests) -- only errors
    	-- arguments list
    --	res = res .. drop_box.new(selector, "modes_all_categories_list_title", modes.all_categories_list) -- n = 0
    --	res = res .. drop_box.new(selector, "modes_all_errors_list_title", modes.all_errors_list) -- todo
    	-- arguments support
    --	res = res .. drop_box.new(selector, "modes_multiple_selection_tests_title", modes.multiple_selection_tests)
    	res = res .. drop_box.new("never", "modes_multiple_values_tests_title", modes.multiple_values_tests)
    	res = res .. drop_box.new(selector, "modes_levenshtein_similar_tests_title", modes.levenshtein_similar_tests)
    	res = res .. drop_box.new(selector, "modes_namespaces_page_list_title", modes.namespaces_page_list)
    	res = res .. drop_box.new(selector, "modes_recursive_normal_tests_title", modes.recursive_normal_tests) -- only errors
    	res = res .. drop_box.new(selector, "modes_namespaces_page_list_title", modes.recursive_normal_tests) -- only errors
    	-- function tab_view.form_one_case)
    	-- "enforcerun"
    --	res = res .. viewers.doc_section(selector, "Library:tests_groups", "h3") -- S170801rtc todo
    --	res = res .. drop_box.new(selector, "tests_groups_recursive_tests_title", tests_groups.recursive_tests (t)
    --	res = res .. drop_box.new(selector, "tests_groups_getTestProvider_title", viewers.simple_list_test )
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:versions", "h3") end
    --	if not mask_sections then res = res .. viewers.doc_section(selector, "viewers_section_title_library_versions", "h3") end
    	res = res .. drop_box.new(selector, "versions_versions_management_title", versions.versions_support_test ) -- OK, to optimize
    	res = res .. drop_box.new(selector, "versions.bind_all_sub_modules() ACTUAL Bind all sub-modules of the main module **", versions.bind_all_sub_modules_actual_report ) -- to_debug_on_20170507
    	res = res .. drop_box.new(selector, "versions_all_G_and_loaded_list_title", versions.all_G_and_loaded_list)
    --	res = res .. drop_box.new(selector, "versions_central_changes_title", versions.central_changes) --RIC mw.loadData(
    --	res = res .. drop_box.new(selector, "versions_deprecated_function_tests", viewers.simple_list_test)
    --	res = res .. drop_box.new(selector, "versions_bind_modules_tests_title", versions.bind_modules_test )
    	res = res .. drop_box.new(selector, "versions_sort_central_modules_title", versions.sort_central_modules_report ) -- S170606cmr
    --	res = res .. drop_box.new(selector, "versions_antiCrash_tests_title", versions.anti_crash_tests ) -- Tests antiCrash() -- to_debug_on_20170507
    	res = res .. drop_box.new(selector, "versions_running_times_title", versions.running_times ) -- versions.running_times()
    	--
    	if not mask_sections then res = res .. viewers.doc_section(selector, "Library:viewers", "h3") end
    --	The Library:viewers can formats texts to document in some languages: tableview(in lines and columns), Dropboxes, recursive luatables...
    	res = res .. drop_box.new(selector, "langs_form9user_tests_title", viewers.form9user_test )
    	res = res .. drop_box.new(selector, "langs_form99user_tests_title", viewers.form99user_test )
    	res = res .. drop_box.new(selector, "viewers_parts_of_date_tests_title", viewers.parts_of_date_tests)
    	res = res .. drop_box.new(selector, "viewers_simpleList_tests_title", viewers.simple_list_test )
    	res = res .. drop_box.new("never", "viewers_table_tab_options_title", viewers.table_test )
    	res = res .. drop_box.new(selector, "viewers_save_restore_balance_title", viewers.save_restore_balance_report) -- to_debug_on_20170507
    	return res
    end -- function viewers.doc_internal(selector, mask_sections)
    
    --	See T166202 Strings defined as long comments give a Lua modules syntax error
    function viewers.try_graph()
    	-- see Macron from https://fr.wikipedia.org/w/index.php?title=Mod%C3%A8le:Frise_chronologique_Emmanuel_Macron&action=edit
    	-- unusable : frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } }
    	-- use : frame:preprocess( string ) or object = frame:newParserValue( text )
    	-- use : frame:newTemplateParserValue{ title = title, args = table }
    	local t = "\n* viewers.try_graph()"
    	t = t .. "<b>Carrière et parcours politique d'Emmanuel Macron</b>"
    	t = t .. viewers.time_line
    	--	<noinclude> </noinclude>
    	return t
    end -- function viewers.try_graph()
    
    viewers.central_functionalCSS = { -- S170617CSS : Use MW CSS see edit_class, content_class, CSSstructure
    	edit_class = "editOptions",
    	edit_form = "mw-editform-legacy",
    	box_class = "infobox_v2",
    	box_form = "infobox_v2",
    	content_class = "content",
    	content_form = "content",
    	page_class = "page_class",
    	page_form = "page_form",
    	user_class = "user_class",
    	user_form = "user_form",
    	toc_class = "toc",
    	toc_form = "toc_form",
    --	result_form = viewers.form9user(result_form, toc_form, toc_class, edit_form, content_form, page_form, user_form, xx, xx, xx)
    	--												%1		%1		%1		%1		%1		%1		%1		%1
    	CSSstructure = '<div class="editOptions">%1</div><div class="editOptions">%1</div><div class="editOptions">%1</div><div class="editOptions">%1</div>',
    	-- .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>',
    	viewers_sentence_example_page_text			= "Cette phrase montre un exemple de texte de page. ", -- br
    	viewers_sentence_example_page_text			= "Dieser Satz zeigt eine Beispieltextseite. ", -- de
    	viewers_sentence_example_page_text			= "This sentence shows an example of page text. ", -- en
    	viewers_sentence_example_page_text			= "Esta frase muestra una página de muestra de texto. ", -- es
    	viewers_sentence_example_page_text			= "Cette phrase montre un exemple de texte de page. ", -- fr
    	viewers_sentence_example_page_text			= "Ez a mondat egy minta oldal szöveg.", -- hu
    	viewers_sentence_example_page_text			= "Câu này cho thấy một trang mẫu của văn bản. ", -- vi
    }
    
    --	The TemplateStyles extension introduces a <templatestyles> tag to specify that a stylesheet should be loaded from a wiki page. Placing this in a template allows the template to have custom styles without having to place them in MediaWiki:Common.css.
    
    p.options_for_modes = { -- module options_for_modes
    	read	= " box1 catview ",
    	doc		= " nobox1 noerr nocatview ",
    	edit	= " box1 catview docdef docline docsrc docdata docview : ",
    	tests	= " box1 catview docdef docline docsrc docdata docview : tests ",
    }
    function p.box_read(prop, title) -- Draw the main box one. -- ric (p.box_read)
    --	Galilée (Q307), Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322),
    --	Nelson Mandela (Q8023), Rudyard Kipling (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772)
    	datas.QITEM = mw.wikibase.getEntityIdForCurrentPage() -- use props.QITEM Returns the Item id as string, like "Q42"
    	local QITEM = datas.QITEM or datas.default_item or "Q307" -- Keep Galilée (Q307)
    	datas.prop, datas.props = datas.get_item(modes.args_known, QITEM) -- Get datas from mw.wikibase for the page.
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	local prop = datas.prop
    	local res = "(p.box_read) "
    	local flag = viewers.form_image("Flag_of_England.svg", 50)
    --	local flag = viewers.form_image(viewers.form9user("flag_of_country"), 50)
    --	args_known_country						= "England", -- English
    --	args_known_flag							= "Flag_of_England.svg", -- English
    --	args_known_monument						= "St_Pauls_aerial_%28cropped%29.jpg", -- English St Paul's Cathedral
    --	args_known_town							= "London", -- English
    	local image = viewers.form_image(prop.image, 50)
    	local birthyear_deathyear = " ( " .. (prop.birthyear or "birthyear") .. " - " .. (prop.deathyear or "deathyear") .. " ) "
    	local phabtask = " - [[d:" .. QITEM .. "|Datas]] "
    	res = res .. "<br/><center><b>firstname: " .. (prop.firstname or "firstname") .. "</b>, "
    	res = res .. "<b>sitelink: " .. prop.sitelink .. phabtask .. "</b></center>"
    	res = res .. "<br/><center>Labels in langs: <b>" .. prop.labelbylang .. "</b>, user: <b>" .. prop.labeluser .. "</b>, content: <b>" .. prop.labelcontent .. "</b>, page: <b>" .. prop.labelpage .. "</b>"
    	res = res .. "<br/><center><b>description: " .. prop.description .. birthyear_deathyear .. "</b></center>"
    	res = res .. " <br/><center>" .. flag .. " * used languages: user:<b>" .. langs.user_lang .. "</b>, content:<b>" .. langs.content_lang .. "</b>, page:<b>" .. langs.page_lang .. "</b> * " .. image .. "</center>"
    --	res = res .. "<br/><center>languages:<b>" .. langs.main_i18n_languages_list() -- List available translations languages
    	res = '<div style="border-radius:0.7em; margin-right:5px; box-shadow:0.2em 0.3em 0.2em #B7B7B7; background-color:#F1F1DE; padding:0.3em; width=90%; overflow-x:hidden; ">' .. res .. '</div>'
    	return res
    end -- function p.box_read(args_final, title)
    
    -- Display the documentation in an infobox, similar to edit-boxs
    -- Affichage de documentation dans un cadre (box), semblable aux boites d'edition
    function p.box_edit(args_final)
    --	read	= " box1 ",
    --	edit	= " box1 docdef docline docsrc docdata catview docview : ",
    --	doc		= " nobox1 noerr nocatview ",
    --	tests	= " box1 docdef docline docsrc docdata catview docview : tests ",
    	local res, props = "", datas.props
    	if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments
    	langs.init_content_page_user_lang(modes.args_source.contentlang, modes.args_source.pagelang, modes.args_source.userlang)
    --	res = res .. "<center><small>" .. viewers.discreet_main_version() .. viewers.ta("contentlang", langs.content_lang) .. viewers.ta("pagelang", langs.page_lang) .. viewers.ta("userlang", langs.user_lang)
    	res = res .. "<center>" .. viewers.discreet_main_version() .. viewers.ta("content", langs.content_lang) .. viewers.ta("page", langs.page_lang) .. viewers.ta("user", langs.user_lang)
    	res = res .. " - [https://fr.wikisource.org/wiki/MediaWiki:Scribunto/Central_modules_reference_manual User manual]"
    	res = res .. " - viewers.phab_task('T135845', 'Convert')"
    	res = res .. " - viewers.phab_task('T198107', 'Begin to use')" .. "</center>"
    	res = res .. viewers.styles_color_error("<center><b>" .. viewers.form9user("modes_delete_docbox_wng") .. "</b><br/></center>")
    	res = res .. drop_box.form(drop_box.new_title(), versions.form_support_desk_report() )
    	if modes.option("debug") then res = res .. "\n*" .. viewers.ta("modes.cat_view", modes.cat_view) .. viewers.ta("modes.template_options", modes.template_options) .. viewers.ta("modes.mode_options", modes.mode_options) end
    	local lnk = props.QITEM
    	if modes.option("docdata")	then res = res .. "\n*" .. modes.generDoc(" docdef docline ", datas.args_wikidata, datas_link) end
    	res = res .. ", " .. viewers.form9user(" (%1	 properties)", (datas.propss_count_all or "") ) -- datas_structured_data_txt
    	if modes.option("docview")	then res = res .. "\n*" .. modes.generDoc("", args_final, "Arguments") end
    	if not modes.option("noerr")then res = res .. "\n*" .. events.errors_lister() end
    	local t = "" -- Formats events views
    --	local wng, err, cat = events.sort_typ() -- Sort events by type in wng, err, cat.
    
    --	if evt.typ == "wng" then evt.res = viewers.styles_color_warning(evt.user_wkt) end
    --	if new_evt then table.insert(events.list_all_events, evt) end
    	for key, evt in pairs(events.list_all_events) do
    		if evt.typ == "wng" then
    			evt.res, evt = events.form(evt)
    			if evt.res then t = t .. "<br>* " .. tostring(evt.res) end
    		end
    	end
    	--
    	for key, evt in pairs(events.list_all_events) do
    		if evt.typ == "err" then
    			evt.res, evt = events.form(evt)
    			if evt.res then t = t .. "<br>* " .. tostring(evt.res) end
    		end
    	end
    	--
    	for key, evt in pairs(events.list_all_events) do
    		if evt.typ == "cat" then
    			evt.res, evt = events.form(evt)
    			if evt.res then t = t .. "<br>* " .. tostring(evt.res) end
    		end
    	end
    	t = t .. langs.main_i18n_languages_list() -- List available translations languages
    	res = res .. t
    	res = '<div style="border-style: solid; border-width: 1px; background-color:#FAFAFA; padding:0.3em; width=90%; overflow-x:hidden; ">' .. res .. '</div>'
    --	local result = "\n------ " -- This code interact with drop_box and debug the bug T20151215 2016-11-13 17:57.
    --	result = result .. '<div class="CentralDocBox" style=" width=90%; border: 1px solid #AAAAAA; margin:1em; background-color:#F1F1F1; padding:0.3em; ">' .. res .. '</div>'
    --	result = result .. "\n* " .. events.categories_lister(":")
    	return res
    end -- function p.box_edit(args_final)
    
    function p.form_result(args_final, main_module) -- Formats all results of this module and its sub-modules.
    	local res = ""
    	local memo = viewers.init_configs("p.form_result") -- Initialize global configurations and save them before eventual changes.
    	datas.default_item = datas.default_item or "Q307" -- Keep Galilée (Q307)
    	main_module = main_module or versions.main_module
    	if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments
    	res = res .. viewers.ta("modes.mode_name", modes.mode_name) .. viewers.ta("modes.options", modes.options)
    --	if modes.option("box1") then res = res .. p.box_read(props) end -- ric (p.box_read)
    	if modes.option("box1") then res = res .. p.box_read(prop, title) end -- Draw the main box one. -- ric (p.box_read)
    	if modes.option("box1") or modes.option("catview")
    	then res = res .. " catview = " .. events.categories_lister(":") end -- Display categories
    	events.gener_categories(args_final) -- Formats all categories without activate them
    	if modes.option("docview") or modes.option(":") or modes.option("tests") or (modes.args_final.mode == "edit") then
    		res = res .. "\n* datas.default_item = <b>" .. datas.default_item .. "</b>, datas.default_name = <b>" .. datas.default_item .. "</b>\n"
    		res = res .. p.box_edit(modes.args_final)
    	elseif modes.option("read") or (modes.args_final.mode == "read") then -- (box_edit)
    		res = res .. "\n* datas.default_item = <b>" .. datas.default_item .. "</b>, datas.default_name = <b>" .. datas.default_item .. "</b>\n"
    		res = res .. p.box_read(modes.args_final)
    	elseif modes.option("edit") or (modes.args_final.mode == "edit") then
    	end
    	modes.time3 = os.clock()
    	if modes.option("tests") then --   or (modes.args_final.mode == "tests") --
    		res = res .. viewers.doc_group("allwaysview") -- viewers.doc_group(selector, mask_sections) -- To enforce title of sections
    --		res = res .. viewers.doc_page("allwaysview") -- included in viewers.doc_group
    --		res = res .. viewers.doc_module("allwaysview") -- included in viewers.doc_group
    --		res = res .. viewers.doc_internal("allwaysview") -- included in viewers.doc_group
    		res = res .. versions.running_times(false, "")
    	end
    	viewers.restore_configs(memo, "p.form_result") -- Restore global configurations after eventual changes.
    	return res
    end -- res = res .. p.form_result(args_final, main_module) -- Formats all results of this module and its sub-modules.
    
    function viewers.init_configs(memo, tab_view, group) -- Initialize global configurations and save them before eventual changes.
    	if type(memo) ~= "table" then memo = {} end
    	if type(group) ~= "table" then group = nil end
    	if type(tab_view) ~= "table" then
    		tab_view = events.tab_view or {}
    	end
    	memo.events = events -- A new events process/object come from the events process/object in this module.
    	memo.events.tab_view			= tab_view				or memo.events.tab_view or events.tab_view
    	memo.events.catview			= tab_view.catview		or memo.events.catview or modes.catView
    	memo.events.default_group	= tab_view.default_group or memo.events.group_all_types_test
    	memo.events.DropboxStyle	= tab_view.DropboxStyle or memo.events.DropboxStyle
    	memo.events.testGroup		= group or tab_view.testGroup or memo.events.testGroup or events.testGroup or {}
    	memo.events.headers			= tab_view.headers		or memo.events.headers
    	memo.events.kind			= tab_view.kind			or memo.events.kind
    	memo.events.tableViewStyle	= tab_view.tableViewStyle or memo.events.DropboxStyle
    	memo.events.testsFunction	= tab_view.testsFunction or memo.events.testsFunction
    	memo.events.typ				= tab_view.typ			or memo.events.typ
    	memo.events.content_lang	= tab_view.content_lang or memo.events.content_lang
    	memo.events.page_lang		= tab_view.page_lang		or memo.events.page_lang
    	memo.events.user_lang		= tab_view.user_lang		or memo.events.user_lang
    	memo.events.recursiveLevel	= tab_view.recursiveLevel or memo.events.recursiveLevel
    	memo.events.recursiveLimit	= tab_view.recursiveLimit or memo.events.recursiveLimit or 11111
    	memo.events.testGroup		= events.testGroup			or memo.events.testGroup or {}
    	langs.init_content_page_user_lang(memo.events.content_lang, memo.events.page_lang, memo.events.user_lang)
    	return memo, memo.events
    end -- function viewers.init_configs(memo, tab_view, group)
    
    function viewers.save_configs(where) -- Save global configuration before eventual changes.
    	if type(where) ~= "string" then where = "where" end -- to not disturb normal string and detect missing where
    	viewers.save_configs_runs = viewers.save_configs_runs or {}
    	viewers.save_configs_runs[where] = { ["where"] = where, ["save"] = "save", }
    	local memo = {}
    	memo.memo_categories_list		= events.categories_list
    	memo.memo_tabView				= events.tab_view
    	memo.memo_testGroup				= events.testGroup
    	memo.memo_content_lang			= langs.content_lang
    	memo.memo_content_translations	= langs.content_translations
    	memo.memo_langs_main_i18n		= langs.main_i18n
    	memo.memo_page_lang				= langs.page_lang
    	memo.memo_page_translations		= langs.page_translations
    	memo.memo_user_lang				= langs.user_lang
    	memo.memo_user_translations		= langs.user_translations
    	memo.memo_args_known			= modes.args_known
    	memo.memo_args_template			= modes.args_template
    	memo.memo_modes_catView			= modes.catView
    	memo.memo_mode_name				= modes.mode_name
    	memo.memo_mode_options			= modes.mode_options
    	memo.memo_options_for_modes		= modes.options_for_modes
    	memo.memo_recursiveLimit		= modes.recursiveLimit
    	memo.memo_report_trackOptions	= modes.report_trackOptions
    	memo.memo_template_options		= modes.template_options
    	memo.memo_used_options			= modes.used_options
    	memo.memo_versions_actual_modules	= versions.actual_modules
    	memo.memo_versions_main_i18n		= versions.main_i18n
    	return mw.clone(memo)
    end -- function viewers.save_configs()
    
    function viewers.restore_configs(memo, where) -- Restore global configurations after eventual changes.
    	if type(where) ~= "string" then where = "where" end -- to not disturb normal string and detect missing where
    	if type(memo) ~= "table" then
    		events.add_err("events_close_without_memo_err", where) -- Add an error in the actual table of events.
    		return
    	end
    	viewers.restore_configs_runs = viewers.restore_configs_runs or {}
    	viewers.restore_configs_runs[where] = { ["where"] = where, ["restore"] = "restore", }
    --	local memo = mw.clone(memo)
    	events.categories_list		= memo.memo_categories_list
    	events.tab_view				= memo.memo_tabView
    	events.testGroup			= memo.memo_testGroup
    	langs.content_lang			= memo.memo_content_lang
    	langs.content_translations	= memo.memo_content_translations
    	langs.main_i18n				= memo.memo_langs_main_i18n
    	langs.page_lang				= memo.memo_page_lang
    	langs.page_translations		= memo.memo_page_translations
    	langs.user_lang				= memo.memo_user_lang
    	langs.user_translations		= memo.memo_user_translations
    	langs.init_content_page_user_lang(langs.content_lang, langs.page_lang, langs.user_lang)
    	modes.args_known			= memo.memo_args_known
    	modes.args_template			= memo.memo_args_template
    	modes.catView				= memo.memo_modes_catView
    	modes.mode_name				= memo.memo_mode_name
    	modes.mode_options			= memo.memo_mode_options
    	modes.options_for_modes		= memo.memo_options_for_modes
    	modes.recursiveLimit		= memo.memo_recursiveLimit
    	modes.report_trackOptions	= memo.memo_report_trackOptions
    	modes.template_options		= memo.memo_template_options
    	modes.used_options			= memo.memo_used_options
    	versions.actual_modules		= memo.memo_versions_actual_modules
    	versions.main_i18n				= memo.memo_versions_main_i18n
    	return
    end -- function viewers.restore_configs(memo, where)
    
    function viewers.save_configs_check(save_configs_runs, restore_configs_runs) -- AFTER ALL RUNS, report saved global configurations.
    	viewers.save_configs_runs = save_configs_runs or viewers.save_configs_runs or {}
    	viewers.restore_configs_runs = restore_configs_runs or viewers.restore_configs_runs or {}
    	viewers.mix_configs_runs, i = {}, 0
    	for where, one_func in pairs(viewers.save_configs_runs) do
    		viewers.mix_configs_runs[where] = one_func -- get all configs from save_configs_runs
    	end
    	for where, one_func in pairs(viewers.restore_configs_runs) do
    		viewers.mix_configs_runs[where] = one_func -- get all configs from restore_configs_runs to complete the group.
    	end
    	viewers.save_restore_balance_group = {}
    	for i, one_func in pairs(viewers.mix_configs_runs) do
    		local where = one_func["where"]
    		if viewers.save_configs_runs[where] then one_func["save"] = "save" end
    		if viewers.restore_configs_runs[where] then one_func["restore"] = "restore" end
    		table.insert(viewers.save_restore_balance_group, one_func)
    	end
    	table.sort(viewers.save_restore_balance_group, function (a, b) return ( a.where < b.where ) end ) -- Sort based on where
    	for i, one_func in pairs(viewers.save_restore_balance_group) do
    		one_func.i = i
    		if one_func["save"] and one_func["restore"] then one_func["err"] = "OK" -- normal run, saved and restored
    		elseif one_func["save"] then one_func["err"] = "missing restore"
    		elseif one_func["restore"] then one_func["err"] = "missing save"
    		else one_func["err"] = "missing save and restore"
    		end
    	end
    	return viewers.save_restore_balance_group
    end -- function viewers.save_configs_check(save_configs_runs, restore_configs_runs) -- After all runs, report saved global configurations.
    
    function viewers.save_restore_balance_report(t) -- Report the check of save and restore configs balance
    	local t = t or "\n* viewers.save_restore_balance_report(t) Report known couples of save and restore global configurations."
    	viewers.save_restore_balance_group = viewers.save_configs_check(viewers.save_configs_runs, viewers.restore_configs_runs) -- After all runs, report saved global configurations.
    	t = t .. viewers.form9user("\n* This report checks %1 configurations.", #viewers.save_restore_balance_group)
    	if type(viewers.save_restore_balance_group) ~= "table" then -- abnormal run
    		t = t .. "\n* Error: <b>The table viewers.save_restore_balance_group{} do not exist.</b>"
    		return t
    	end
    --	t = t .. "\n* save_restore_balance_group[37] = " .. lua_table.level_count(viewers.save_restore_balance_group[37]) ..
    --	lua_table.rough_view(viewers.save_restore_balance_group[37])
    	local tab_view = { -- Group datas and options for a table view with lines and columns.
    		test_group = viewers.save_restore_balance_group,
    		title_memo = "viewers_save_restore_balance_title",
    		headers = "viewers_save_restore_balance_headers", -- viewers_tableView_default_headers
    		headers = "i;where;save;restore;errors",
    		headers_class = "wikitable alternative center sortable",
    		form_one_case = function(one_func) -- Convert a case from test_group to rowGroup.
    			return { one_func.i, one_func.where, one_func.save, one_func.restore, one_func.err, }
    		end,
    		rowGroup = {},
    	--	track_on == "details",
    	}
    	t = t .. "<br/>" .. tableview.new(tab_view) -- Form a table view with lines and columns.
    	return t
    end -- t = t .. viewers.save_restore_balance_report(t)
    
    -------------------------------------------------------------------------------------
    
    --	cut_libraries
    
    p.i18n = {} -- translations tables known in the module
    
    p.i18n.br = { -- Translations in breton
    	-- Arguments to import, do not translate. Arguments à importer, ne pas traduire.
    	["modules_guide"] = { ["typ"]	= "ctr", ["need"] = 0, ["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	['p_template_drop_box_name']	= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	['c']							= 'c',
    	['mode']						= 'mode',
    	['options']						= 'options',
    	['itemid']						= 'itemid',
    	['QITEM']						= 'QITEM',
    	['uri']							= 'uri',
    	--
    	-- Translate all next arguments. Traduire tous les arguments suivants :
    	occupation_cat					= '%1',
    	p_authors_deathyear_cat			= "Auteurs-%1",
    	year_number_cat					= "Année %1",
    	-- Noms et descriptions des arguments
    	lastname						= 'nom',
    	lastname_descr					= "Nom. A préciser pour corriger la clé de tri.",
    	firstname						= 'prénom',
    	firstname_descr					= "Prénom. A préciser pour corriger la clé de tri.",
    	firstname2						= 'prenom',
    	firstname2_descr				= "Prénom. A préciser pour corriger la clé de tri.",
    	initial							= 'initiale',
    	initial_descr					= "Initiale pour corriger les catégories d'ateurs.",
    	title							= 'titre',
    	title_descr						= "Titre de la page, automatique.",
    	country							= 'pays',
    	flag_of_country					= 'Flag_of_France.svg',
    	flag_of_country_descr			= 'Drapeau du pays',
    
    	-- naissance et deces
    	birthday						= 'jourNaissance', -- nacimiento P569
    	birthday_descr					= "Jour de naissance.",
    	birthyear						= 'anneeNaissance',
    	birthyear_descr					= "Année de naissance",
    	p_authors_birthyear_cat			= "Naissance en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	deathday						= 'jourDeces', -- muerte P570
    	deathday_descr					= "Jour de décès",
    	deathyear						= 'anneeDeces',
    	deathyear_descr					= "Année de décès",
    	p_authors_deathyear_cat			= "Décès en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	description						= 'description',
    	description_descr				= "Description de l'auteur, à préciser si la description automatique ne convient pas",
    	--
    	-- Arguments limités à des valeurs multiples
    	region							= 'région',
    	region_descr					= 'Région pour déterminer les époques anciennes.',
    	region_values					= "autre;chine;inde;siècle", -- wiki_selectors
    
    	rights							= 'droits',
    	rights_descr					= "Type de droits d'auteur nécessaire parmi : 70,50,mpf,ONU,non.",
    	rights_values					= '70;50;mpf;ONU;non',
    
    	sex								= 'sexe',
    	sex_descr						= "Sexe de l'auteur",
    	sex_values						= 'homme;femme',
    } -- p.i18n.br
    
    p.i18n.en = { -- Translations in English
    	-- Arguments to import, do not translate.
    	["modules_guide"] = { ["typ"]	= "ctr", ["need"] = 0, ["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	['p_template_drop_box_name']	= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	['c']							= 'c',
    	['mode']						= 'mode',
    	['options']						= 'options',
    	['itemid']						= 'itemid',
    	['QITEM']						= 'QITEM',
    	['uri']							= 'uri',
    	--
    	-- Translate all the following arguments:
    	-- Arguments linked to the main module
    	lastname						= 'name',
    	lastname_descr					= "Family name. Please specify to correct the sort key.",
    	firstname						= 'firstname',
    	firstname_descr					= "First name. Please specify to correct the sort key.",
    	firstname2						= 'firstname',
    	firstname2_descr				= "First name. Please specify to correct the sort key.",
    	initial							= 'initial',
    	initial_descr					= "Initial to correct the category of authors.",
    	title							= 'title',
    	title_descr						= "Page title, automatic.",
    	country							= 'country',
    	flag_of_country					= 'Flag of England.svg',
    	flag_of_country_descr			= 'Flag of the country',
    	occupation_cat					= '%1',
    	year_number_cat					= "Year %1",
    	-- birth and death
    	birthday						= 'birthday', -- birthday P569
    	birthday_descr					= "Day of birth.",
    	birthyear						= 'birthyear',
    	birthyear_descr					= "Year of birth.",
    	p_authors_birthyear_cat			= "%1 births",
    	deathday						= 'deathday', -- deathyear P570
    	deathday_descr					= "Day of death.",
    	deathyear						= 'deathyear',
    	deathyear_descr					= "Year of death.",
    	p_authors_deathyear_cat			= "%1 births",
    	description						= 'description',
    	description_descr				= "Description of the author, to clarify if the automatic description does not fit.",
    	description						= 'description',
    	description_descr				= "Author's description, to clarify whether the automatic description does not fit.",
    	-- Arguments limited to multiple values
    	region							= 'region', -- argument with verified multiple values
    	region_descr					= 'Region to determine the ancient periods.',
    	region_values					= 'other;china;india;century', -- wiki_selectors
    
    	rights							= 'rights',
    	rights_descr					= "Necessary copyrights type: 70,50,mpf,ONU,non.",
    	rights_values					= '70;50;mpf;ONU;none',
    
    	sex								= 'sex',
    	sex_descr						= 'Genre of the author',
    	sex_values						= 'male;female',
    } -- p.i18n.en
    
    p.i18n.es = { -- Translations in espagnol
    	-- Importar estos argumentos. No traducir.
    	["modules_guide"] = { ["typ"]	= "ctr", ["need"] = 0, ["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	['p_template_drop_box_name']	= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	['c']							= 'c',
    	['mode']						= 'mode',
    	['options']						= 'options',
    	['itemid']						= 'itemid',
    	['QITEM']						= 'QITEM',
    	['uri']							= 'uri',
    	--
    	-- Traducir todos los los argumentos siguientes:
    	-- Argumentos relacionados con el módulo principal
    	occupation_cat					= '%1',
    	p_authors_deathyear_cat			= "Autores-%1",
    	year_number_cat					= "Año %1",
    	-- Nombres y descripciones de los argumentos
    	lastname						= 'nombre',
    	lastname_descr					= "Nombre. Por favor, especifique para corregir la clave de ordenación.",
    	firstname						= 'apellido',
    	firstname_descr					= "Primero. Proponer para corregir la autómata.",
    	firstname2						= 'primero',
    	firstname2_descr				= "Primero. Proponer para corregir la autómata.",
    	initial							= 'inicial',
    	initial_descr					= "Inicial para corregir la categoría de los autores.",
    	title							= 'titulo',
    	title_descr						= "Título de la página, automático.",
    	country							= 'país',
    	flag_of_country					= 'Flag_of_Spain.svg',
    	flag_of_country_descr			= 'Bandera del país',
    	-- nacimiento y muerte
    	birthday						= 'nacimientodía', -- nacimiento P569
    	birthday_descr					= "Día de nacimiento.",
    	birthyear						= 'nacimientoaño',
    	birthday_descr					= "Año de nacimiento.",
    	p_authors_birthyear_cat			= "N%1", -- es.wikisource N1802 - F1885
    	deathday						= 'muertedía', -- muerte P570
    	deathday_descr					= "Día de muerte",
    	deathyear						= 'muerteaño',
    	deathyear_descr					= "Año de muerte",
    	p_authors_deathyear_cat			= "F%1", -- es.wikisource N1802 - F1885
    	description						= 'descripcion',
    	description_descr				= "Descripción del autor, para aclarar si la descripción automática no encaja.",
    
    	-- Argumentos limitados a múltiples valores
    	region							= 'región',
    	region_descr					= 'Región para determinar los tiempos antiguos.',
    	region_values					= "otro;china;india;siglo",
    
    	rights							= 'derechos',
    	rights_descr					= "Tipo de derechos de autor necesario: 70,50,mpf,ONU,non.",
    	rights_values					= '70;50;mpf;ONU;no',
    
    	sex								= 'sex',
    	sex_descr						= 'Género del autor',
    	sex_values						= 'hombre;mujer',
    } -- p.i18n.es
    
    p.i18n.fr = { -- Translations in français
    	-- Arguments to import, do not translate. Arguments à importer, ne pas traduire.
    	["modules_guide"] = { ["typ"]	= "ctr", ["need"] = 0, ["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	['p_template_drop_box_name']	= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	['c']							= 'c',
    	['mode']						= 'mode',
    	['options']						= 'options',
    	['itemid']						= 'itemid',
    	['QITEM']						= 'QITEM',
    	['uri']							= 'uri',
    	--
    	-- Translate all next arguments. Traduire tous les arguments suivants :
    	-- Arguments liés au module principal
    	occupation_cat					= '%1',
    	p_authors_deathyear_cat			= "Auteurs-%1",
    	year_number_cat					= "Année %1",
    	-- Noms et descriptions des arguments
    	lastname						= 'nom',
    	lastname_descr					= "Nom. A préciser pour corriger la clé de tri.",
    	firstname						= 'prénom',
    	firstname_descr					= "Prénom. A préciser pour corriger la clé de tri.",
    	firstname2						= 'prenom',
    	firstname2_descr				= "Prénom. A préciser pour corriger la clé de tri.",
    	initial							= 'initiale',
    	initial_descr					= "Initiale pour corriger les catégories d'ateurs.",
    	title							= 'titre',
    	title_descr						= "Titre de la page, automatique.",
    	country							= 'pays',
    	flag_of_country					= 'Flag_of_France.svg',
    	flag_of_country_descr			= 'Drapeau du pays',
    
    	-- naissance et deces
    	birthday						= 'jourNaissance', -- nacimiento P569
    	birthday_descr					= "Jour de naissance.",
    	birthyear						= 'anneeNaissance',
    	birthyear_descr					= "Année de naissance",
    	p_authors_birthyear_cat			= "Naissance en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	deathday						= 'jourDeces', -- muerte P570
    	deathday_descr					= "Jour de décès",
    	deathyear						= 'anneeDeces',
    	deathyear_descr					= "Année de décès",
    	p_authors_deathyear_cat			= "Décès en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	description						= 'description',
    	description_descr				= "Description de l'auteur, à préciser si la description automatique ne convient pas",
    	--
    	-- Arguments limités à des valeurs multiples
    	region							= 'région',
    	region_descr					= 'Région pour déterminer les époques anciennes.',
    	region_values					= "autre;chine;inde;siècle", -- wiki_selectors
    
    	rights							= 'droits',
    	rights_descr					= "Type de droits d'auteur nécessaire parmi : 70,50,mpf,ONU,non.",
    	rights_values					= '70;50;mpf;ONU;non',
    
    	sex								= 'sexe',
    	sex_descr						= "Sexe de l'auteur",
    	sex_values						= 'homme;femme',
    } -- p.i18n.fr
    
    p.i18n.vi = {
    	-- Arguments to import, do not translate. Arguments à importer, ne pas traduire.
    	["modules_guide"] = { ["typ"]	= "ctr", ["need"] = 0, ["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	['p_template_drop_box_name']	= 'Boîte déroulante', -- Modèle:Boîte déroulante for drop_box.form
    	['c']							= 'c',
    	['mode']						= 'mode',
    	['options']						= 'options',
    	['itemid']						= 'itemid',
    	['QITEM']						= 'QITEM',
    	['uri']							= 'uri',
    	--
    	-- Translate all next arguments. Traduire tous les arguments suivants :
    	-- Arguments liés au module principal
    	occupation_cat					= '%1',
    	p_authors_deathyear_cat			= "Auteurs-%1",
    	year_number_cat					= "Année %1",
    	-- Noms et descriptions des arguments
    	lastname						= 'nom',
    	lastname_descr					= "Nom. A préciser pour corriger la clé de tri.",
    	firstname						= 'prénom',
    	firstname_descr					= "Prénom. A préciser pour corriger la clé de tri.",
    	firstname2						= 'prenom',
    	firstname2_descr				= "Prénom. A préciser pour corriger la clé de tri.",
    	initial							= 'initiale',
    	initial_descr					= "Initiale pour corriger les catégories d'ateurs.",
    	title							= 'titre',
    	title_descr						= "Titre de la page, automatique.",
    	country							= 'pays',
    	flag_of_country					= 'Flag_of_France.svg',
    	flag_of_country_descr			= 'Drapeau du pays',
    
    	-- naissance et deces
    	birthday						= 'jourNaissance', -- nacimiento P569
    	birthday_descr					= "Jour de naissance.",
    	birthyear						= 'anneeNaissance',
    	birthyear_descr					= "Année de naissance",
    	p_authors_birthyear_cat			= "Naissance en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	deathday						= 'jourDeces', -- muerte P570
    	deathday_descr					= "Jour de décès",
    	deathyear						= 'anneeDeces',
    	deathyear_descr					= "Année de décès",
    	p_authors_deathyear_cat			= "Décès en %1", -- fr.wikisource Naissance en 1802 Décès en 1885
    	description						= 'description',
    	description_descr				= "Description de l'auteur, à préciser si la description automatique ne convient pas",
    	--
    	-- Arguments limités à des valeurs multiples
    	region							= 'région',
    	region_descr					= 'Région pour déterminer les époques anciennes.',
    	region_values					= "autre;chine;inde;siècle", -- wiki_selectors
    
    	rights							= 'droits',
    	rights_descr					= "Type de droits d'auteur nécessaire parmi : 70,50,mpf,ONU,non.",
    	rights_values					= '70;50;mpf;ONU;non',
    
    	sex								= 'sexe',
    	sex_descr						= "Sexe de l'auteur",
    	sex_values						= 'homme;femme',
    } -- p.i18n.vi
    
    -- - - - ------------------ - - - - ---------------------------------
    -- p.i18n tables end
    -- - - - ------------------ - - - - ---------------------------------
    
    -- - - - ------------------ - - - - ---------------------------------
    -- Arguments table, to change in calling modules
    -- - - - ------------------ - - - - ---------------------------------
    
    p.args_known = { -- Table of the definitions of all known arguments at module level. -- ric (p.box_read)
    
    	-- Arguments in order without names, with their keyword for use as other arguments.
    	-- Arguments dans l'ordre, non nommés, avec leur keyword pour traitement comme les autres arguments.
    --	[1]					= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "mode", ["syn"] = 2},
    
    	-- Guideline to integer i18n translations following a list of sub-modules: modules_guide with their own translations.
    	-- Guideline to integer default arguments values: defaults values are always from Centralizer.
    	-- Guideline for default arguments values: each main_module can replace any option of any argument from Centralizer.
    	-- Guideline for these changes: Centralizer is always protected against any change.
    	--
    	-- Special arguments to modify the fonctions and outputs of this module.
    	-- Arguments speciaux pour modifier le fonctionnement et les sorties de ce module.
    	["modules_guide"]	= { ["typ"] = "ctr",	["need"] = 0,	["keyword"] = "modules_guide", ["modules_guide_default"] = "Centralizer", },
    	["category"]		= { ["typ"] = "ctr",	["need"] = 0,	["keyword"] = "category"},
    	["debug"]			= { ["typ"] = "opt",	["need"] = 0,	["keyword"] = "debug"},
    	["c"]				= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "c"},
    	["docfunc"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "docfunc"},
    	["docitem"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "docitem"},
    	["dockey"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "dockey"},
    	["itemid"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "itemid"}, -- Property:P2959 points to a double of the item.
    	["mode"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "mode"},
    	["options"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "options"},
    	["knownversions"]	= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "knownversions"},
    	["soughtversions"]	= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "soughtversions"},
    	["contentlang"]		= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "contentlang"},
    	["pagelang"]		= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "pagelang"},
    	["userlang"]		= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "userlang"},
    	["args_known_country"]	= { ["typ"] = "dat", ["need"] = 0,	["keyword"] = "args_known_country",	["prop"] = "P18", },
    	["args_known_flag"]		= { ["typ"] = "dat", ["need"] = 0,	["keyword"] = "args_known_flag",	["prop"] = "P18", },
    	["args_known_monument"]	= { ["typ"] = "dat", ["need"] = 0,	["keyword"] = "args_known_monument",["prop"] = "P18", },
    	["args_known_town"]		= { ["typ"] = "dat", ["need"] = 0,	["keyword"] = "args_known_town",	["prop"] = "P18", },
    	
    --[[
    	datas.i18n.en
    	args_known_country						= "London", -- English
    	args_known_flag							= "flag of English.svg", -- English
    	args_known_monument						= "St Paul Cathedral.png", -- English
    	args_known_town							= "London", -- English
    	
    	datas.i18n.es
    	args_known_country						= "Madrid", -- Spanish
    	args_known_flag							= "flag of .......png", -- Spanish
    	args_known_monument						= "parliament.png", -- Spanish
    	args_known_town							= "Madrid", -- Spanish
    	
    	datas.i18n.fr
    	args_known_country						= "France", -- French
    	args_known_flag							= "flag of France.svg", -- French
    	args_known_monument						= "Tour Eiffel", -- French
    	args_known_town							= "Paris", -- French
    --]]
    	
    --[[
    	for key, trans in pairs(langs.content_translations) do -- Add to function datas.get_item(
    		if key == "args_known_country" then datas.prop["country"] = langs["args_known_country"] end
    		if key == "args_known_flag" then datas.prop["country"] = langs["args_known_flag"] end
    		if key == "args_known_monument" then datas.prop["monument"] = langs["args_known_monument"] end
    		if key == "args_known_town" then datas.prop["town"] = langs["args_known_town"] end
    	end
    --]]
    	-- All arguments have a keyword identical to the registration name, except synonyms.
    	-- Tous les arguments ont un keyword identique au nom d'enregistrement, sauf les synonymes.
    	["image"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "image",		["prop"] = "P18", },
    	["country"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "country",	["prop"] = "P27", },
    	["birthyear"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "birthyear",	["prop"] = "P569", ["format"] = "year", },
    	["deathyear"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "deathyear",	["prop"] = "P570", ["format"] = "year", },
    	["lastname"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", },
    	["lastname2"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "lastname",	["prop"] = "P734", ["syn"] = 2, },
    	["firstname"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "firstname",	["prop"] = "P735", },
    	["firstname2"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "firstname",	["prop"] = "P735", ["syn"] = 2, },
    	["initial"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "initial",	["prop"] = "P735", },
    	["title"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "label",		["prop"] = "P735", ["syn"] = 2, },
    	["personlang"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "personlang", ["prop"] = "P1412", },
    	["description"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "description",["prop"] = "description", },
    	["label"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "label" ,		["prop"] = "label", ["prop_default"] = "Aristote", },
    	["labelcontent"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "labelcontent",["prop"] = "labelcontent", },
    	["labelpage"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "labelpage",	["prop"] = "labelpage", },
    	["labeluser"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "labeluser",	["prop"] = "labeluser", },
    	["labelbylang"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "labelbylang",["prop"] = "labelbylang", },
    	["QITEM"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "QITEM",		["prop"] = "QITEM", ["prop_default"] = "Q307", }, -- Galilée
    --	Galilée (Q307), Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322),
    --	Nelson Mandela (Q8023), Rudyard Kipling (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772)
    	["sitelink"]		= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "sitelink",	["prop"] = "sitelink", },
    	["uri"]				= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "uri",		["prop"] = "uri", },
    	["sex"]				= {["keyword"] = "sex", ["typ"] = "dat",	["need"] = 0, ["prop"] = "P21",
    		["arg_values"] = "sex_values",	  ["key_values"] = "male;femelle", }, -- wiki_selectors
    	["region"]			= {["keyword"] = "region", ["typ"] = "dat", ["need"] = 0,
    		["arg_values"] = "region_values", ["key_values"] = "other;china;india;century" }, -- wiki_selectors
    	["rights"]			= {["keyword"] = "rights", ["typ"] = "dat", ["need"] = 0,
    		["arg_values"] = "rights_values", ["key_values"] = "no;none;ONU;none;cn;50;us;70;mpf", -- wiki_selectors
    		["delay_values"] = "0;0;0;0;50;50;70;70;95", ["arg_uses"] = "none;none;none;none;cn;cn;us;us;mpf" }, -- wiki_selectors
    	["args_known_monument"]	= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "args_known_monument",	["prop"] = "P18", },
    	["labelbylang"]			= { ["typ"] = "dat",	["need"] = 0,	["keyword"] = "labelbylang",			["prop"] = "P18", },
    --	args_known_monument						= "Tour Eiffel", -- French
    --	args_known_town							= "Paris", -- French
    } -- #p.args_known = 29 on 2018-01-15
    
    function p.form_support_desk_report(t) return versions.form_support_desk_report(t) end
    
    function versions.form_support_desk_report(t) -- Formats the detailed Versions report
    	local memo = viewers.save_configs("versions.form_support_desk_report") -- Save global configuration before eventual changes.
    	local report_main_discreet = versions.report_main_discreet or " report_main_discreet missing "
    	local t = t or ""
    	t = t .. "\n* Discreet main version: " .. viewers.discreet_main_version() -- .. form_support_desk_report
    	local version = p.version or {}
    	t = t .. "\n* Description of the Module:Centralizer version: " .. viewers.ta("versionName", version.versionName) .. viewers.ta("versionNumber", version.versionNumber) .. viewers.ta("versionDate", version.versionDate)
    	t = t .. "\n* The structure of the Module:Centralizer versionNumber is <code>yymmdd:hh:mm</code>."
    	t = t .. "\n* " .. viewers.ta("Main module Description", version.mainDescription) .. viewers.ta("function", version.functionDescription) .. viewers.ta("task", version.taskDescription)
    	t = t .. "\n* MediaWiki_version: " .. versions.MediaWiki_version() -- Formats MediaWiki_version, in error color if it changes.
    	t = t .. "\n*" .. langs.main_i18n_languages_list() -- Lists available translations in available languages.
    	t = t .. "\n* Start versions from the main module: " .. (versions.bind_verif_modules_report_start or " bind_verif_modules_report_start missing ")
    	t = t .. versions.versions_management_report()
    	t = t .. versions.sort_central_modules_report()
    	t = t .. versions.running_times()
    --	Inside the viewer drop_box.form(), a function in test or in report has a nil result
    	viewers.restore_configs(memo, "versions.form_support_desk_report") -- Restore global configurations after eventual changes.
    	return t, details
    end
    
    function p.form_tests_init(res, args_source)
    -- Special init for the test mode
    	if type(res) ~= "string" then res = "\n* Mode test : " end
    	if type(args_source) ~= "table" then args_source = modes.args_source or {} end
    	if p.i18n and p.i18n.en then p.i18n.en.error_i18n_wanted_to_test_missing_translation = 'English error i18n wanted for tests missing translation' end
    	if p.i18n and p.i18n.es then p.i18n.es.error_i18n_deseada_para_probar_traduccion_faltan = 'Espagnol error i18n deseada para probar traducción faltan' end
    	if p.i18n and p.i18n.fr then p.i18n.fr.error_i18n_voulue_pour_test_de_traduction_manquante = 'Français erreur i18n voulue pour tests de traduction manquante' end
    --	if not args_source.userlang then args_source.userlang = "en" end
    --	if not args_source.contentlang then args_source.contentlang = "es" end
    	if not args_source.modeinvoke then args_source.modeinvoke = "catview" end
    	if not args_source.mode_invoke then args_source.mode_invoke = "catview" end
    	if not args_source.template_options then args_source.template_options = "catview" end
    	if not args_source.name then args_source.name = "Jack Smith" end
    	if not args_source.nom then args_source.nom = "Victor Hugo" end
    	if not args_source.region then args_source.region = "india" end
    	if not args_source["région"] then args_source["région"] = "chine" end
    	if not args_source.description then args_source.description = "Victor Hugo est très connu." end
    	if not args_source.langue then args_source.langue = "français,japonais" end
    	if not args_source.occupation then args_source.occupation = "Académiciens,Personnalités politiques" end
    	modes.args_source = args_source
    	return res
    end -- function p.form_tests_init(res, args_source)
    
    function p.interact_args_final(args_import, args_known)
    	local t = ""
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = { -- }
    	if type(args_import) ~= "table" then args_import = modes.args_import or {} end
    	local args_final = mw.clone(args_import) -- do not disturb original args_import
    	local a = args_import
    	local i = {} -- interact
    	datas.prop_default = datas.prop_default or "Q307" -- keep Galilée (Q307)
    	local tit = nil
    	if not a.title then -- If title is undefined, enforce it.
    		if a.lastname and a.firstname then
    			tit = a.firstname .. " " .. a.lastname
    		end
    		i.title = a.label or modes.main_title or a.QITEM or a.itemid or a.title or datas.prop_default
    	end
    	--
    	if a.docfunc then a.docfunc = mw.text.trim(a.docfunc) end -- dockey docitem args_known = { i18n.vi
    	if a.docitem then a.docitem = mw.text.trim(a.docitem) end -- dockey docitem args_known = { i18n.vi
    	if a.dockey then a.dockey = mw.text.trim(a.dockey) end -- dockey docitem args_known = { i18n.vi
    	if not a.QITEM then -- The Title can come from several arguments to insure it.
    		i.QITEM = a.label or modes.main_title or a.QITEM or a.itemid or a.title
    		i.QITEM = mw.text.trim(i.QITEM or datas.prop_default) -- Rudyard Kipling
    	else
    		a.QITEM = a.QITEM or datas.default_item
    		a.QITEM = mw.text.trim(a.QITEM)
    	end
    	--
    	-- if absent, synonym of basic arguments, syn = 2
    	if not a.firstname then i.firstname = (i.firstname2 or a.firstname2) end
    	if not a.lastname then i.lastname = (i.lastname2 or a.lastname2) end
    	if not a.firstname2 then i.firstname2 = (i.firstname or a.firstname) end
    	if not a.lastname2 then i.lastname2 = (i.lastname or a.lastname) end
    	--
    	if not a.initial then -- If initial is undefined, enforce it.
    		if a.lastname then
    			i.initial = string.sub( a.lastname, 1, 1 ) -- selector the first letter
    			i.initial = string.upper( i.initial or "*" )
    		end
    	end
    	--
    	local label = a.label or a.labeluser or a.labelpage or a.labelcontent or a.labelbylang
    	if label then i.label = label
    	else
    		events.add_err( viewers.form9user("versions_with_internal_error") )
    		events.add_cat( viewers.form9user("versions_with_internal_error_cat") )
    	end
    	--
    	if a.birth and not a.birthyear then
    		local tt, err = viewers.date_to_part(a.birth, viewers.form9user("modes_date_to_part_format"), "yyyy")
    		if tt then i.birthyear = tt else
    			events.add_err(err, viewers.form9user("birthyear"), "yyyy")
    			events.add_cat("modes_date_to_part_call_cat")
    		end
    	end
    	-- memorize interactions in modes.args_final and show errors or warnings
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	local n = 0
    	for key, val in pairs(i) do
    		local argskwn = args_known[key]
    		if type(argskwn) == "table" then
    			args_final[key] = val -- = i[key]
    			args_final.src = "inter"
    			n = n + 1
    			if (args_final.need == 2) and not a[key] then --
    				-- need = 2 necessary from argument or module interaction
    				events.add_wng("modes_auto_val_warning_wng", langs.user_translations[key], val) -- form_result
    			end
    		else
    			events.add_err("modes_unknown_auto_arg_err", langs.content_translations[key], val)
    		end
    	end
    	modes.args_final = args_final
    	return args_final, t
    end --	args_final = p.interact_args_final(args_import)
    
    
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    -- Interfaces, alias and functions to templates
    -- Interfaces, alias y funciones para modelos
    -- Interfaces, alias et fonctions pour les modèles
    -- - - - ------------------ - - - - ---------------------------------
    -- - - - ------------------ - - - - ---------------------------------
    
    function Central.install(frame, Central_version, mode_name, args_known, options_for_modes)
    --	p.version.versionNumber = CentralI18N.version.versionNumber
    	local res = ""
    	return "\n* ARGS.t=" .. tostring(ARGS.t) .. ", CNT.t=" .. tostring(CNT.t)
    end
    
    function Central.demo(frame, Central_version, mode_name, args_known, options_for_modes)
    --	p.version.versionNumber = CentralI18N.version.versionNumber
    	local res = ""
    	return "\n* ARGS.t=" .. tostring(ARGS.t) .. ", CNT.t=" .. tostring(CNT.t)
    end
    
    function Central.init(frame, Central_version, mode_name, args_known, options_for_modes)
    --	p.version.versionNumber = CentralI18N.version.versionNumber
    	local res = ""
    	tracker.init_trakers() -- Initialize some trakers. To run in Central.init()
    	modes.time1 = os.clock()
    	local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = {...}
    	Central_version = Central_version or langs.Central_version or Central.Central_version
    	local options_for_modes = options_for_modes or modes.options_for_modes or p.options_for_modes
    	res = res .. versions.init(frame, Central_version)
    	versions.memo_i18n = mw.clone(versions.main_i18n or langs.main_i18n)
    	langs.main_i18n = versions.memo_i18n ; versions.main_i18n = versions.memo_i18n
    --	local datas = mw.clone(datas)
    	res = res .. modes.init_modes_translate_events(frame, Central_version, mode_name, modes.args_known, options_for_modes, QITEM or itemid)
    	datas.props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page.
    	modes.init_args_mode_options(mix, mode_name, modes.args_template) -- Import and mix args mode and options from template and invoke -- S170710mix
    	modes.args_import = modes.import_arguments(args_known, args_source, content_translations, args_wikidata) -- function modes.import_arguments()
    	modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments
    	modes.get_args(args_known) -- Interactions between arguments
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	res = res .. (datas.props_trk or "")
    	res = res .. "</b>"
    --	p.version.versionNumber = CentralI18N.version.versionNumber
    	return res
    end -- function Central.init(frame, Central_version, mode_name, args_known, options_for_modes)
    
    function Central.read(frame) -- The read mode generates the normal result for read only users.
    	-- Helpers or admins can add options to include edit or tests or user language...
    	local res = ""
    	local t = Central.init(frame, Central.Central_version, "read", p.args_known, p.options_for_modes)
    --	res = res .. t
    	modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments
    	res = res .. p.form_result(modes.args_final)
    	res = res .. "\n* " .. datas.track_val
    	return res
    end -- function Central.read(frame)
    
    function Central.edit(frame) -- The edit mode verifies arguments, displays the edit panel with errors, warnings and categories.
    	local res = "</b>"
    	res = res .. "Library:langs"
    	local t = Central.init(frame, Central.Central_version, "edit", p.args_known, p.options_for_modes)
    --	res = res .. t
    	modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts
    	res = res .. "</b>"
    	res = res .. p.form_result(modes.args_final)
    	return res
    end -- function Central.edit(frame)
    
    --	["docfunc"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "docfunc"},
    --	["docitem"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "docitem"},
    --	["dockey"]			= { ["typ"] = "config", ["need"] = 0,	["keyword"] = "dockey"},
    function Central.doc(frame) -- Formats a documentation or a test in a drop_box.
    	local res = ""
    	Central.init(frame, p.Module_Central_version, "doc", p.args_known, p.options_for_modes) -- QITEM
    	langs.init_content_page_user_lang() -- function langs.init_content_page_user_lang()
    	modes.change_itemid() -- default = "Q41568"
    	modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts
    --	{{Central|doc|versions_support_desk_title}}
    	local docfunc = modes.args_final.docfunc or modes.args_final[3] or modes.args_import.docitem or modes.args_import[3]
    	local docitem = modes.args_final.docitem or modes.args_final[2] or modes.args_import.docitem or modes.args_import[2] or datas.default_item
    	local dockey = modes.args_final.dockey or modes.args_final[1] or modes.args_import.dockey or modes.args_import[1]
    	local QITEM = modes.args_final.QITEM or modes.args_final.docitem or docitem
    	QITEM = mw.text.trim(QITEM) -- clean spaces in each name
    	if dockey then
    		local selector = mw.text.trim(dockey)
    	end
    	return res
    end -- function Central.doc(frame)
    
    function Central.tests(frame)
    	local res = ""
    	res = res .. tracker.init_trakers() -- Initialize some trakers. To run in Central.init()
    	local t = Central.init(frame, Central.Central_version, "tests", p.args_known, p.options_for_modes)
    	res = res .. t
    --	res = res .. "\n* getEntityIdForCurrentPage = " .. tostring( mw.wikibase.getEntityIdForCurrentPage() ) -- Returns the Item id as string, like "Q42"
    	p.form_tests_init()
    	modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments
    	langs.init_content_page_user_lang(a, b, c, d, "Central.tests")
    	versions.main_versions = versions.main_versions or { versionName = "versionName", versionNumber = "0.0", }
    	if not versions.main_versions then versions.main_versions = p.version or versions.version end
    	modes.mode_name = "tests"
    	res = res .. p.form_result(modes.args_final) -- Generate wikitext, categories, and others
    --	res = res .. viewers.try_graph()
    	return res
    end -- function Central.tests(frame)
    
    function versions.detect_MediaWiki_changes()
    --	Could record MediaWiki_Versions in Special:PageData T163923
    	local t = t or "\n* <b>versions.record_mw_changes()</b> : Detect, record and report all date-time changes of MediaWiki, in each wiki."
    	versions.site_currentVersion = mw.site.currentVersion
    	versions.MediaWiki_version_memo = vers
    	if mw.site.currentVersion == versions.MediaWiki_version_memo
    	then versions.site_currentVersion_view = viewers.styles_color_discreet(versions.site_currentVersion)
    	else versions.site_currentVersion_view = viewers.styles_color_error(versions.site_currentVersion) end
    	t = t .. "\n* See also the [https://www.MediaWiki.org/wiki/Manual:Substitution MediaWiki Manual:Substitution]."
    	return "" -- t
    end -- function versions.detect_MediaWiki_changes()
    
    --	Last MediaWiki-Wikisource update/upgrade versions:
    --	Seen and recorded at each preview to test fr.wikisource.org/wiki/Module:Centralizer-s-fr
    --	French time UTC +1 or +2
    --	See ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 shift hours) = 1977-04-22T06:00:00Z local time
    
    versions.MediaWiki_Versions_sort = ">"
    versions.MediaWiki_Versions = {
    	--	KEEP FIRST VERSIONS
    	{ site = "fr.wikisource", verstime = "2016-06-19", versid = "2016-06-19", seen_time = "2016-06-19", },
    	{ site = "fr.wikisource", verstime = "2017-05-11T00:48:00", versid = "1.29.0-wmf.21 (d6c07d1)", seen_time = "2017-05-11T00:48:00-00:00",
    		task = "T165000", title = "The version date of MW 1.29.0-wmf.21 (d6c07d1) is in the future !",
    		report = "Rical: Schedule in https://www.MediaWiki.org/wiki/MediaWiki_1.29/Roadmap", },
    	--	function versions.detect_MediaWiki_changes() display only 3 last months
    	{ site = "fr.wikisource", verstime = "2018-01-02T18:49:06", versid = "1.31.0-wmf.15 (8e46998)", seen_time = "2018-01-04T14:20:00", },
    	{ site = "fr.wikisource", verstime = "2018-01-04T21:47:05", versid = "1.31.0-wmf.15 (601cf9d)", seen_time = "2018-01-07T18:30:00", },
    	{ site = "fr.wikipedia", verstime = "2018-01-07T20:46:36", versid = "1.31.0-wmf.15 (0953700)", seen_time = "2018-01-09T20:57:00", },
    	{ site = "fr.wikisource", verstime = "2018-01-07T20:46:36", versid = "1.31.0-wmf.15 (0953700)", seen_time = "2018-01-12T07:43:00", },
    	{ site = "fr.wikisource", verstime = "2017-12-15T23:35:09", versid = "1.31.0-wmf.16 (a31d45c)", seen_time = "2018-01-12T07:43:00",
    		task = "T155624", title = "In wikisource/Spécial:Version:wmf.15 (0953700) but Central module mw = 1.31.0-wmf.16 (a31d45c) seen by Rical.", },
    	{ site = "www.MediaWiki", verstime = "2018-01-11T20:29:30", versid = "1.31.0-wmf.16 (ab6bf1f)", seen_time = "2018-01-13T06:11:00", },
    	{ site = "fr.wikisource", verstime = "2018-01-16T18:33:22", versid = "1.31.0-wmf.16 (d3c472e)", seen_time = "2018-01-17T06:59:00", },
    	{ site = "www.MediaWiki", verstime = "2018-01-16T21:16:44", versid = "1.31.0-wmf.17 (d543eb9)", seen_time = "2018-01-17T06:59:00", },
    	{ site = "fr.wikisource", verstime = "2018-01-18T01:23:03", versid = "1.31.0-wmf.17 (d8c8c31)", seen_time = "2018-01-19T08:16:00", },
    	{ site = "fr.wikisource", verstime = "2018-01-29T20:37:52", versid = "1.31.0-wmf.17 (dfc8ff3)", seen_time = "2018-02-02T19:19:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-05T21:33:14", versid = "1.31.0-wmf.17 (b34e25b)", seen_time = "2018-02-06T23:40:00", },
    	{ site = "www.MediaWiki", verstime = "2018-02-06T19:00:03", versid = "1.31.0-wmf.20 (5bcccb0)", seen_time = "2018-02-07T00:14:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-12T17:50:32", versid = "1.31.0-wmf.20 (11f1e9c)", seen_time = "2018-02-13T10:38:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-13T19:40:36", versid = "1.31.0-wmf.21 (5e7beec)", seen_time = "2018-02-14T20:47:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-16T01:11:36", versid = "1.31.0-wmf.21 (828e6cc)", seen_time = "2018-02-18T05:17:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-23T21:50:11", versid = "1.31.0-wmf.22 (fd29ac3)", seen_time = "2018-02-23T21:28:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-26T20:32:35", versid = "1.31.0-wmf.22 (d5c267c)", seen_time = "2018-02-28T23:04:00", },
    	{ site = "fr.wikisource", verstime = "2018-02-27T18:48:39", versid = "1.31.0-wmf.23 (82d9536)", seen_time = "2018-03-03T21:13:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-06T02:30:14", versid = "1.31.0-wmf.23 (f46c818)", seen_time = "2018-03-06T08:04:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-06T19:10:12", versid = "1.31.0-wmf.24 (52b67ec)", seen_time = "2018-03-08T11:30:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-10T00:19:55", versid = "1.31.0-wmf.24 (6e6b5d9)", seen_time = "2018-03-13T10:30:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-14T12:21:45", versid = "1.31.0-wmf.25 (02e257c)", seen_time = "2018-03-15T21:47:00", },
    	{ site = "www.MediaWiki", verstime = "2018-03-20T20:46:55", versid = "1.31.0-wmf.25 (18911f8)", seen_time = "2018-03-20T08:00:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-20T20:36:33", versid = "1.31.0-wmf.26 (68b8563)", seen_time = "2018-03-22T18:22:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-26T15:13:22", versid = "1.31.0-wmf.26 (c3296c8)", seen_time = "2018-03-22T26:22:00", },
    	{ site = "www.MediaWiki", verstime = "2018-03-27T21:01:26", versid = "1.31.0-wmf.27 (06af291)", seen_time = "2018-03-28T21:01:00", },
    	{ site = "fr.wikisource", verstime = "2018-03-27T21:01:26", versid = "1.31.0-wmf.27 (06af291)", seen_time = "2018-04-02T21:10:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-03T21:17:25", versid = "1.31.0-wmf.28 (80a1a33)", seen_time = "2018-04-04T20:10:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-05T22:06:11", versid = "1.31.0-wmf.28 (7fa86eb)", seen_time = "2018-04-06T21:07:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-10T19:18:04", versid = "1.31.0-wmf.29 (3125cb5)", seen_time = "2018-04-12T18:30:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-11T19:35:36", versid = "1.31.0-wmf.29 (e5d3ad6)", seen_time = "2018-04-15T05:39:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-17T15:36:44", versid = "1.31.0-wmf.29 (1cb7198)", seen_time = "2018-04-19T08:35:00", },
    	{ site = "www.MediaWiki", verstime = "2018-04-18T18:47:14", versid = "1.31.0-wmf.30 (e8360e8)", seen_time = "2018-04-19T08:35:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-23T16:34:41", versid = "1.31.0-wmf.30 (990d8c8)", seen_time = "2018-04-23T18:45:00", },
    	{ site = "fr.wikisource", verstime = "2018-04-24T01:11:27", versid = "1.31.0-wmf.30 (1865391)", seen_time = "2018-04-25T25:05:31", },
    	{ site = "www.MediaWiki", verstime = "2018-04-24T18:56:18", versid = "1.32.0-wmf.1 (d94bd0b)", seen_time = "2018-04-25T25:05:31", },
    	{ site = "fr.wikisource", verstime = "2018-04-26T22:59:23", versid = "1.32.0-wmf.1 (d5ae4d6)", seen_time = "2018-04-27T06:55:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-01T01:24:19", versid = "1.32.0-wmf.1 (1de2db9)", seen_time = "2018-05-02T04:23:00", },
    	{ site = "www.MediaWiki", verstime = "2018-05-01T22:12:54", versid = "1.32.0-wmf.2 (b0c908a)", seen_time = "2018-05-02T04:23:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-03T22:59:29", versid = "1.32.0-wmf.2 (bbd5b51)", seen_time = "2018-05-04T04:49:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-08T15:38:13", versid = "1.32.0-wmf.2 (fad297c)", seen_time = "2018-05-09T05:05:00", },
    	{ site = "www.MediaWiki", verstime = "2018-05-08T20:36:49", versid = "1.32.0-wmf.3 (5f8dcbf)", seen_time = "2018-05-09T05:05:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-09T17:53:16", versid = "1.32.0-wmf.3 (9809712)", seen_time = "2018-05-10T15:55:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-15T03:08:36", versid = "1.32.0-wmf.3 (e3cf869)", seen_time = "2018-05-15T07:12:36", },
    	{ site = "www.MediaWiki", verstime = "2018-05-15T19:45:34", versid = "1.32.0-wmf.4 (eb66f55)", seen_time = "2018-05-15T09:52:00", },
    	{ site = "www.MediaWiki", verstime = "2018-05-18T00:47:32", versid = "1.32.0-wmf.4 (54379d4)", seen_time = "2018-05-18T19:17:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-18T17:56:38", versid = "1.32.0-wmf.4 (cb4dbfb)", seen_time = "2018-05-22T08:40:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-22T15:16:13", versid = "1.32.0-wmf.4 (03a6eac)", seen_time = "2018-05-23T07:35:00", },
    	{ site = "www.MediaWiki", verstime = "2018-05-22T23:18:01", versid = "1.32.0-wmf.5 (82c3307)", seen_time = "2018-05-23T07:35:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-23T16:24:49", versid = "1.32.0-wmf.5 (fda06ee)", seen_time = "2018-05-24T05:19:00", },
    	{ site = "fr.wikisource", verstime = "2018-05-29T21:44:35", versid = "1.32.0-wmf.6 (54cd6f3)", seen_time = "2018-05-31T12:01:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-02T09:30:41", versid = "1.32.0-wmf.6 (22984c1)", seen_time = "2018-06-06T03:32:00", },
    	{ site = "www.MediaWiki", verstime = "2018-06-05T18:23:32", versid = "1.32.0-wmf.7 (3878394)", seen_time = "2018-06-06T03:32:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-02T09:30:41", versid = "1.32.0-wmf.6 (22984c1)", seen_time = "2018-06-06T17:15:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-07T01:13:36", versid = "1.32.0-wmf.7 (2e7183b)", seen_time = "2018-06-06T17:15:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-12T15:32:14", versid = "1.32.0-wmf.7 (c37c061)", seen_time = "2018-06-13T05:55:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-12T19:04:43", versid = "1.32.0-wmf.8 (645bb45)", seen_time = "2018-06-13T22:55:00", },
    	{ site = "www.MediaWiki", verstime = "2018-06-14T23:46:07", versid = "1.32.0-wmf.999 (b631ec6)", seen_time = "2018-06-15T06:45:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-15T00:14:44", versid = "1.32.0-wmf.8 (53a4a6c)", seen_time = "2018-06-15T06:45:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-25T16:34:52", versid = "1.32.0-wmf.8 (53a4a6c)", seen_time = "2018-06-26T13:25:00", },
    	{ site = "www.MediaWiki", verstime = "2018-06-25T16:35:25", versid = "1.32.0-wmf.999 (db8bc87)", seen_time = "2018-06-26T13:25:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-25T16:34:52", versid = "1.32.0-wmf.8 (6949e74)", seen_time = "2018-06-27T05:18:00", },
    	{ site = "www.MediaWiki", verstime = "2018-06-26T19:33:39", versid = "1.32.0-wmf.10 (dfc8825)", seen_time = "2018-06-27T05:18:00", },
    	{ site = "fr.wikisource", verstime = "2018-06-29T01:45:57", versid = "1.32.0-wmf.10 (02fc5f1)", seen_time = "2018-07-06T14:36:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-05T16:30:23", versid = "1.32.0-wmf.10 (4c30aa3)", seen_time = "2018-07-06T14:36:00", },
    	{ site = "www.MediaWiki", verstime = "2018-07-10T14:14:37", versid = "1.32.0-wmf.12 (490a345)", seen_time = "2018-07-11T07:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-10T14:48:52", versid = "1.32.0-wmf.10 (9b12f7f)", seen_time = "2018-07-11T07:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-17T13:26:15", versid = "1.32.0-wmf.12 (7c2cfe6)", seen_time = "2018-07-17T19:55:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-17T21:51:12", versid = "1.32.0-wmf.12 (eb2e8d4)", seen_time = "2018-07-18T07:15:00", },
    	{ site = "www.MediaWiki", verstime = "2018-07-18T01:25:01", versid = "1.32.0-wmf.13 (360f7b5)", seen_time = "2018-07-18T07:15:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-18T01:25:01", versid = "1.32.0-wmf.13 (360f7b5)", seen_time = "2018-07-19T15:58:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-23T23:26:55", versid = "1.32.0-wmf.13 (93bb3e9)", seen_time = "2018-07-26T10:00:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-24T18:08:34", versid = "1.32.0-wmf.14 (e2b3d28)", seen_time = "2018-07-24T14:53:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-25T06:10:28", versid = "1.32.0-wmf.13 (3b7d427)", seen_time = "2018-07-26T10:42:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-30T13:20:27", versid = "1.32.0-wmf.14 (bf3db55)", seen_time = "2018-07-30T16:10:00", },
    	{ site = "www.MediaWiki", verstime = "2018-07-31T21:50:01", versid = "1.32.0-wmf.14 (418983a)", seen_time = "2018-07-31T19:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-31T01:59:33", versid = "1.32.0-wmf.15 (ffb4e30)", seen_time = "2018-08-01T07:00:00", },
    	{ site = "fr.wikisource", verstime = "2018-07-31T21:50:01", versid = "1.32.0-wmf.15 (ffb4e30)", seen_time = "2018-08-01T20:25:00", },
    	{ site = "www.MediaWiki", verstime = "2018-08-02T01:32:39", versid = "1.32.0-wmf.14 (418983a)", seen_time = "2018-08-05T21:00:00", },
    	{ site = "www.MediaWiki", verstime = "2018-07-31T21:50:01", versid = "1.32.0-wmf.15 (ffb4e30)", seen_time = "2018-08-06T05:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-08-04T02:53:20", versid = "1.32.0-wmf.15 (376d0a8)", seen_time = "2018-08-08T14:41:00", },
    	{ site = "www.MediaWiki", verstime = "2018-08-07T21:19:02", versid = "1.32.0-wmf.16 (e818a98)", seen_time = "2018-08-08T14:41:00", },
    	{ site = "fr.wikisource", verstime = "2018-08-20T20:51:52", versid = "1.32.0-wmf.16 (29fbc92)", seen_time = "2018-08-16T21:27:00", },
    	{ site = "www.MediaWiki", verstime = "2018-08-15T13:21:49", versid = "1.32.0-wmf.16 (a1c7015)", seen_time = "2018-08-21T09:58:00", },
    	{ site = "www.MediaWiki", verstime = "2018-08-21T19:31:24", versid = "1.32.0-wmf.18 (857f494)", seen_time = "2018-08-22T17:43:00", },
    	{ site = "fr.wikisource", verstime = "2018-08-22T17:43:00", versid = "1.32.0-wmf.19 (c8515bc)", seen_time = "2018-09-05T08:50:00", },
    	{ site = "www.MediaWiki", verstime = "2018-09-04T16:39:41", versid = "1.32.0-wmf.20 (cee9956)", seen_time = "2018-09-05T08:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-05T03:33:38", versid = "1.32.0-wmf.20 (922ef6d)", seen_time = "2018-09-05T19:05:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-06T06:00:52", versid = "1.32.0-wmf.20 (879b2b2)", seen_time = "2018-09-12T08:46:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-11T23:18:09", versid = "1.32.0-wmf.20 (922ef6d)", seen_time = "2018-09-13T23:40:00", },
    	{ site = "www.MediaWiki", verstime = "2018-09-18T18:31:09", versid = "1.32.0-wmf.22 (5d33b6d)", seen_time = "2018-09-18T21:07:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-18T18:31:14", versid = "1.32.0-wmf.20 (8a97ce1)", seen_time = "2018-09-18T21:07:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-20T20:51:53", versid = "1.32.0-wmf.22 (2650d03)", seen_time = "2018-09-23T14:14:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-25T13:59:38", versid = "1.32.0-wmf.22 (53887ef)", seen_time = "2018-09-26T09:34:00", },
    	{ site = "www.MediaWiki", verstime = "2018-09-25T15:33:51", versid = "1.32.0-wmf.23 (c014536)", seen_time = "2018-09-26T09:34:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-26T17:35:06", versid = "1.32.0-wmf.23 (647d3c2)", seen_time = "2018-09-26T19:30:00", },
    	{ site = "fr.wikisource", verstime = "2018-09-27T13:36:13", versid = "1.32.0-wmf.23 (7081a55)", seen_time = "2018-09-27T15:15:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-03T02:36:46", versid = "1.32.0-wmf.23 (16a7864)", seen_time = "2018-10-03T20:32:00", },
    	{ site = "www.MediaWiki", verstime = "2018-10-03T18:21:13", versid = "1.32.0-wmf.24 (5fa193c)", seen_time = "2018-10-03T20:32:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-04T01:30:09", versid = "1.32.0-wmf.24 (4f66a3b)", seen_time = "2018-10-05T09:28:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-10T01:44:27", versid = "1.32.0-wmf.24 (9291e40)", seen_time = "2018-10-10T20:26:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-16T13:30:15", versid = "1.32.0-wmf.24 (35fb3b6)", seen_time = "2018-10-16T20:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-18T22:57:44", versid = "1.32.0-wmf.24 (35fb3b6)", seen_time = "2018-10-17T06:30:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-20T22:57:44", versid = "1.32.0-wmf.26 (06a4ac1)", seen_time = "2018-10-21T19:22:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-23T22:56:17", versid = "1.32.0-wmf.26 (abfc550)",	seen_time = "2018-10-24T06:10:00", },
    	{ site = "www.MediaWiki", verstime = "2018-10-24T00:34:34", versid = "1.33.0-wmf.1 (b1724ee)",	seen_time = "2018-10-24T06:10:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-26T01:30:57", versid = "1.32.0-wmf.1 (ef37e05)",	seen_time = "2018-10-27T09:38:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-29T00:33:47", versid = "1.33.0-wmf.1 (bdf45fc)",	seen_time = "2018-10-30T08:50:00", },
    	{ site = "www.MediaWiki", verstime = "2018-10-30T21:36:59", versid = "1.33.0-wmf.2 (f6c4f5f)",	seen_time = "2018-10-31T08:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-10-29T00:33:47", versid = "1.33.0-wmf.2 (1c41eef)",	seen_time = "2018-11-02T08:50:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-05T20:37:45", versid = "1.33.0-wmf.2 (b6abf62)",	seen_time = "2018-11-06T21:46:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-08T13:23:27", versid = "1.33.0-wmf.3 (d114665)",	seen_time = "2018-11-09T00:00:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-14T19:43:13", versid = "1.33.0-wmf.4 (967d9eb)",	seen_time = "2018-11-15T08:27:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-15T13:12:06", versid = "1.33.0-wmf.4 (b34307c)",	seen_time = "2018-11-17T07:35:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-19T20:59:49", versid = "1.33.0-wmf.4 (bf6a756)",	seen_time = "2018-11-21T06:04:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-27T11:28:27", versid = "1.33.0-wmf.4 (ebeab6e)",	seen_time = "2018-11-28T07:47:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-28T13:29:48", versid = "1.33.0-wmf.6 (19f2ad7)",	seen_time = "2018-11-29T08:35:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-29T14:08:43", versid = "1.33.0-wmf.6 (e5db35f)",	seen_time = "2018-11-29T21:51:00", },
    	{ site = "fr.wikisource", verstime = "2018-11-29T20:09:40", versid = "1.33.0-wmf.6 (e7d6fb2)",	seen_time = "2018-11-29T23:33:00", },
    	{ site = "fr.wikisource", verstime = "2018-12-13T01:34:02", versid = "1.33.0-wmf.8 (2859494)",	seen_time = "2018-12-17T08:33:00", },
    	{ site = "www.MediaWiki", verstime = "2018-12-18T14:22:32", versid = "1.33.0-wmf.9 (b5ca53a)",	seen_time = "2018-12-18T18:00:00", },
    	{ site = "fr.wikisource", verstime = "2018-12-19T17:52:30", versid = "1.33.0-wmf.9 (7cf3023)",	seen_time = "2018-12-20T09:07:00", },
    	{ site = "fr.wikisource", verstime = "2018-12-20T17:20:46", versid = "1.33.0-wmf.9 (02196d2)",	seen_time = "2018-12-20T21:04:00", },
    } -- MWMW   
    versions.MediaWiki_version_memo = "1.33.0-wmf.9 (02196d2)"
    versions.MediaWiki_Versions_sort = "<" -- First on end, Last on begin
    versions.MediaWiki_Versions_sort = ">" -- First on begin, Last on end
    --	function activity.MW_Versions_report(t) -- Reports versions of MediaWiki for 3 months.
    
    function viewers.doc_group(selector, mask_sections) -- function viewers.doc_internal(selector, mask_sections)
    	local res = ""
    	local selector = selector or "enforce"
    	local mask_sections = mask_sections or nil
    	if p.teststests == "FAMLTVQDR" then -- DODO
    		res = res .. "\n* Display : langs_main_i18n_languages_list and langs_list_MediaWiki_languages_title \n*"
    		res = res .. drop_box.new("enforce", "langs_main_i18n_languages_list", langs.main_i18n_languages_list ) -- OK, show in table ?
    		res = res .. drop_box.new("enforce", "langs_list_MediaWiki_languages_title", langs.list_MediaWiki_languages ) -- OK, show in table ?
    		res = res .. drop_box.new(selector, "p.teststests = FAMLTVQDR Init_mode_args_datas_tests **", modes.Init_mode_args_datas_tests )
    		res = res .. drop_box.new(selector, "modes Init Frame Args Mode Libraries **", p.init_central_module_tests)
    		res = res .. drop_box.new(selector, "modes_get_args_datas_tests_title", modes.get_args_datas_tests)
    		res = res .. viewers.doc_page(selector, mask_sections) -- mask for time limit function viewers.doc_page(
    		res = res .. viewers.doc_module(selector, mask_sections) -- mask for time limit
    		return res
    	else
    		res = res .. viewers.doc_section(selector, "Tests of this page", "h2", mask_sections) -- function viewers.doc_section(
    		res = res .. drop_box.new(selector, "activity_report_subtasks_title", activity.central_subtasks_report) -- to try if needed
    		res = res .. viewers.doc_page(selector, mask_sections) -- mask for time limit
    		res = res .. viewers.doc_module(selector, mask_sections) -- mask for time limit
    		res = res .. viewers.doc_internal(selector, mask_sections) -- function viewers.doc_internal(selector, mask_sections)
    		res = res .. versions.running_times(false, "")
    	end
    	return res
    end -- function viewers.doc_group(selector, mask_sections) item:
    
    return p
    
    --	Galilée (Q307), Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322),
    --	Nelson Mandela (Q8023), Rudyard Kipling or "Q (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772)
    --	local QITEM = datas.QITEM or datas.default_item
    --
    --	Tests pages on 2018-06-22 :
    --	MediaWiki:Scribunto/Central modules reference manual
    --	Auteur:Victor Hugo						-- ws.Module:Tpt (Q535)
    --	Module:Tests/Aristote					-- ws.Module:Tests (Q868)
    --	Utilisateur:Rical/Rudyard Kipling		-- ws.Module:Centralizer (Q34743)
    --	Utilisateur:Rical/Nelson Mandela		-- ws.Module:Tests (Q8023)
    --	Utilisateur:Rical/Nelson Mandela		-- ws.Module:Centralizer-s-fr (Q8023)
    --	Module:Centralizer-s-fr/Galilée			-- ws.Module:Centralizer (Q307)
    --
    --	Tests pages on 2018-07-24 :
    --	Patrom:TestsAuteur2Tpt					-- s.br.Patrom:TestsAuteur2Tpt for tests in Breton
    --	Patrom:Auteur2Tpt						-- s.br.Patrom:Auteur2Tpt as templete in Breton
    --	Modulenn:Auteur2Tpt-s-br				-- s.br.Modulenn:Auteur2Tpt as module itself in Breton
    --
    --	Mô đun:Centralizer-w-vi					-- w.vi.wikipedia.Mô đun:Centralizer-w-vi in Vietnamise
    --	MediaWiki:Centralizer/Tests				-- w.vi.wikipedia.Mô đun:Centralizer/Tests in Vietnamise
    --	Módulo:Centralizer-w-es					-- s.es.wikipedia.Módulo:Central-w-es in Spanish
    --	Plantilla:Centralizer/Tests				-- s.es.wikipedia.Módulo:Centralizer/Tests in Spanish
    --	Modulenn:Centralizer-s-br				-- s.br.wikisource.Modulenn:Centralizer-s-br in Breton
    --	Patrom:TestsCentralizer					-- s.br.wikisource.Patrom:CentralizerTests in Breton
    --
    --	Tests pages on 2018-08-06 :
    --	Module:Auteur2Tpt						-- s.fr.wikisource.Module:Auteur2Tpt in French
    --	Module:Auteur2Tpt/Documentation			-- s.fr.wikisource.Module:Auteur2Tpt/Documentation in French
    --	Module:Centralizer						-- s.fr.wikisource.Module:Centralizer-s-fr in French
    --	Module:Centralizer/Documentation		-- s.fr.wikisource.Module:Centralizer/Tests in French
    --