Модуль:NumberOf: различия между версиями

Материал из Тептар — свободной энциклопедии
Перейти к навигации Перейти к поиску
(Новая страница: «-- Модуль для шаблонов серии NUMBEROF и страницы Тептар:Список Тептар local p = {} -- Важнейшие п...»)
 
Нет описания правки
 
Строка 15: Строка 15:
kj = true,
kj = true,
kr = true,
kr = true,
lrc = true,
mh = true,
mh = true,
mus = true,
mus = true,
Строка 40: Строка 41:
for _ in pairs(t) do count = count + 1 end
for _ in pairs(t) do count = count + 1 end
return count
return count
end
-- Вычисление вики по переданному номеру
local function calculatePosition(pos, info)
pos = tonumber(pos)
for key in pairs(info) do
if key ~= 'total' and info[key]['pos'] == pos then
return key
end
end
return ''
end
end


-- Рендеринг необходимого параметра из страницы с данными
-- Рендеринг необходимого параметра из страницы с данными
local function renderNum(f, info)
local function getParam(f, info)
-- Парсинг параметров шаблона
-- Парсинг параметров шаблона
local wiki = f.wiki
local wiki = f.wiki
Строка 54: Строка 67:
result = 0
result = 0
else
else
-- Убираем NUMBEROF из легаси-кода параметров
param = param:lower():gsub('numberof','')
if param == 'date' then
if param == 'date' then
result = formatDate(info['total']['date'])
result = formatDate(info['total']['date'])
return result
end
if param == 'pos' and tonumber(wiki) ~= nil then
--
result = calculatePosition(wiki, info)
return result
return result
end
end
Строка 71: Строка 93:
local obj = info[wiki]
local obj = info[wiki]
if obj ~= nil then
if obj ~= nil then
-- Убираем NUMBEROF из легаси-кода параметров
param = param:lower():gsub('numberof','')
if param ~= nil and info[wiki][param] ~= nil then
if param ~= nil and info[wiki][param] ~= nil then
result = info[wiki][param]
result = info[wiki][param]
Строка 101: Строка 120:
if readOnly[val] == true then
if readOnly[val] == true then
result = result .. '<span style="color:#202122; text-decoration:inherit; text-decoration-color:#202122;"><s title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s></span>'
result = result .. string.format('<s title="Данный раздел закрыт и доступен только в режиме для чтения">%s</s>', text)
else
else
result = result .. text
result = result .. text
Строка 115: Строка 134:
-- Вывод названия языка
-- Вывод названия языка
local function renderLang(val, frame)
local function renderLang(val, frame)
local text = ''
local text = langs[val] and langs[val][1] or mwlang:ucfirst(mw.language.fetchLanguageName(val))
local result = ''
local link = langs[val] and langs[val][2] or nil
local hasArticle = false
local result = text
if not isEmpty(langs[val]) then
if readOnly[val] == true then
text = langs[val][1]
result = '<s title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s> (закрыт)'
if not isEmpty(langs[val][2]) then
result = '[[' .. langs[val][2] .. '|'
hasArticle = true
else
result = frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), text }
}
end
else
text = mwlang:ucfirst(mw.language.fetchLanguageName(val))
result = frame:expandTemplate{
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), text }
}
end
end
 
if readOnly[val] == true then
if not isEmpty(link) then
result = frame:expandTemplate{
result = string.format('[[:%s|%s]]', link, result)
title = 'Цветная ссылка',
args = { '#202122', string.format('%s:', val), '<span title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s>' }
}
result = '<s>' .. result .. '</s>'
end
end


if hasArticle then
result = result .. text .. ']]'
end
if val == mwlang:getCode() then
if val == mwlang:getCode() then
result = result .. '<span class="nomobile" style="margin-left:4px;">[[File:Mw-unwatch-icon.svg|16px|text-top|alt=|link=]]</span>'
result = result .. ' [[File:Mw-unwatch-icon.svg|16px|text-top|alt=(текущий раздел)|link=]]'
end
end
Строка 157: Строка 153:


-- Функция для вывода ячейки
-- Функция для вывода ячейки
local function createCell(val, style, fmt, stats, frame)
local function renderNum(val, key, stats)
local result = '|'
local text = mwlang:formatNum(val)
if not isEmpty(fmt) then
if isEmpty(stats) or val == 0 then
result = result .. 'data-sort-value="' .. val .. '" '
return text
end
end
result = result .. 'style="border:0; ' .. (not isEmpty(style) and style or 'padding:4px 24px 4px 0;') .. '"| '
if not isEmpty(stats) then
return string.format(
result = result .. frame:expandTemplate{
'[[:%s:%s|%s]]',
title = 'Цветная ссылка',
key,
args = { '#202122', stats, (not isEmpty(fmt) and mwlang:formatNum(val) or val) }
stats,
}
text
else
)
result = result .. (not isEmpty(fmt) and mwlang:formatNum(val) or val) .. ' '
end
return result
end
end


-- Функция для вывода ряда таблицы
-- Функция для вывода ряда таблицы
local function createRow(key, val, frame)
local function createRow(key, val, frame)
local result = '|- style="'
local result = mw.html.create('tr')
local style, originalStyle = ''
:css('text-align', 'right')
if key == mwlang:getCode() then
if key == mwlang:getCode() then
result = result .. 'font-weight:bold; '
result
style = 'background:#d5fdf4; '
:css('background', '#d5fdf4')
originalStyle = style .. 'padding:4px 24px 4px 0;'
:css('font-weight', 'bold')
end
end
result = result .. 'text-align:right; vertical-align:top;"\n'
result = result .. createCell(val['pos'], style .. 'font-weight:normal; padding:4px 24px 4px 0;')
result:tag('td')
.. '|' .. createCell(renderLink(key), style .. 'font-weight:normal; padding:4px 24px 4px 0; white-space:nowrap;')
:wikitext(val['pos'])
.. '|' .. createCell(renderLang(key, frame), style .. 'padding:4px 24px 4px 0; text-align:left;')
.. '|' .. createCell(val['articles'], originalStyle, true, key .. ':' .. 'Special:Statistics', frame)
result:tag('td')
.. '|' .. createCell(val['pages'], originalStyle, true)
:wikitext(renderLink(key))
.. '|' .. createCell(val['edits'], originalStyle, true)
.. '|' .. createCell(round(val['depth']), originalStyle, true)
result:tag('td')
.. '|' .. createCell(val['users'], originalStyle, true, key .. ':' .. 'Special:ListUsers', frame)
:wikitext(renderLang(key, frame))
.. '|' .. createCell(val['activeusers'], originalStyle, true, key .. ':' .. 'Special:ActiveUsers', frame)
:css('text-align', 'left')
.. '|' .. createCell(val['admins'], originalStyle, true, key .. ':' .. 'Special:ListAdmins', frame)
.. '|' .. createCell(val['files'], originalStyle, true)
result:tag('td')
:wikitext(renderNum(val['articles'], key, 'Special:Statistics'))
result:tag('td')
:wikitext(renderNum(val['pages']))
result:tag('td')
:wikitext(renderNum(val['edits']))
result:tag('td')
:wikitext(renderNum(round(val['depth'])))
result:tag('td')
:wikitext(renderNum(val['users'], key, 'Special:ListUsers'))
return result .. '\n'
result:tag('td')
:wikitext(renderNum(val['activeusers'], key, 'Special:ActiveUsers'))
result:tag('td')
:wikitext(renderNum(val['admins'], key, 'Special:ListAdmins'))
result:tag('td')
:wikitext(renderNum(val['files'], key, 'Special:ListFiles'))
return result
end
end


-- Функция для вывода шапки таблицы
-- Функция для вывода шапки таблицы
local function createHeader()
local function createHeader()
local cell = 'background-color:transparent; padding-bottom:2px; padding-right:24px;'
local result = mw.html.create('table')
local cellLang = 'background-color:transparent; padding-bottom:2px; text-align:left; width:25%;'
:addClass('wikitable sortable')
:attr('style', 'font-feature-settings:"tnum" 1; margin:0.25em 0; width:100%;')
:css('width', '100%')
:css('margin', '0.25em 0')
result:tag('tr')
local cells = {
'№',
'Код',
'Язык',
'Статей',
'Страниц',
'Правок',
'<abbr title="Глубина">Глуб.</abbr>',
'Участников',
'<abbr title="Активных участников">(акт.)</abbr>',
'<abbr title="Администраторов">Адм.</abbr>',
'Файлов',
}
local result = '\n{| class="mw-datatable sortable" style="border:0; font-feature-settings:\'tnum\' 1; margin:4px 0 0; width:100%;"\n'
for i, val in ipairs(cells) do
.. '|- style="border-bottom:1px solid #a2a9b1; text-align:right;"\n'
result
.. '!style="border:0; ' .. cell .. '"| №'
:tag('th')
.. '|' .. createCell('Код', cell)
:attr('scope', 'col')
.. '|' .. createCell('Язык', cellLang)
:css('text-align', (val == 'Язык' and 'left' or 'right'))
.. '|' .. createCell('Статей', cell)
:css('width', (val == 'Язык' and '25%' or nil))
.. '|' .. createCell('Страниц', cell)
:wikitext(val)
.. '|' .. createCell('Правок', cell)
end
.. '|' .. createCell('<abbr title="Глубина">Глуб.</abbr>', cell)
.. '|' .. createCell('Участников', cell)
.. '|' .. createCell('(<abbr title="Активных участников">акт.</abbr>)', cell)
.. '|' .. createCell('<abbr title="Администраторов">Адм.</abbr>', cell)
.. '|' .. createCell('Файлов', cell)
return result .. '\n'
return result
end
end


Строка 228: Строка 254:
-- Параметр hide отвечает за оптическое выравнивание таблиц
-- Параметр hide отвечает за оптическое выравнивание таблиц
local val = frame['total']
local val = frame['total']
local cell = 'background:transparent; padding-right:24px; ' .. (hide and '' or 'padding-top:2px;')
local cellStyle = 'text-align:right;'
local cellHide = 'padding-right:24px;' .. (hide and '' or ' padding-top:2px;') .. ' visibility:hidden; white-space:nowrap;'
local cellStyleHide = 'color:transparent; padding:0; white-space:nowrap;'
if hide then
cellStyle = 'padding:0;' .. cellStyle
end
-- aa — закрытый раздел с самой большой глубиной
-- aa — закрытый раздел с самой большой глубиной
local num = tableLength(frame) - 1
local num = tableLength(frame) - 1
local depth = (hide and round(frame['aa']['depth']) or round(val['depth']))
local depth = (hide and round(frame['aa']['depth']) or round(val['depth']))
local result = '\n|- style="border-top:1px solid; font-weight:bold; text-align:right; vertical-align:top;'
local result = mw.html.create('tr')
.. (hide and ' line-height:0; visibility:hidden; border-top-color:transparent;' or ' border-top-color:#a2a9b1;') .. '"'
:addClass('sortbottom' .. (hide and ' nomobile' or ''))
.. (hide and ' class="nomobile"' or '') .. '\n'
:attr('style', (hide and ' line-height:0; visibility:hidden; white-space:nowrap;' or ''))
.. '!style="border:0; ' .. cellHide .. '"| ' .. num
if hide then
result:attr('aria-hidden', 'true')
end
result:tag('th')
:wikitext(string.format('<span aria-hidden="true">%s</span>', num))
:attr('style', cellStyleHide)
-- zh-classical — самое длинное название раздела
-- zh-classical — самое длинное название раздела
result = result .. '|' .. createCell('zh-classical', cellHide)
result:tag('th')
.. '|' .. createCell('Всего', cell .. ' text-align:left;')
:wikitext('<span aria-hidden="true">zh-classical</span>')
.. '|' .. createCell(val['articles'], cell, true)
:attr('style', cellStyleHide)
.. '|' .. createCell(val['pages'], cell, true)
.. '|' .. createCell(val['edits'], cell, true)
result:tag('th')
.. '|' .. createCell(depth, cell, true)
:attr('scope', 'col')
.. '|' .. createCell(val['users'], cell, true)
:wikitext('Всего')
.. '|' .. createCell(val['activeusers'], cell, true)
:attr('style', cellStyle)
.. '|' .. createCell(val['admins'], cell, true)
:css('text-align', 'left')
.. '|' .. createCell(val['files'], cell, true)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['articles']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['pages']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['edits']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(depth))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['users']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['activeusers']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['admins']))
:attr('style', cellStyle)
result:tag('th')
:attr('scope', 'col')
:wikitext(renderNum(val['files']))
:attr('style', cellStyle)
return result
return result
Строка 258: Строка 333:
local data = mw.loadData('Модуль:NumberOf/data')
local data = mw.loadData('Модуль:NumberOf/data')
return renderNum(frame.args, data)
return getParam(frame.args, data)
end
end


Строка 265: Строка 340:
local data = mw.loadData('Модуль:NumberOf/today')
local data = mw.loadData('Модуль:NumberOf/today')
return renderNum(frame.args, data)
return getParam(frame.args, data)
end
end


-- Функция для вывода в [[Тептар:Список Тептар]]
-- Функция для вывода в [[Википедия:Список Википедий]]
function p.Editions(frame)
function p.Editions(frame)
local data = mw.loadData('Модуль:NumberOf/today')
local data = mw.loadData('Модуль:NumberOf/today')
Строка 324: Строка 399:
-- Автоматический скролл для недостаточно широких мониторов
-- Автоматический скролл для недостаточно широких мониторов
result = result .. '\n<div style="overflow-x:auto; overflow-y:hidden;">\n' .. createHeader()
local section = mw.html.create('div')
:attr('style', 'overflow-x:auto; overflow-y:hidden;')
local sectionTable = createHeader()


-- Вывод рядов таблицы
-- Вывод рядов таблицы
Строка 330: Строка 408:
if val ~= false then
if val ~= false then
local curr = data[val]
local curr = data[val]
result = result .. createRow(val, curr, frame)
sectionTable:node(createRow(val, curr, frame))
end
end
end
end
-- Вывод подвала таблицы
-- Вывод подвала таблицы
result = result .. createFooter(data, (n ~= 0))
sectionTable:node(createFooter(data, (n ~= 0)))
result = result .. '\n|}\n</div>'
section:node(sectionTable)
result = result .. '\n' .. tostring(section)
end
end

Текущая версия от 12:18, 11 февраля 2022

Данный модуль используется для отображения и обновления шаблонов {{NUMBEROF}} и {{TODAYNUMBEROF}}, использующихся для отображения статистики по другим разделам Тептар. Помимо этого, с помощью данного модуля отображается список Тептар. Подстраницы с данными этого модуля периодично обновляются ботом Adam.

Функции и параметры[править код]

Доступные функции:

  • Editions — функция (без параметров) для вывода таблиц с языковыми разделами Тептар, отсортированными по количеству статей (используется на странице Тептар:Список Тептар). Использует страницу Модуль:NumberOf/today в качестве списка данных (обновляется ботом ежедневно) и страницу Модуль:NumberOf/lang для отображения названий языков.
  • Now — функция для вывода наиболее актуальной статистики (используется в шаблоне {{NUMBEROF}}). Использует Модуль:NumberOf/data (обновляется ботом раз в 2 часа) в качестве списка данных.
  • Today — функция для вывода статистики по состоянию на начало текущего UTC-дня (используется в шаблоне {{TODAYNUMBEROF}}). Использует Модуль:NumberOf/today (обновляется ботом ежедневно) в качестве списка данных.

Параметры, используемые функциями Now и Today:

  • wiki — код раздела Тептар (обязательный параметр; список кодов доступен в списке разделов Тептар);
  • param — необходимые данные (обязательный параметр):
    articles — количество статей в разделе,
    admins — количество администраторов,
    activeusers — количество активных участников,
    date — дата обновления данных в модуле,
    depth — глубина раздела,
    edits — количество правок в разделе,
    files — количество файлов,
    pages — количество страниц,
    pos — место раздела по количеству статей (см. список Тептар),
    users — количество участников.
  • fmt — форматирование числа (принимает любое непустое значение).

Использование[править код]

Формат использования:

  • {{#invoke:NumberOf|Editions}}
  • {{#invoke:NumberOf|Now|wiki=en|param=articles}} — 6451528 (неформатированное значение)
  • {{#invoke:NumberOf|Now|wiki=en|param=articles|fmt=N}} — 6 451 528 (форматированное значение)

Дату последнего обновления страницы с данными можно узнать с помощью конструкции {{#invoke:NumberOf|Now|wiki=en|param=date}} (11 февраля 2022, 10:00 (UTC); параметр wiki может содержать любое непустое значение). На страницах с данными дата обновления шаблона представлена в UNIX-времени.

Представленные примеры с функцией Now работают и с функцией Today.


-- Модуль для шаблонов серии NUMBEROF и страницы [[Тептар:Список Тептар]]
local p = {}

-- Важнейшие переменные
local mwlang = mw.getContentLanguage()
local langs = mw.loadData('Module:NumberOf/lang')

-- Разделы Тептар, закрытые от редактирования
local readOnly = {
	aa = true,
	cho = true,
	ho = true,
	hz = true,
	ii = true,
	kj = true,
	kr = true,
	lrc = true,
	mh = true,
	mus = true,
	ng = true
}

-- Проверка пустоты параметра
local function isEmpty(s)
	return s == nil or s == ''
end

-- Округление до сотых
local function round(n)
	return math.floor(n * 100) / 100
end

-- Форматирование даты
local function formatDate(val)
	return mwlang:formatDate('j xg Y, G:i', val) .. ' (UTC)'
end

-- Длина таблицы
local function tableLength(t)
	local count = 0
	for _ in pairs(t) do count = count + 1 end
	return count
end

-- Вычисление вики по переданному номеру
local function calculatePosition(pos, info)
	pos = tonumber(pos)
	for key in pairs(info) do
		if key ~= 'total' and info[key]['pos'] == pos then
			return key
		end
	end
	
	return ''
end

-- Рендеринг необходимого параметра из страницы с данными
local function getParam(f, info)
	-- Парсинг параметров шаблона
	local wiki = f.wiki
	local param = f.param
	local fmt = f.fmt
	
	-- Если нет обязательных параметров, выводится ноль
	local result
	if isEmpty(wiki) or isEmpty(param) then
		result = 0
	else
		-- Убираем NUMBEROF из легаси-кода параметров
		param = param:lower():gsub('numberof','')
		
		if param == 'date' then
			result = formatDate(info['total']['date'])
			return result
		end
		
		if param == 'pos' and tonumber(wiki) ~= nil then
			-- 
			result = calculatePosition(wiki, info)
			return result
		end
		
		-- Расчёты для общего числа разделов
		if wiki == 'total' then
			if param == 'all' then
				result = tableLength(info) - 1
			end
			if param == 'active' then
				result = tableLength(info) - 1 - tableLength(readOnly)
			end
		end
		
		local obj = info[wiki]
		if obj ~= nil then
			if param ~= nil and info[wiki][param] ~= nil then
				result = info[wiki][param]
				
				-- Форматируем значение, если задан параметр
				if not isEmpty(fmt) and type(result) == 'number' then
					if param == 'depth' then
						result = math.floor(result * 100) / 100
					end
					result = mwlang:formatNum(result)
				end
			end
		else
			result = 0
		end
	end
	return tostring(result)
end

-- Вывод ссылки на языковой раздел
local function renderLink(val, text)
	local text = (isEmpty(text) and val or text)
	
	local result = ''
	if val ~= mwlang:getCode() then
		result = result .. '[[:' .. val ..  ':|'
		
		if readOnly[val] == true then
			result = result .. string.format('<s title="Данный раздел закрыт и доступен только в режиме для чтения">%s</s>', text)
		else
			result = result .. text
		end
		
		result = result .. ']]'
	else
		result = result .. text
	end
	return result
end

-- Вывод названия языка
local function renderLang(val, frame)
	local text = langs[val] and langs[val][1] or mwlang:ucfirst(mw.language.fetchLanguageName(val))
	local link = langs[val] and langs[val][2] or nil
	local result = text
	if readOnly[val] == true then
		result = '<s title="Данный раздел закрыт и доступен только в режиме для чтения">' .. text .. '</s> (закрыт)'
	end
	
	if not isEmpty(link) then
		result = string.format('[[:%s|%s]]', link, result)
	end

	if val == mwlang:getCode() then
		result = result .. ' [[File:Mw-unwatch-icon.svg|16px|text-top|alt=(текущий раздел)|link=]]'
	end
	
	return result
end

-- Функция для вывода ячейки
local function renderNum(val, key, stats)
	local text = mwlang:formatNum(val)
	if isEmpty(stats) or val == 0 then
		return text
	end
	
	return string.format(
		'[[:%s:%s|%s]]',
		key,
		stats,
		text
	)
end

-- Функция для вывода ряда таблицы
local function createRow(key, val, frame)
	local result = mw.html.create('tr')
		:css('text-align', 'right')
	if key == mwlang:getCode() then
		result
			:css('background', '#d5fdf4')
			:css('font-weight', 'bold')
	end
	
	result:tag('td')
		:wikitext(val['pos'])
	
	result:tag('td')
		:wikitext(renderLink(key))
	
	result:tag('td')
		:wikitext(renderLang(key, frame))
		:css('text-align', 'left')
	
	result:tag('td')
		:wikitext(renderNum(val['articles'], key, 'Special:Statistics'))
	
	result:tag('td')
		:wikitext(renderNum(val['pages']))
	
	result:tag('td')
		:wikitext(renderNum(val['edits']))
	
	result:tag('td')
		:wikitext(renderNum(round(val['depth'])))
	
	result:tag('td')
		:wikitext(renderNum(val['users'], key, 'Special:ListUsers'))
	
	result:tag('td')
		:wikitext(renderNum(val['activeusers'], key, 'Special:ActiveUsers'))
	
	result:tag('td')
		:wikitext(renderNum(val['admins'], key, 'Special:ListAdmins'))
	
	result:tag('td')
		:wikitext(renderNum(val['files'], key, 'Special:ListFiles'))
	
	return result
end

-- Функция для вывода шапки таблицы
local function createHeader()
	local result = mw.html.create('table')
		:addClass('wikitable sortable')
		:attr('style', 'font-feature-settings:"tnum" 1; margin:0.25em 0; width:100%;')
		:css('width', '100%')
		:css('margin', '0.25em 0')
	
	result:tag('tr')
	
	local cells = {
		'№',
		'Код',
		'Язык',
		'Статей',
		'Страниц',
		'Правок',
		'<abbr title="Глубина">Глуб.</abbr>',
		'Участников',
		'<abbr title="Активных участников">(акт.)</abbr>',
		'<abbr title="Администраторов">Адм.</abbr>',
		'Файлов',
	}
	
	for i, val in ipairs(cells) do
		result
			:tag('th')
			:attr('scope', 'col')
			:css('text-align', (val == 'Язык' and 'left' or 'right'))
			:css('width', (val == 'Язык' and '25%' or nil))
			:wikitext(val)
	end
	
	return result
end

-- Функция для вывода подвала таблицы
local function createFooter(frame, hide)
	-- Параметр hide отвечает за оптическое выравнивание таблиц
	local val = frame['total']
	local cellStyle = 'text-align:right;'
	local cellStyleHide = 'color:transparent; padding:0; white-space:nowrap;'
	if hide then
		cellStyle = 'padding:0;' .. cellStyle
	end
	
	-- aa — закрытый раздел с самой большой глубиной
	local num = tableLength(frame) - 1
	local depth = (hide and round(frame['aa']['depth']) or round(val['depth']))
	local result = mw.html.create('tr')
		:addClass('sortbottom' .. (hide and ' nomobile' or ''))
		:attr('style', (hide and ' line-height:0; visibility:hidden; white-space:nowrap;' or ''))
	
	if hide then
		result:attr('aria-hidden', 'true')
	end
	
	result:tag('th')
		:wikitext(string.format('<span aria-hidden="true">%s</span>', num))
		:attr('style', cellStyleHide)
	
	-- zh-classical — самое длинное название раздела
	result:tag('th')
		:wikitext('<span aria-hidden="true">zh-classical</span>')
		:attr('style', cellStyleHide)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext('Всего')
		:attr('style', cellStyle)
		:css('text-align', 'left')
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['articles']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['pages']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['edits']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(depth))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['users']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['activeusers']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['admins']))
		:attr('style', cellStyle)
	
	result:tag('th')
		:attr('scope', 'col')
		:wikitext(renderNum(val['files']))
		:attr('style', cellStyle)
	
	return result
end

-- Функция для вывода в {{NUMBEROF}}
function p.Now(frame)
	local data = mw.loadData('Модуль:NumberOf/data')
	
	return getParam(frame.args, data)
end

-- Функция для вывода в {{TODAYNUMBEROF}}
function p.Today(frame)
	local data = mw.loadData('Модуль:NumberOf/today')
	
	return getParam(frame.args, data)
end

-- Функция для вывода в [[Википедия:Список Википедий]]
function p.Editions(frame)
	local data = mw.loadData('Модуль:NumberOf/today')
	local length = tableLength(data)
	local result = ''
	
	-- Таблица для сбора разделов по величине
	local sorted = {
		[1000000] = {},
		[100000] = {},
		[10000] = {},
		[1000] = {},
		[0] = {}
	}
	local sortedKeys = { 0, 1000, 10000, 100000, 1000000 }
	
	-- Заполняем пустыми элементами каждую таблицу
	for i = #sortedKeys, 1, -1 do
		local n = sortedKeys[i]
		for j = 1, length, 1 do
			table.insert(sorted[n], false)
		end
	end
	
	-- Сортировка разделов по позиции и величине
	for key, val in pairs(data) do
		local curr = data[key]
		if key ~= 'total' then
			if curr['articles'] <= 1000 then
				sorted[ 0 ][ tonumber(curr['pos']) ] = key
			else
				for i = #sortedKeys, 2, -1 do
					local n = sortedKeys[i]
					if curr['articles'] / n > 1 then
						sorted[ n ][ tonumber(curr['pos']) ] = key
						break
					end
				end
			end
		end
	end
	
	-- Вывод таблицы
	for i = #sortedKeys, 1, -1 do
		if i ~= #sortedKeys then
			result = result .. '\n'
		end
		
		local n = sortedKeys[i]
		if n == 0 then 
			result = result .. '=== Менее 1000 статей ==='
		else
			result = result .. string.format('=== Более %s статей ===', mwlang:formatNum(n))
		end
		
		-- Автоматический скролл для недостаточно широких мониторов
		local section = mw.html.create('div')
			:attr('style', 'overflow-x:auto; overflow-y:hidden;')
		
		local sectionTable = createHeader()

		-- Вывод рядов таблицы
		for _, val in ipairs(sorted[n]) do
			if val ~= false then
				local curr = data[val]
				sectionTable:node(createRow(val, curr, frame))
			end
		end
		
		-- Вывод подвала таблицы
		sectionTable:node(createFooter(data, (n ~= 0)))
		section:node(sectionTable)
		
		result = result .. '\n' .. tostring(section)
	end
	
	return result
end

return p