(Arreglos (UCP)) Etiqueta: Editor clásico |
Sin resumen de edición Etiqueta: Editor clásico |
||
Línea 580: | Línea 580: | ||
:css('padding', '0 0 5px 0') |
:css('padding', '0 0 5px 0') |
||
:css('background-color', color) |
:css('background-color', color) |
||
− | :css('line-height', '0. |
+ | :css('line-height', '0.95em') |
:css('font-size', '150%') |
:css('font-size', '150%') |
||
:css('font-weight', 'bold') |
:css('font-weight', 'bold') |
||
+ | :css('border-bottom', '3px solid #002e54') |
||
:css('width', '20px') |
:css('width', '20px') |
||
:css('vertical-align', 'top') |
:css('vertical-align', 'top') |
||
Línea 588: | Línea 589: | ||
:addClass('content-bg rtop') |
:addClass('content-bg rtop') |
||
:css('background', '#ffffff') |
:css('background', '#ffffff') |
||
− | :css('width', '170px') |
||
:tag('span') |
:tag('span') |
||
:addClass('r1') |
:addClass('r1') |
Revisión del 16:20 23 oct 2020
La documentación para este módulo puede ser creada en Módulo:Eras/doc
-- <nowiki>
-------------------------------------------------------------------------------
-- Module:Eras
-- Obtenido [[w:c:starwars:Module:Eras]] de Wookieepedia.
--
-- Este módulo muestra los iconos en la parte superior derecha de los artículos, así como
-- las pestañas del Canon y de las Leyendas para las páginas con versiones Canon/Leyendas.
-- También da formato al título de la página mediante {{DISPLAYTITLE}}.
--
-------------------------------------------------------------------------------
local DEBUG_MODE = false -- if true, errors are not caught
-------------------------------------------------------------------------------
-- Icon data
-------------------------------------------------------------------------------
--[[
-- Esta tabla almacena los datos de todos los iconos que aparecen en la parte superior derecha.
-- Puede tener los siguientes campos:
-- * image - el nombre de la imagen del icono, sin el prefijo "File:" (requerido).
-- * tooltip - el tooltip del icono (opcional).
-- * link - la página a la que se enlaza desde el icono (opcional).
-- * category - la categoría que va con el icono, sin el prefijo "Category:"
-- (opcional).
-- * protectionAction - para iconos de protección acciones como editar o renombrar (opcional)
-- * protectionLevel - para iconos de protección sobre el nivel de protección,
-- como "sysop". Si la página no tiene el nivel correcto de protección
-- la página se coloca en una categoría de seguimiento y el icono no se muestra
-- (opcional).
-- Nota: esto es solo un lugar conveniente para almacenar los datos. Las subtablas se
-- acceden desde el código manualmente, por lo que añadir nuevos subtablas no lo hará
-- de forma automática. Añadir nuevos iconos, y la eliminación de las subtablas puede romper cosas.
--]]
local iconData = {
pre = {
image = "Premium-Era-pre.png",
tooltip = "El tema de este artículo aparece antes de la era de la Pre-República.",
link = "Era Pre-República"
},
btr = {
image = "Premium-Era-pre.png",
tooltip = "El tema de este artículo aparece antes de la República.",
link = "Era Antes de la República"
},
old = {
image = "Premium-Era-old.png",
tooltip = "El tema de este artículo aparece en la era de la Antigua República.",
link = "Era de la Antigua República"
},
imp = {
image = "Premium-Era-imp.png",
tooltip = "El tema de este artículo aparece en la era del Alzamiento del Imperio.",
link = "Era del Alzamiento del Imperio"
},
reb = {
image = "Premium-Era-reb.png",
tooltip = "El tema de este artículo aparece en la era de la Rebelión.",
link = "Era de la Rebelión"
},
new = {
image = "Premium-Era-new.png",
tooltip = "El tema de este artículo aparece en la era de la Nueva República.",
link = "Era de la Nueva República"
},
njo = {
image = "Premium-Era-njo.png",
tooltip = "El tema de este artículo aparece en la era de la Nueva Orden Jedi.",
link = "Era de la Nueva Orden Jedi"
},
leg = {
image = "Premium-Era-leg.png",
tooltip = "El tema de este artículo aparece en la era del Legado.",
link = "Era del Legado de la Fuerza"
},
inf = {
image = "Premium-Era-inf.png",
tooltip = "El tema de este artículo es considerado parte de Star Wars Infinities.",
link = "Infinitos"
},
real = {
image = "Premium-Era-real.png",
tooltip = "El tema de este artículo existe o es relevante en el mundo real.",
link = "Categoría:Artículos del mundo real",
category = "Artículos del mundo real"
},
destacado = {
image = "Premium-FeaturedIcon.png",
tooltip = "Este es un artículo destacado de Star Wars Wiki en español.",
link = "Star Wars Wiki:Artículos destacados",
category = "Artículos destacados"
},
exdestacado = {
image = "Premium-DefeaturedIcon.png",
tooltip = "Este fue un artículo destacado de Star Wars Wiki en español.",
link = "Star Wars Wiki:Inquisidores#AD perdidos",
category = "Artículos que han perdido el estatus de destacado"
},
bueno = {
image = "Premium-GoodIcon.png",
tooltip = "Este es un artículo bueno de Star Wars Wiki en español.",
link = "Star Wars Wiki:Artículo bueno",
category = "Artículos buenos"
},
exbueno = {
image = "Premium-FormerGAicon.png",
tooltip = "Este fue un artículo bueno de Star Wars Wiki en español.",
link = "Star Wars Wiki:Inquisidores#AB perdidos",
category = "Artículos que han perdido el estatus de bueno"
},
comp = {
image = "Premium-ComprehensiveArticle.png",
tooltip = "Este es un artículo completo de Star Wars Wiki en español.",
link = "Star Wars Wiki:Artículo completo",
category = "Artículos completos"
},
excomp = {
image = "Premium-FormerCAIcon.png",
tooltip = "Este fue un artículo completo de Star Wars Wiki en español.",
link = "Star Wars Wiki:Artículo completo",
category = "Artículos que han perdido el estatus de completo"
},
prot = {
protectionAction = "edit",
protectionLevel = "sysop",
image = "Premium-Era-Fprotect.png",
tooltip = "Este artículo está protegido.",
link = "Star Wars Wiki:Políticas de protección#Artículos protegidos",
category = "Artículos protegidos"
},
sprot = {
protectionAction = "edit",
protectionLevel = "autoconfirmed",
image = "Premium-Era-Sprotect.png",
tooltip = "Este artículo está semiprotegido.",
link = "Star Wars Wiki:Políticas de protección#Artículos semiprotegidos",
category = "Artículos semiprotegidos"
},
ssprot = {
image = "Premium-Era-Ssprotect.png",
tooltip = "Este artículo está supersemiprotegido.",
link = "Star Wars Wiki:Políticas de protección#Artículos supersemiprotegidos",
category = "Artículos supersemiprotegidos"
},
mprot = {
protectionAction = "move",
protectionLevel = "sysop",
image = "Premium-Era-Mprotect.png",
tooltip = "La opción de renombrar este artículo está protegida.",
link = "Star Wars Wiki:Políticas de protección#Artículos protegidos",
category = "Artículos con protección de renombramiento"
},
uprot = {
protectionAction = "upload",
protectionLevel = "sysop",
image = "Premium-Era-Uprotect.png",
tooltip = "La subida de este archivo está protegida.",
link = "Star Wars Wiki:Políticas de protección#Artículos protegidos",
category = "Archivos que tienen protegida la subida"
},
noncanon = {
image = "Premium-Era-inf.png",
tooltip = "El tema de este artículo se considera no-canon."
}
}
-------------------------------------------------------------------------------
-- Funciones de ayuda
-------------------------------------------------------------------------------
-- Comprueba si existe la página especificada. Utilizamos pcall para detectar errores
-- si estamos por encima del límite del recuento de funciones parser u otros errores.
-- Esta función aumenta el recuento de funciones parser para cada nueva página llamada.
local function exists(page)
local success, title = pcall(mw.title.new, page)
return success and title and title.exists or false
end
-------------------------------------------------------------------------------
-- Clase Eras
-------------------------------------------------------------------------------
-- La clase eras hace todo el trabajo pesado en el módulo. Utilizamos una clase.
-- en vez de funciones normales para poder evitar pasar muchos valores diferentes
-- alrededor de cada función diferente.
local Eras = {}
Eras.__index = Eras -- Configurar la herencia para las tablas que utilizan Eras como metatabla.
-- Esta función hace un nuevo objeto de eras. Aquí establecemos todos los valores de
-- los argumentos y hacemos cualquier preprocesamiento requerido.
function Eras.new(args, title)
local obj = setmetatable({}, Eras) -- Make our object inherit from Eras.
obj.title = title or mw.title.getCurrentTitle()
-- Establece estructura de objeto
obj.categories = {}
-- Establece parámetros para mostrar el título
obj.noDisplayTitle = args.notitle
obj.displayTitleBase = args.title
obj.displayTitleParen = args.title2
-- Establece estatus oculto
obj.isHidden = args.hide
-- Establece la anulación de la continuidad (el parámetro "tipo")
if args.type then
local override = args.type:lower()
if override ~= 'canon' and override ~= 'leyendas' then
obj:raiseError("si el parámetro 'type' está especificado, debe " ..
"tener el valor de 'canon' o 'leyendas'")
end
obj.continuityOverride = override
end
-- Establece los nombres de artículos canon y leyendas para el tema
obj.legendsArticle = args.legends
obj.canonArticle = args.canon
-- Obtiene los datos de icono.
do
local icons = {}
for _, v in ipairs(args) do
local t = iconData[string.lower(v)]
if t then
icons[string.lower(v)] = t
else
-- El icono especificado no se encuentro en los datos de icono, por lo que
-- se establece una categoría de seguimiento.
obj.hasBadParameter = true
end
end
obj.icons = icons
end
return obj
end
-- Generará un error. Si el modo de depuración se establece en falso, entonces los errores generados aquí
-- son cogidos por la función de exportación p._main.
function Eras:raiseError(msg)
local level
if DEBUG_MODE then
level = nil
else
level = 0 -- Sumprimer el nombre del módulo y el número de línea en el mensaje de error.
end
error(msg, level)
end
-- Añade una categoría, para mostrarse al final.
function Eras:addCategory(cat, sort)
table.insert(self.categories, {category = cat, sortKey = sort})
end
-- Método de acceso directo para obtener una subtabla icono de datos.
function Eras:getIconData(code)
return self.icons[code]
end
-- Si el título actual termina con /Canon.
function Eras:hasCanonTitle()
return self.title.text:find('/Canon$')
end
-- Si el título actual termina con /Legends.
function Eras:hasLegendsTitle()
return self.title.text:find('/Leyendas$')
end
-- Devuelve un valor booleano que indica si cualquiera de los iconos fueron especificados por el
-- usuario.
function Eras:hasAnyOfIcons(...)
for i = 1, select('#', ...) do
if self:getIconData(select(i, ...)) then
return true
end
end
return false
end
-- Analiza el nombre de la página y establece {{DISPLAYTITLE}}.
function Eras:renderDisplayTitle()
local pagename = self.title.text
-- Salir si se ha dicho que no se establece un título o si el título comienza con
-- apertura de paréntesis.
if self.noDisplayTitle or pagename:find('^%(') then
return nil
end
-- Encuentra la base de la visualización y los paréntesis.
local dBase = self.displayTitleBase
local dParen = self.displayTitleParen
if not dBase or not dParen then
-- Analizar el nombre de página para encontrar parte de la base y el fin del paréntesis.
-- /Canon se elimina, y el paréntesis solo se reconoce si están
-- al final del nombre de la página.
local trimmedPagename = pagename:gsub('/Canon$', '')
trimmedPagename = pagename:gsub('/Leyendas$', '')
local base, paren = trimmedPagename:match('^(.*)%s*%((.-)%)$')
if not base then
base = trimmedPagename
end
-- Utiliza los valores que encontramos, pero sólo si un valor no ha sido ya
-- especificado.
dBase = dBase or base
dParen = dParen or paren
end
-- Construye la cadena de visualización
local display
if dParen then
display = string.format('%s <small>(%s)</small>', dBase, dParen)
else
display = dBase
end
if self.title.namespace ~= 0 then
display = mw.site.namespaces[self.title.namespace].name .. ':' .. display
end
-- Devuelve la función parser DISPLAYTITLE expandida.
return mw.getCurrentFrame():preprocess(string.format(
'{{DISPLAYTITLE:%s}}',
display
))
end
-- Renders an eras icon from the given icon data. It deals with the image,
-- tooltip, link, and the category, but not the protection fields.
function Eras:renderIcon(data)
-- Render the category at the end if it exists.
if data.category then
self:addCategory(data.category)
end
-- Render the icon and return it.
local ret = {}
ret[#ret + 1] = '[[File:'
ret[#ret + 1] = data.image
if data.tooltip then
ret[#ret + 1] = '|'
ret[#ret + 1] = data.tooltip
end
if data.link then
ret[#ret + 1] = '|link='
ret[#ret + 1] = data.link
end
ret[#ret + 1] = ']]'
return table.concat(ret)
end
-- Renders a protection eras icon from the given data. If the page doesn't have
-- the specified protection level, returns nil and adds a flag to add a
-- tracking category later on in processing.
function Eras:renderProtectionIcon(data)
if not data.protectionAction then
return self:renderIcon(data)
end
local protectionLevel = self.title.protectionLevels[data.protectionAction]
protectionLevel = protectionLevel and protectionLevel[1]
if protectionLevel and protectionLevel == data.protectionLevel then
return self:renderIcon(data)
else
self.hasIncorrectProtectionIcon = true
end
end
-- Renders the first icon, either Canon or Legends, or nil if the continuity
-- couldn't be determined. This is equivalent to the previous {{Eraicon/canon}}
-- template.
function Eras:renderContinuityIcon()
-- First, find what continuity to use, if any.
local continuity, isUsingCategory
if self.continuityOverride == 'leyendas' then
continuity = 'leyendas'
if not self:hasAnyOfIcons('real') then
isUsingCategory = true
end
elseif self.title.namespace == 0 then
if self:hasLegendsTitle() then
continuity = 'leyendas'
isUsingCategory = true
elseif self:hasCanonTitle() then
continuity = 'canon'
isUsingCategory = true
elseif self.legendsArticle then
continuity = 'canon'
isUsingCategory = true
elseif self.canonArticle then
continuity = 'leyendas'
isUsingCategory = true
elseif exists(self.title.text .. '/Leyendas') then
continuity = 'canon'
isUsingCategory = true
elseif exists(self.title.text .. '/Canon') then
continuity = 'leyendas'
isUsingCategory = true
elseif self:hasAnyOfIcons('pre', 'btr', 'old', 'imp', 'reb', 'new',
'njo', 'leg')
then
continuity = 'leyendas'
if self:hasAnyOfIcons('real') then
isUsingCategory = false
else
isUsingCategory = true
end
elseif self:hasAnyOfIcons('inf', 'noncanon') then
continuity = 'leyendas'
isUsingCategory = false
elseif self:hasAnyOfIcons('real') then
if self.continuityOverride == 'canon' then
continuity = 'canon'
end
isUsingCategory = false
else
continuity = 'canon'
isUsingCategory = true
end
end
-- Generate the icon data and make the icon.
if continuity == 'canon' then
local data = {
image = 'Premium-Eras-canon.png',
tooltip = 'Este artículo trata sobre un tema considerado Canon.',
link = 'Canon'
}
if isUsingCategory then
data.category = 'Artículos Canon'
end
return self:renderIcon(data)
elseif continuity == 'leyendas' then
local data = {
image = 'Premium-Eras-legends.png',
tooltip = 'Este artículo trata sobre un tema incluido en las Leyendas.',
link = 'Star Wars Legends'
}
if isUsingCategory then
data.category = 'Artículos de las Leyendas'
end
return self:renderIcon(data)
end
end
-- Renders the icons that respond to a publishing era.
function Eras:renderPublishingIcons()
if self.continuityOverride ~= 'canon'
and not self.legendsArticle
and not self:hasCanonTitle()
then
local ret = {}
local codes = {'pre', 'btr', 'old', 'imp', 'reb', 'new', 'njo', 'leg', 'inf'}
for _, code in ipairs(codes) do
local data = self:getIconData(code)
if data then
ret[#ret + 1] = self:renderIcon(data)
end
end
return table.concat(ret)
end
end
-- Muestra otros iconos, i.e. estatus de artículos destacados y de protección.
function Eras:renderNonPublishingIcons()
local ret = {}
local codes = {'real', 'destacado', 'exdestacado', 'bueno', 'exbueno', 'comp', 'excomp'}
for _, code in ipairs(codes) do
local data = self:getIconData(code)
if data then
ret[#ret + 1] = self:renderIcon(data)
end
end
local protectionCodes = {'prot', 'sprot', 'ssprot', 'mprot', 'uprot'}
for _, code in ipairs(protectionCodes) do
local data = self:getIconData(code)
if data then
ret[#ret + 1] = self:renderProtectionIcon(data)
end
end
return table.concat(ret)
end
-- Render all the icons and eclose them in a surrounding div tag.
function Eras:renderIcons()
local icons = {}
icons[#icons + 1] = self:renderContinuityIcon()
icons[#icons + 1] = self:renderPublishingIcons()
icons[#icons + 1] = self:renderNonPublishingIcons()
icons = table.concat(icons)
local root = mw.html.create('div')
root
:attr('id', 'title-eraicons')
:css('text-align', 'right')
:css('margin-bottom', '5px')
:wikitext(icons)
return tostring(root)
end
-- Renders the Canon and Legends tabs for articles that are in both
-- continuities.
function Eras:renderCanonTab()
if self.isHidden or self.title.namespace ~= 0 then
-- Exit if we have been explicitly hidden or if we are not in the main
-- namespace.
return nil
end
-- Find the page type, canon title, and leyendas title.
local pageType, canonTitle, legendsTitle
if self.legendsArticle then
pageType = 'canon'
canonTitle = self.title.text
legendsTitle = self.legendsArticle
elseif self.canonArticle then
pageType = 'leyendas'
canonTitle = self.canonArticle
legendsTitle = self.title.text
elseif self:hasCanonTitle() then
pageType = 'canon'
canonTitle = self.title.text
legendsTitle = canonTitle:match('^(.*)/Canon$') or canonTitle
elseif self:hasLegendsTitle() then
pageType = 'leyendas'
legendsTitle = self.title.text
canonTitle = legendsTitle:match('^(.*)/Leyendas$') or legendsTitle
elseif exists(self.title.text .. '/Leyendas') then
pageType = 'canon'
legendsTitle = self.title.text .. '/Leyendas'
canonTitle = self.title.text
elseif exists(self.title.text .. '/Canon') then
pageType = 'leyendas'
canonTitle = self.title.text .. '/Canon'
legendsTitle = self.title.text
else
-- Could not determine that the article has both a Canon and a Legends
-- version, so exit.
canonTitle = ''
legendsTitle = ''
return nil
end
-- Add categories.
if pageType == 'canon' then
self:addCategory('Artículos canon con contrapartes de las leyendas')
elseif pageType == 'leyendas' then
self:addCategory('Artículos de las leyendas con contrapartes canon')
else
self:addCategory('Casos aparte')
end
-- Make the table root.
local root = mw.html.create('table')
root
:attr('id', 'canontab')
:css('text-align', 'center')
:css('padding', '0')
:css('margin', '0 0 5px 0')
:css('border-left', '0')
:css('border-right', '0')
:css('border-top', '0')
:css('border-bottom', '7px solid #002e54')
:css('border-spacing', '0')
:css('border-collapse', 'collapse')
:css('width', '100%')
:css('vertical-align', 'top')
local row = root:tag('tr')
-- This makes one Canon/Legends cell. Having this as a function rather than
-- doing it with chaining allows us to avoid putting the same code in twice.
local function makeCell(id, color, image, link, tooltip)
local cell = mw.html.create('td')
cell
:attr('id', id)
:css('padding', '0 0 5px 0')
:css('background-color', color)
:css('line-height', '0.95em')
:css('font-size', '150%')
:css('font-weight', 'bold')
:css('border-bottom', '3px solid #002e54')
:css('width', '20px')
:css('vertical-align', 'top')
:tag('span')
:addClass('content-bg rtop')
:css('background', '#ffffff')
:tag('span')
:addClass('r1')
:css('background', color)
:done()
:tag('span')
:addClass('r2')
:css('background', color)
:done()
:tag('span')
:addClass('r3')
:css('background', color)
:done()
:tag('span')
:addClass('r4')
:css('background', color)
:done()
:done()
:wikitext(string.format(
' [[File:%s|link=%s|%s]]',
image, link, tooltip
))
return cell
end
local foregroundColor = '#002e54'
local backgroundColor = '#d8e9fc'
-- Make the canon cell.
do
local link = canonTitle
local color, image, tooltip
if pageType == 'canon' then
id = 'canontab-canon_ctcw'
color = foregroundColor
image = 'Tab-canon-white.png'
tooltip = 'Este artículo cubre la versión Canon.'
else
id = 'canontab-canon_ctcb'
color = backgroundColor
image = 'Tab-canon-black.png'
tooltip = "Clic aquí para la versión Canon del artículo."
end
row:node(makeCell(id, color, image, link, tooltip))
end
-- First separator cell
row:tag('td')
:attr('id', 'canontab-separator1')
:css('width', '3px')
:wikitext(' ')
-- Make the legends cell
do
local link = legendsTitle
local color, image, tooltip
if pageType ~= 'canon' then -- is a Legends page
id = 'canontab-legends_ctlw'
color = foregroundColor
image = 'Tab-leyendas-white.png'
tooltip = 'Este artículo cubre la versión de las Leyendas.'
else -- is a Canon page
id = 'canontab-legends_ctlb'
color = backgroundColor
image = 'Tab-leyendas-black.png'
tooltip = "Clic aquí para la versión del artículo de las Leyendas."
end
row:node(makeCell(id, color, image, link, tooltip))
end
-- Second separator cell
row:tag('td')
:attr('id', 'canontab-separator2')
:css('width', '3000px')
:wikitext(' ')
return tostring(root)
end
-- Render all the categories that were specified using Eras:addCategory or with
-- category flags.
function Eras:renderCategories()
local fullPagename = self.title.prefixedText
if fullPagename == 'Template:Eras' or fullPagename == 'Template:Eraicon' then
-- Exit if we are on a blacklisted page.
return nil
end
local pagename = self.title.text
-- Renders one category.
local function renderCategory(cat, sort)
return string.format(
'[[%s:%s|%s]]', 'Category', cat, sort or pagename
)
end
local ret = {}
-- Render categories from Eras:addCategory
for i, t in ipairs(self.categories) do
ret[i] = renderCategory(t.category, t.sortKey)
end
-- Render categories from category flags.
if self.hasBadParameter then
ret[#ret + 1] = renderCategory(
'Páginas con parámetros incorrectos en la Plantilla:Eras'
)
end
if self.hasIncorrectProtectionIcon then
ret[#ret + 1] = renderCategory(
'Páginas con iconocos de protección incorrectos'
)
end
return table.concat(ret)
end
-- This method is called when the tostring function is used on the Eras object.
-- (This works in a similar fashion to Eras.__index above.) It calls all the
-- top-level render methods and returns the final output.
function Eras:__tostring()
local ret = {}
ret[#ret + 1] = self:renderDisplayTitle()
ret[#ret + 1] = self:renderIcons()
ret[#ret + 1] = self:renderCanonTab()
ret[#ret + 1] = self:renderCategories()
return table.concat(ret)
end
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
local p = {}
-- This function is the entry point from other Lua modules.
function p._main(args)
-- Define a function to call from pcall so that we can catch any errors
-- and display them to the user rather than the cryptic "Script error".
-- (It's not so cryptic if you click on it to see the error message, but
-- not so many users know to do that.)
local function getErasResult ()
local erasObj = Eras.new(args)
return tostring(erasObj)
end
-- Get the result. We only catch errors if debug mode is set to false.
local success, result
if DEBUG_MODE then
success = true
result = getErasResult()
else
success, result = pcall(getErasResult)
end
-- Return the result if there were no errors, and a formatted error message
-- if there were.
if success then
return result
else
return string.format(
'<strong class="error">[[Template:Eras]] error: %s.</strong>' ..
'[[' .. 'Categoría:Páginas con parámetros incorrectos en la Plantilla:Eras]]',
result -- this is the error message
)
end
end
-- This is the function accessed from wikitext. It must be accessed through
-- a template. The template should transclude only the text
-- "{{#invoke:Eras|main}}", and then when that template is used, any arguments
-- passed to it are magically sent through to the module.
function p.main(frame)
local args = {}
for k, v in pairs(frame:getParent().args) do
v = v:match('^%s*(.-)%s*$') -- trim whitespace
if v ~= '' then
args[k] = v
end
end
return p._main(args)
end
return p
-- </nowiki>
-- [[Categoría:Plantillas de utilidades|{{PAGENAME}}]]