end
if (year > 70) or --add support for AD/BC (<= AD 10) if/when needed
(minyear >= 0 and --must be a non-year series like "AC with 0 elements"
not parentAD and not parentBC)
then
local yskipped = {} --track skipped y's to avoid double-checking
local cat, found, Yeary  
--populate nav element queue outwards positively from the parent
local Year = year --to save/ratchet progression
local i = 1
while i <= 5 do
local y = 1
while y <= skipgaps_limit do
found = false
Yeary = Year + y
if yskipped[Yeary] == nil then
yskipped[Yeary] = Yeary
cat = firstpart..lspace..Yeary..tspace..lastpart
found = catexists(cat)
if found then break end
end
y = y + 1
end
if found then Year = Yeary
else Year = Year + 1 end
ynogaps[i] = Year
i = i + 1
end  
ynogaps[0] = year --the parent  
--populate nav element queue outwards negatively from the parent
Year = year --reset ratchet
i = -1
while i >= -5 do
local y = -1
while y >= -skipgaps_limit do
found = false
Yeary = Year + y
if yskipped[Yeary] == nil then
yskipped[Yeary] = Yeary
cat = firstpart..lspace..Yeary..tspace..lastpart
found = catexists(cat)
if found then break end
end
y = y - 1
end
if found then Year = Yeary
else Year = Year - 1 end
ynogaps[i] = Year
i = i - 1
end
else
skipgaps = false --AD/BC not supported
end
end  
--begin navyears
local navy = '{|\n'..'|\n'  
local y
local i = -5 --nav position
while i <= 5 do
if skipgaps then
y = ynogaps[i]
else
y = year + i*ygap*switchADBC
end
local BCdisp = ''
if i ~= 0 then --/ navy  
local AD = ''
local BC = ''
if year1to15AD and not
(year1to10 and not year1to10ADBC) --don't AD/BC 1-10's if parents don't contain AD/BC
then
if year >= 11 then --parent = AD 11-15
if y <= 10 then --prepend AD on y = 1-10 cats only, per existing cats
AD = 'AD '
end  
elseif year >= 1 then --parent = AD 1-10
if y <= 0 then
BC = BCe..' '
y = math.abs(y - 1) --skip y = 0 (DNE)
elseif y >= 1 and y <= 10 then --prepend AD on y = 1-10 cats only, per existing cats
AD = 'AD '
end
end  
elseif parentBC then
if switchADBC == -1 then --displayed y is in the BC regime
if y >= 1 then --the common case
BC = BCe..' '
elseif y == 0 then --switch from BC to AD regime
switchADBC = 1
end
end
if switchADBC == 1 then --displayed y is now in the AD regime
Y = Y + 1 --skip y = 0 (DNE)
y = Y --easiest solution: start another iterator for these AD y's displayed on a BC year parent
AD = 'AD '
end
end
if BC ~= '' and year <= 5 then --only show 'BC' for parent years <= 5: saves room, easier to read,
BCdisp = ' '..BCe --and 6 is the first/last nav year that doesn't need a disambiguator;
end --the /parent year will always show BC, so no need to show it another 10x  
--populate / navy
local ysign = y --use y for display & ysign for logic
local disp = y..BCdisp
if BC ~= '' then ysign = -ysign end
local firsttry = firstpart..lspace..AD..y..tspace..BC..lastpart
if (minyear <= ysign) and (ysign <= maxyear) then
local catlinkAD = catlinkfollowr( , firsttry, disp ) --try AD
local catlink = catlinkAD --tentative winner
if AD ~= '' then --for "ACArt with 5 suppressed elements"-type cats
local catlinkNoAD = catlinkfollowr( , firstpart..lspace..y..tspace..BC..lastpart, disp ) --try !AD
if catlinkNoAD.catexists == true then
catlink = catlinkNoAD --usurp
elseif listall then
tlistall[#tlistall] = tlistall[#tlistall]..' (tried; not displayed)'
end
end
if (AD..BC == '') and (catlink.catexists == false) and (y >= 1000) then --!ADBC & DNE; 4-digit only, to be frugal
--try basic hyphenated cats: 1-year, endash, MOS-correct only, no #Rs
local yHyph_4 = y..'–'..(y+1) --try 2010–2011 type cats
local catlinkHyph_4 = catlinkfollowr( , firstpart..lspace..yHyph_4..tspace..BC..lastpart, yHyph_4 )
if catlinkHyph_4.catexists and catlinkHyph_4.rtarget == nil then --exists & no #Rs
catlink = catlinkHyph_4 --usurp
trackcat(27, 'Navseasoncats year and range')
else
if listall then
tlistall[#tlistall] = tlistall[#tlistall]..' (tried; not displayed)'
end
local yHyph_2 = y..'–'..string.match(y+1, '%d%d$') --try 2010–11 type cats
local catlinkHyph_2 = catlinkfollowr( , firstpart..lspace..yHyph_2..tspace..BC..lastpart, yHyph_2 )
if catlinkHyph_2.catexists and catlinkHyph_2.rtarget == nil then --exists & no #Rs
catlink = catlinkHyph_2 --usurp
trackcat(27, 'Navseasoncats year and range')
elseif listall then
tlistall[#tlistall] = tlistall[#tlistall]..' (tried; not displayed)'
end
end
end
if catlink.rtarget then --#R followed; determine why
local r = catlink.rtarget
local c = catlink.cat
local regex_year = '%d%d%d%d[–-]?%d?%d?%d?%d?' --prioritize year/range stripping, e.g. for "2006 Super 14 season"
local regex_hyph = '%d%d%d%d[–-]%d+'
local regex_num = '%d+' --strip any number otherwise
local regex_final = nil --best choice goes here
if mw.ustring.match(r, regex_year) and mw.ustring.match(c, regex_year) then
regex_final = regex_year
elseif mw.ustring.match(r, regex_num) and mw.ustring.match(c, regex_num) then
regex_final = regex_num
end
if regex_final then
local r_base = mw.ustring.gsub(r, regex_final, '')
local c_base = mw.ustring.gsub(c, regex_final, '')
if r_base ~= c_base then
trackcat(19, 'Navseasoncats year redirected (base change)') --acceptable #R target
elseif mw.ustring.match(r, regex_hyph) then
trackcat(20, 'Navseasoncats year redirected (var change)') --e.g. "2008 in Scottish women's football" to "2008–09"
else
trackcat(21, 'Navseasoncats year redirected (other)') --exceptions go here
end
else
trackcat(20, 'Navseasoncats year redirected (var change)') --e.g. "V2 engines" to "V-twin engines"
end
end
navy = navy..'*'..catlink.navelement..'\n'
else --OOB vs min/max
local hidden = '<span>'..disp..'</span>'
navy = navy..'*'..hidden..'\n'
if listall then
local dummy = catlinkfollowr( , firsttry, disp )
tlistall[#tlistall] = tlistall[#tlistall]..' ('..hidden..')'
end
end
else -- navy
if parentBC then BCdisp = ' '..BCe end
navy = navy..'*<b>'..year..BCdisp..'</b>\n'
end  
i = i + 1
end  
isolatedcat
if listall then
return listalllinks
else
return navy..'|}'
end
end  
--=========================================================  
local function nav_roman( , firstpart, roman, lastpart, minimumrom, maximumrom )
local toarabic = require('Module:ConvertNumeric').roman_to_numeral
local toroman = require('Module:Roman').main  
--sterilize/convert rom/num
local num = tonumber(toarabic(roman))
local rom = toroman({ [1] = num })
if num == nil or rom == nil then --out of range or some other error
errors = p.errorclass('Function nav_roman can\'t recognize one or more of "'..(num or 'nil')..'" & "'..
(rom or 'nil')..'" in category "'..firstpart..' '..roman..' '..lastpart..'".')
return p.failedcat(errors, 'R')
end  
--sterilize min/max
local minrom = tonumber(minimumrom or *) or tonumber(toarabic(minimumrom or *))
local maxrom = tonumber(maximumrom or *) or tonumber(toarabic(maximumrom or *))
if minrom < 1 then minrom = 1 end --toarabic returns -1 on error
if maxrom < 1 then maxrom = 9999 end --toarabic returns -1 on error
if minrom > num then minrom = num end
if maxrom < num then maxrom = num end  
--begin navroman
local navr = '{|\n'..'|\n'  
local i = -5 --nav position
while i <= 5 do
local n = num + i  
if n >= 1 then
local r = toroman({ [1] = n })
if i ~= 0 then --/ navr
local catlink = catlinkfollowr( , firstpart..' '..r..' '..lastpart, r )
if minrom <= n and n <= maxrom then
if catlink.rtarget then --a was followed
trackcat(22, 'Navseasoncats roman numeral redirected')
end
navr = navr..'*'..catlink.navelement..'\n'
else
local hidden = '<span>'..r..'</span>'
navr = navr..'*'..hidden..'\n'
if listall then
tlistall[#tlistall] = tlistall[#tlistall]..' ('..hidden..')'
end
end
else -- navr
navr = navr..'*<b>'..r..'</b>\n'
end
else
navr = navr..'*<span>'..'I'..'</span>\n'
end  
i = i + 1
end  
isolatedcat
if listall then
return listalllinks
else
return navr..'|}'
end
end  
--======================================================  
local function nav_nordinal( , firstpart, ord, lastpart, minimumord, maximumord )
local nord = tonumber(ord)