Editing Module:Navbox

Jump to navigation Jump to search
Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-- <nowiki>
--
--
-- This module implements {{Navbox}}
-- Implements {{Navbox}}
--
--


local p = {}
local p = {}
local tnavbar = require( 'Module:Tnavbar' )
local yesno = require( 'Module:Yesno' )
local onmain = require('Module:Mainonly').on_main()
local page_title = mw.title.getCurrentTitle().fullText
--
-- Helper for inserting a new row into the navbox
--
-- @param tbl {mw.html table}
-- @return tbl {mw.html table}
--
local function insertRow( tbl )
return tbl:tag( 'tr' )
end


local navbar = require('Module:Navbar')._navbar
--
local getArgs -- lazily initialized
-- Creates the navbox table
--
-- @param args {table}
-- @return tbl {mw.html table}
--
local function createTbl( args )


local args
local tbl = mw.html.create( 'table' )
local border
local listnums
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'


local function striped(wikitext)
tbl
-- Return wikitext with markers replaced for odd/even striping.
:addClass( yesno( args.subgroup ) and 'navbox-subgroup' or 'navbox' )
-- Child (subgroup) navboxes are flagged with a category that is removed
:addClass( 'nowraplinks' )
-- by parent navboxes. The result is that the category shows all pages
 
-- where a child navbox is not contained in a parent navbox.
if not yesno( args.subgroup ) and
local orphanCat = '[[Category:Navbox orphans]]'
( args.state == 'collapsed' or
if border == 'subgroup' and args.orphan ~= 'yes' then
  args.state == 'uncollapsed' or
-- No change; striping occurs in outermost navbox.
  args.state == 'autocollapse' or
return wikitext .. orphanCat
  -- defaults to autocollapse
end
  args.state == nil )
local first, second = 'odd', 'even'
then
if args.evenodd then
tbl:addClass( 'mw-collapsible' )
if args.evenodd == 'swap' then
 
first, second = second, first
if args.state == 'collapsed' then
tbl:addClass( 'mw-collapsed' )
elseif args.state == 'uncollapsed' then
tbl:addClass('navbox-uncollapsed')
else
else
first = args.evenodd
tbl:addClass( 'mw-collapsed' )
second = first
tbl:addClass( 'navbox-autocollapse' )
end
end
end
end
local changer
 
if first == second then
if yesno( args.collapsible ) then
changer = first
tbl:addClass( 'navbox-collapsible' )
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer))  -- () omits gsub count
end


local function processItem(item, nowrapitems)
if args.style then
if item:sub(1, 2) == '{|' then
tbl:cssText( args.style )
-- Applying nowrap to lines in a table does not make sense.
-- Add newlines to compensate for trim of x in |parm=x in a template.
return '\n' .. item ..'\n'
end
end
if nowrapitems == 'yes' then
local lines = {}
for line in (item .. '\n'):gmatch('([^\n]*)\n') do
local prefix, content = line:match('^([*:;#]+)%s*(.*)')
if prefix and not content:match('^<span class="nowrap">') then
line = prefix .. '<span class="nowrap">' .. content .. '</span>'
end
table.insert(lines, line)
end
item = table.concat(lines, '\n')
end
if item:match('^[*:;#]') then
return '\n' .. item ..'\n'
end
return item
end


local function renderNavBar(titleCell)
-- manually set collapse/expand messages
-- bug causing the default database messages to be used
tbl
:attr( {
['cellspacing'] = '0',
['data-expandtext'] = 'show',
['data-collapsetext'] = 'hide',
['data-navbox-name'] = args.name
} )


if args.navbar ~= 'off' and args.navbar ~= 'plain' and not (not args.name and mw.getCurrentFrame():getParent():getTitle():gsub('/sandbox$', '') == 'Template:Navbox') then
return tbl
titleCell:wikitext(navbar{
end
args.name,
mini = 1,
fontstyle = (args.basestyle or '') .. ';' .. (args.titlestyle or '') .. ';background:none transparent;border:none;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none; padding:0;'
})
end


--
-- Wrapper for [[Module:Tnavbar]]
--
-- @param args {table}
-- @return {string}
--
local function navbar( args )
return tnavbar._collapsible( { [1] = '<span style="display:none;">RS3 </span>'..args.title, [2] = args.name } )
end
end


--
--
--   Title row
-- Creates the header (what you see when the navbox is collapsed)
--
--
local function renderTitleRow(tbl)
-- @param tbl {mw.html table}
if not args.title then return end
-- @param args {table}
-- @return {mw.html table}
--
local function header( tbl, args )
local div = insertRow( tbl )
:tag( 'th' )
:attr( 'colspan', '2' )
:addClass( 'navbox-title' )
:attr( 'id' , 'navbox-title' )
:tag( 'div' )


local titleRow = tbl:tag('tr')
-- @todo move this to site css so we can simplify this (hook off a class)
 
-- to something like div:wikitext( args.name and navbar( args ) or args.title )
if args.titlegroup then
-- which can be appended to the above and returned straight away
titleRow
if args.name then
:tag('th')
div
:attr('scope', 'row')
:css( 'padding-right', args.state == 'plain' and '6em' or '0' )
:addClass('navbox-group')
:wikitext( navbar( args ) )
:addClass(args.titlegroupclass)
else
:cssText(args.basestyle)
div
:cssText(args.groupstyle)
:css( 'padding-left', args.state == 'plain' and '0' or '6em' )
:cssText(args.titlegroupstyle)
:wikitext( '<span style="display:none;">RS3 </span>'..args.title )
:wikitext(args.titlegroup)
end
end


local titleCell = titleRow:tag('th'):attr('scope', 'col')
return div:allDone()
 
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
 
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
 
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
 
renderNavBar(titleCell)
 
titleCell
:tag('div')
-- id for aria-labelledby attribute
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 4em')
:wikitext(processItem(args.title))
end
end


--
--
--   Above/Below rows
-- Inserts a row into the navbox
--
-- @param tbl {mw.html table}
-- @param gtitle {string}
-- @param group {string}
-- @param gtype {string}
-- @param gcats {table}
-- @param style {string}
-- @return {mw.html table}
--
--
local function row( tbl, gtitle, group, gtype, gcats, style, _name, subgroup )
local tr = insertRow( tbl )
local td
if gtitle then
td = tr
:addClass( 'navbox-group' )
:tag( 'th' )
:addClass( 'navbox-group-title' )
:wikitext( gtitle )
:done()
:tag( 'td' )
else
td = tr
:addClass( 'navbox-group' )
:addClass( 'navbox-group-split' )
:tag( 'td' )
:addClass( 'navbox-group-title-hidden' )
:attr( 'colspan', '0' )
:css( 'display', 'none' )
:done()
:tag( 'td' )
:attr( 'colspan', '2' )
end


local function getAboveBelowColspan()
--[[
local ret = 2
  List styling
if args.imageleft then ret = ret + 1 end
  This is unlikely to be implemented in the near future due to it requiring extra css to work
if args.image then ret = ret + 1 end
  and mobile currently not supporting that css.
return ret
  As an example, it lets you do the following instead if using {{*}} all the time
end
  | group3 =
  * {{plink|foo}}
  * {{plink|bar}}
  * {{plink|baz}}
]]
if mw.ustring.match( group, '^%s*%*' ) then
td:newline()


local function renderAboveRow(tbl)
-- trim whitespace on bullets
if not args.above then return end
local spl = mw.text.split( group, '\n' )


tbl:tag('tr')
for i = 1, #spl do
:tag('td')
spl[i] = mw.text.trim( spl[i] )
:addClass('navbox-abovebelow')
end
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan())
:tag('div')
-- id for aria-labelledby attribute, if no title
:attr('id', args.title and nil or mw.uri.anchorEncode(args.above))
:wikitext(processItem(args.above, args.nowrapitems))
end


local function renderBelowRow(tbl)
group = '\n' .. table.concat( spl, '\n' )
if not args.below then return end
end


tbl:tag('tr')
--local group2 = group
:tag('td')
--local group3 = group2
:addClass('navbox-abovebelow')
-- analytics
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan())
:tag('div')
:wikitext(processItem(args.below, args.nowrapitems))
end


--
--if _name then
--   List rows
-- local name = mw.ustring.gsub(_name,' ','_')
--
-- for v in mw.ustring.gmatch(group,'%[%[[^%]]+%]%]') do
local function renderListRow(tbl, index, listnum)
-- if mw.ustring.match(v,'%[%[File:.+|link=') then
local row = tbl:tag('tr')
-- local link = mw.ustring.match(v,'|link=([^%]|]+)')
-- if link then
-- local linkrep = mw.ustring.gsub(link,'([%%%]%[%-^$*()+?])','%%%1')
-- local _link = mw.ustring.gsub(link,' ','_')
-- local newfile = mw.ustring.gsub(v,'|link='..linkrep,string.format('|link=https://runescape.wiki/w/%s?f=%s',_link,name))
-- local w = mw.ustring.gsub(v,'([%%%]%[%-^$*()+?])','%%%1')
-- group2 = mw.ustring.gsub(group2,w,newfile)
-- end
-- elseif mw.ustring.match(v,'%[%[Category:') then
-- nothing
-- else
-- local link = mw.ustring.match(v,'%[%[([^%]|]+)')
-- local txt = mw.ustring.match(v,'%|([^%]|]+)') or link


if index == 1 and args.imageleft then
-- local newlink = ''
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')              -- Minimize width
:css('padding', '0px 2px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', #listnums)
:tag('div')
:wikitext(processItem(args.imageleft))
end


if args['group' .. listnum] then
-- black links if current page
local groupCell = row:tag('th')
-- if link == page_title then
-- newlink = string.format('<b>%s</b>',txt)
-- else
-- local _link = mw.ustring.gsub(link or '',' ','_')
-- newlink = string.format('[https://runescape.wiki.com/w/%s?n=%s %s]',_link,name,txt)
-- end
-- local w = mw.ustring.gsub(v,'([%%%]%[%-^$*()+?])','%%%1')
-- group2 = mw.ustring.gsub(group2,w,newlink)
-- end
-- end


-- id for aria-labelledby attribute, if lone group with no title or above
--[==[
if listnum == 1 and not (args.title or args.above or args.group2) then
fix [[these kind]]s of [[link]]s post analytics parse
groupCell
]==]
:attr('id', mw.uri.anchorEncode(args.group1))
-- group3 = group2
end


groupCell
-- for v in mw.ustring.gmatch(group2,'%[https://runescape.wiki.com/w[^%]]-%]%a') do
:attr('scope', 'row')
-- local rep = mw.ustring.gsub(v,'%]','')
:addClass('navbox-group')
-- rep = rep..']'
:addClass(args.groupclass)
-- local w = mw.ustring.gsub(v,'([%%%]%[%-^$*()+?])','%%%1')
:cssText(args.basestyle)
:css('width', args.groupwidth or '1%') -- If groupwidth not specified, minimize width


groupCell
-- group3 = mw.ustring.gsub(group2,w,rep)
:cssText(args.groupstyle)
-- end
:cssText(args['group' .. listnum .. 'style'])
--end
:wikitext(args['group' .. listnum])
end


local listCell = row:tag('td')
td
:addClass( 'navbox-list' )
:wikitext( group ) --group3


if args['group' .. listnum] then
if gtype and mw.ustring.lower( gtype ) == 'subgroup' then
listCell
td
:css('text-align', 'left')
:addClass( 'navbox-parent' )
:css('border-left-width', '2px')
:css( {
:css('border-left-style', 'solid')
padding = '0',
else
['border-bottom'] = '0'
listCell:attr('colspan', 2)
} )
end
end


if not args.groupwidth then
if style then
listCell:css('width', '100%')
td:cssText( style )
end
end
 
local rowstyle  -- usually nil so cssText(rowstyle) usually adds nothing
-- add subgroup categories
if index % 2 == 1 then
if next(gcats) and onmain then
rowstyle = args.oddstyle
first_char = page_title:sub(1,1)
else
title_pattern = "[" .. first_char:upper() .. first_char:lower() .. "]" .. page_title:sub(2)
rowstyle = args.evenstyle
title_pattern = title_pattern :gsub("%(","%%(")
end
:gsub("%)","%%)")
 
:gsub("_"," ")
local listText = args['list' .. listnum]
:gsub(" ","[_ ]")
local oddEven = ODD_EVEN_MARKER
:gsub("%-","%%-")
if listText:sub(1, 12) == '</div><table' then
local link_patterns = {
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
"%[%["..title_pattern.."%]%]", "%[%["..title_pattern.."%|", "{{[Pp]link%|"..title_pattern.."}}",
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
"{{[Pp]link%|"..title_pattern.."%|", "{{[Pp]linkp%|"..title_pattern.."}}",
end
"{{[Pp]linkp%|"..title_pattern.."%|", "{{[Ii]linkp%|"..title_pattern.."}}",
listCell
"{{[Ii]linkp%|"..title_pattern.."%|", "{{[Cc]hatl%|"..title_pattern.."}}",
:css('padding', '0px')
"{{[Cc]hatl%|"..title_pattern.."%|"
:cssText(args.liststyle)
}
:cssText(rowstyle)
for _,v in ipairs(link_patterns) do
:cssText(args['list' .. listnum .. 'style'])
if group:match(v) then
:addClass('navbox-list')
for _,cat in ipairs(gcats) do
:addClass('navbox-' .. oddEven)
td:wikitext('[[Category:'..cat..']]')
:addClass(args.listclass)
end
:addClass(args['list' .. listnum .. 'class'])
break
:tag('div')
end
:css('padding', (index == 1 and args.list1padding) or args.listpadding or '0em 0.25em')
end
:wikitext(processItem(listText, args.nowrapitems))
 
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')              -- Minimize width
:css('padding', '0px 0px 0px 2px')
:cssText(args.imagestyle)
:attr('rowspan', #listnums)
:tag('div')
:wikitext(processItem(args.image))
end
end
return td:allDone()
end
end


--
--
--   Tracking categories
-- Inserts a footer into the navbox
--
-- @param tbl {mw.html table}
-- @param args {table}
-- @return {mw.html table}
--
--
local function footer( tbl, args )
local th = insertRow( tbl )
:tag( 'th' )
:attr( 'colspan', '2' )
:addClass( 'navbox-footer' )


local function needsHorizontalLists()
if args.fstyle then
if border == 'subgroup' or args.tracking == 'no' then
th:cssText( args.fstyle )
return false
end
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end


local function hasBackgroundColors()
if mw.ustring.match( args.footer, '^%s*%*' ) then
for _, key in ipairs({'titlestyle', 'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
th:newline()
if tostring(args[key]):find('background', 1, true) then
 
return true
-- trim whitespace on bullets
end
local spl = mw.text.split( args.footer, '\n' )
end
end


local function hasBorders()
for i = 1, #spl do
for _, key in ipairs({'groupstyle', 'basestyle', 'abovestyle', 'belowstyle'}) do
spl[i] = mw.text.trim( spl[i] )
if tostring(args[key]):find('border', 1, true) then
return true
end
end
end
end


local function isIllegible()
args.footer = table.concat( spl, '\n' )
local styleratio = require('Module:Color contrast')._styleratio


for key, style in pairs(args) do
th:addClass( 'navbox-list' )
if tostring(key):match("style$") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
end
return false
end


local function getTrackingCategories()
th:wikitext( args.footer )
local cats = {}
 
if needsHorizontalLists() then table.insert(cats, 'Navigational boxes without horizontal lists') end
return th:allDone()
if hasBackgroundColors() then table.insert(cats, 'Navboxes using background colours') end
if isIllegible() then table.insert(cats, 'Potentially illegible navboxes') end
if hasBorders() then table.insert(cats, 'Navboxes using borders') end
return cats
end
end


local function renderTrackingCategories(builder)
--
-- Adds [[Category:Navigational templates]] to navbox template pages
--
-- @return {string}
--
local function categories()
local title = mw.title.getCurrentTitle()
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local page = title.text
local subpage = title.subpageText
local ns = title.nsText
if subpage == 'doc' or subpage == 'sandbox' or subpage == 'testcases' then return end


for _, cat in ipairs(getTrackingCategories()) do
if ns == 'Template' then
builder:wikitext('[[Category:' .. cat .. ']]')
-- sort in category by pagename
return '[[Category:Navigational templates|' .. page .. ']]'
else
return ''
end
end
end
end


--
--
--   Main navbox tables
-- Adds [[Template:Navbox/doc]] to navbox template pages
--
--
local function renderMainTable()
-- @param args {table}
local tbl = mw.html.create('table')
-- @return {string}
:addClass('nowraplinks')
--
:addClass(args.bodyclass)
local function docs( args )
local frame = mw.getCurrentFrame()
local title = mw.title.getCurrentTitle()
local base = title.baseText
local ns = title.nsText


if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
-- not if a subpage of [[Template:Navbox]]
if args.state == 'collapsed' then args.state = 'mw-collapsed' end
if base ~= 'Navbox' and
tbl
-- in template ns
:addClass('mw-collapsible')
ns == 'Template' and
:addClass(args.state or 'autocollapse')
-- not a navbox group within a navbox
end
not yesno( args.subgroup ) and
 
-- not a collapsible navbox within a navbox
tbl:css('border-spacing', 0)
not yesno( args.collapsible ) and
if border == 'subgroup' or border == 'none' then
-- not if the doc argument is not set to "yes"
tbl
yesno( args.doc, false )
:addClass('navbox-subgroup')
then
:cssText(args.bodystyle)
return frame:expandTemplate{ title = 'Navbox/doc' }
:cssText(args.style)
else
else  -- regular navbox - bodystyle and style will be applied to the wrapper table
return ''
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
end
tbl:cssText(args.innerstyle)


renderTitleRow(tbl)
renderAboveRow(tbl)
for i, listnum in ipairs(listnums) do
renderListRow(tbl, i, listnum)
end
renderBelowRow(tbl)
return tbl
end
end


function p._navbox(navboxArgs)
--
args = navboxArgs
-- Navbox method to allow it to be called by other modules
listnums = {}
--
 
-- @param _args {table}
for k, _ in pairs(args) do
-- @return {string}
if type(k) == 'string' then
--
local listnum = k:match('^list(%d+)$')
function p._navbox( _args )
if listnum then table.insert(listnums, tonumber(listnum)) end
local args = {}
local wkCss = ''
local wkDiv = ''
local j
-- preserves parser function behaviour where an empty string is considered undefined
-- or nil in lua's case
for k, v in pairs( _args ) do
if v ~= '' then
args[k] = v
end
end
end
end
table.sort(listnums)


border = mw.text.trim(args.border or args[1] or '')
local tbl = createTbl( args )
if border == 'child' then
 
border = 'subgroup'
if not yesno( args.subgroup ) then
tbl = header( tbl, args )
end
end


-- render the main body of the navbox
-- insert up to 20 rows
local tbl = renderMainTable()
--
-- 20 is a limit inherited from wikipedia when we copied this over
-- and we've never had a reason to extend it
for i = 1, 20 do
j = tostring( i )


-- render the appropriate wrapper around the navbox, depending on the border param
if args['group' .. j] then
local res = mw.html.create()
local gcats = {}
if border == 'none' then
for p = 1, 20 do
local nav = res:tag('div')
local q = tostring ( p )
:attr('role', 'navigation')
:node(tbl)
if args['g' .. j .. 'cat' .. q] then
-- aria-labelledby title, otherwise above, otherwise lone group
table.insert(gcats, args['g' .. j .. 'cat' .. q])
if args.title or args.above or (args.group1 and not args.group2) then
else
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
break
end
end
tbl = row( tbl, args['gtitle' .. j], args['group' .. j], args['gtype' .. j], gcats, args['style' .. j], args.name, args.subgroup )
else
else
nav:attr('aria-label', 'Navbox')
break
end
elseif border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>')
:node(tbl)
:wikitext('<div>')
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:addClass(args.navboxclass)
:cssText(args.bodystyle)
:cssText(args.style)
:css('padding', '3px')
:node(tbl)
-- aria-labelledby title, otherwise above, otherwise lone group
if args.title or args.above or (args.group1 and not args.group2) then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above or args.group1))
else
nav:attr('aria-label', 'Navbox')
end
end
end
end


if (args.nocat or 'false'):lower() == 'false' then
if args.footer then
renderTrackingCategories(res)
tbl = footer( tbl, args )
end
end
return striped(tostring(res))
end


function p.navbox(frame)
tbl = tostring( tbl )
if not getArgs then
 
getArgs = require('Module:Arguments').getArgs
local cats = ''
end
if not yesno(args.subgroup) and not yesno(args.hidecat) then
args = getArgs(frame, {wrappers = {'Template:Navbox', 'Template:Navbox subgroup'}})
cats = categories()
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
end
local docs = docs( args )


-- Read the arguments in the order they'll be output in, to make references number in the right order.
return tbl .. cats .. docs
local _
end
_ = args.title
_ = args.above
for i = 1, 20 do
_ = args["group" .. tostring(i)]
_ = args["list" .. tostring(i)]
end
_ = args.below


return p._navbox(args)
--
-- Main navbox method accessed through #invoke
--
-- @param frame {table}
-- @return {string}
--
function p.navbox( frame )
local args = frame:getParent().args
return p._navbox( args )
end
end


return p
return p
-- </nowiki>
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template

Page included on this page: