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

Материал из ЧТМ
Перейти к навигации Перейти к поиску
-- Версия 0.2
Версия 1.0, работает и для искомой страницы, и как чистый движок, всё тщательно протестировано
 
(не показано 10 промежуточных версий этого же участника)
Строка 1: Строка 1:
-- ==========================================
-- =====================================================
-- Модуль:Significance (Калькулятор Значимости ЧТМ)
-- Модуль:Significance (калькулятор значимости игроков)
-- Версия 0.2
-- Версия 1.0
-- ==========================================
-- =====================================================
local Significance = {}
local Significance = {}


local Config = require('Module:Config')
local StatEngine = require('Module:StatEngine')
local StatEngine = require('Module:StatEngine')
local Megarating = require('Module:Megarating')
local Megarating = require('Module:Megarating')
-- Вспомогательная функция: Выводит галочку или крестик
local function mark(condition)
    return condition and '<span style="color:green;">✅ Да</span>' or '<span style="color:red;">❌ Нет</span>'
end


-- ==========================================
-- ==========================================
-- ЯДРО ЛОГИКИ: ОЦЕНКА ОДНОГО ИГРОКА
-- РУЧНЫЕ ИСКЛЮЧЕНИЯ (Особые случаи)
-- Возвращает: Уровень (string), Лог проверок (string)
-- ==========================================
-- ==========================================
function Significance.evaluate_player(p_stats, mr_data)
local SPECIAL_CASES = {
     local logs = {}
    ["Амид"] = "[[ЦАР-КИР2026|о.случай]]",
     local function log_cat(title) table.insert(logs, "\n=== " .. title .. " ===") end
     ["Губа"] = "[[Финал ЧТМ-2014#Дополнительное время|о.случай]]",
    local function log_item(text) table.insert(logs, text) end
     ["Другой Очкан"] = "[[ДОМ-АФГ2018#Серия пенальти|о.случай]]",
    ["Рамиз"] = "[[ДОМ-АФГ2018#Серия пенальти|о.случай]]",
}
 
-- =====================================================
-- API ДВИЖКА (Для использования во внешних "Монстрах")
-- =====================================================
 
-- 1. Выдает пустую "болванку" (схему) для нового игрока
function Significance.createPlayerStruct(name)
    return {
        name = name,
        tournaments_played = 0, top5 = 0, top10 = 0,
        matches_total = 0, goals = {total=0}, assists = {total=0}, mvp = {is_mvp=0},
        megarating = {final_goals=0, final_assists=0},
        awards = {
            golden_spheres=0, other_spheres=0, golden_shoes=0, other_shoes=0,
            golden_assistants=0, other_assistants=0, best_goalies=0,
            superchamps=0, titles=0, finals_played=0
        }
    }
end


    -- СБОР ДОСЬЕ ИГРОКА
-- 2. Вливает статистику из БД одного года в общую копилку игрока
    local aw = p_stats.awards or {}
function Significance.mergeStats(target, source)
     local mr = p_stats.megarating or {}
     target.matches_total = (target.matches_total or 0) + (source.matches_total or 0)
   
     target.goals.total = (target.goals.total or 0) + (source.goals.total or 0)
    local gold_spheres = aw.golden_spheres or 0
     target.assists.total = (target.assists.total or 0) + (source.assists.total or 0)
    local titles = aw.titles or 0
     target.mvp.is_mvp = (target.mvp.is_mvp or 0) + (source.mvp.is_mvp or 0)
     local superchamps = aw.superchamps or 0
    local goals = p_stats.goals.total or 0
    local assists = p_stats.assists.total or 0
     local mvps = p_stats.mvp.is_mvp or 0
   
    local finals_goals = mr.final_goals or 0
    local finals_assists = mr.final_assists or 0
    local finals_played = aw.finals_played or 0
   
    -- Сумма призов (согласно правилам: Шары кроме золотого + любые Башмаки + Вратарь)
     local sum_awards = (aw.other_spheres or 0) + (aw.golden_shoes or 0) + (aw.other_shoes or 0) + (aw.best_goalies or 0)
    local any_award_exist = (sum_awards > 0) or (gold_spheres > 0)
      
      
     -- Данные из кэша Мегарейтинга
     target.megarating.final_goals = (target.megarating.final_goals or 0) + (source.megarating.final_goals or 0)
    local top5 = mr_data and mr_data.top5 or 0
     target.megarating.final_assists = (target.megarating.final_assists or 0) + (source.megarating.final_assists or 0)
     local top10 = mr_data and mr_data.top10 or 0
      
      
     -- Считаем количество сыгранных турниров (проверяем ключи в таблице years из GrandStats)
     if source.awards then
    local tournaments_played = 0
        target.awards.golden_spheres = target.awards.golden_spheres + (source.awards.golden_spheres or 0)
    if p_stats.years then
        target.awards.other_spheres = target.awards.other_spheres + (source.awards.other_spheres or 0)
         for _, _ in pairs(p_stats.years) do tournaments_played = tournaments_played + 1 end
        target.awards.golden_shoes = target.awards.golden_shoes + (source.awards.golden_shoes or 0)
        target.awards.other_shoes = target.awards.other_shoes + (source.awards.other_shoes or 0)
        target.awards.golden_assistants = target.awards.golden_assistants + (source.awards.golden_assistants or 0)
        target.awards.other_assistants = target.awards.other_assistants + (source.awards.other_assistants or 0)
        target.awards.best_goalies = target.awards.best_goalies + (source.awards.best_goalies or 0)
        target.awards.superchamps = target.awards.superchamps + (source.awards.superchamps or 0)
         target.awards.titles = target.awards.titles + (source.awards.titles or 0)
        target.awards.finals_played = target.awards.finals_played + (source.awards.finals_played or 0)
     end
     end
   
end
    local matches = p_stats.matches_total or 0


    log_cat("ДОСЬЕ: " .. p_stats.name)
-- 3. ЧИСТЫЙ КАЛЬКУЛЯТОР. Принимает заполненную структуру, возвращает уровень значимости.
    log_item("Турниров: " .. tournaments_played .. " | Матчей: " .. matches .. " | Финалов: " .. finals_played)
function Significance.evaluatePlayer(p_stats)
    log_item("Голы: " .. goals .. " (в финалах: " .. finals_goals .. ")")
     local aw = p_stats.awards
     log_item("Ассисты: " .. assists .. " (в финалах: " .. finals_assists .. ")")
     local sum_awards = aw.other_spheres + aw.golden_shoes + aw.other_shoes + aw.best_goalies
     log_item("MVP: " .. mvps)
     local any_award_exist = (sum_awards > 0) or (aw.golden_spheres > 0)
    log_item("Титулы: " .. titles .. " | Суперчемпионства: " .. superchamps)
     log_item("Золотых шаров: " .. gold_spheres .. " | Других призов (для суммы): " .. sum_awards)
    log_item("В топ-5: " .. top5 .. " | В топ-10: " .. top10)


    -- ==========================================
     -- 1. МАКСИМАЛЬНАЯ
     -- 1. МАКСИМАЛЬНАЯ ЗНАЧИМОСТЬ
     local m_c1 = (aw.golden_spheres >= 1)
    -- ==========================================
     local m_c2 = (aw.titles >= 2 or aw.superchamps >= 1)
    log_cat("Проверка: Максимальная")
     local m_c3 = (p_stats.goals.total >= 75 or p_stats.assists.total >= 50 or p_stats.mvp.is_mvp >= 20)
     local m_c1 = (gold_spheres >= 1); log_item(mark(m_c1) .. " 1. Обязательно: Минимум один Золотой Шар")
     local m_c4 = (p_stats.megarating.final_goals >= 2 or p_stats.megarating.final_assists >= 3 or aw.finals_played >= 4)
     local m_c2 = (titles >= 2 or superchamps >= 1); log_item(mark(m_c2) .. " 2. Минимум два титула или одно суперчемпионство")
     local m_c5 = (sum_awards >= 4)
     local m_c3 = (goals >= 75 or assists >= 50 or mvps >= 20); log_item(mark(m_c3) .. " 3. Голы >= 75 ИЛИ ассисты >= 50 ИЛИ MVP >= 20")
     local m_c6 = (p_stats.top5 >= 2 or p_stats.top10 >= 4)
     local m_c4 = (finals_goals >= 2 or finals_assists >= 3 or finals_played >= 4); log_item(mark(m_c4) .. " 4. В финале: голы >= 2 ИЛИ ассисты >= 3 ИЛИ сыграно финалов >= 4")
     if m_c1 and ((m_c1 and 1 or 0) + (m_c2 and 1 or 0) + (m_c3 and 1 or 0) + (m_c4 and 1 or 0) + (m_c5 and 1 or 0) + (m_c6 and 1 or 0)) >= 4 then return "Максимальная" end
     local m_c5 = (sum_awards >= 4); log_item(mark(m_c5) .. " 5. Минимум 4 любых Шара (кр. золотого), Башмака или Вратаря")
     local m_c6 = (top5 >= 2 or top10 >= 4); log_item(mark(m_c6) .. " 6. Мегарейтинг: топ-5 >= 2 ИЛИ топ-10 >= 4")
      
    local m_score = (m_c1 and 1 or 0) + (m_c2 and 1 or 0) + (m_c3 and 1 or 0) + (m_c4 and 1 or 0) + (m_c5 and 1 or 0) + (m_c6 and 1 or 0)
    log_item("Итого критериев: " .. m_score .. "/6")
   
    if m_c1 and m_score >= 4 then
        return "Максимальная", table.concat(logs, "\n")
    end


    -- ==========================================
     -- 2. ВЫСОКАЯ
     -- 2. ВЫСОКАЯ ЗНАЧИМОСТЬ
     local h_score = (any_award_exist and 1 or 0) + ((aw.titles >= 1) and 1 or 0) + ((p_stats.goals.total >= 40 or p_stats.assists.total >= 25 or p_stats.mvp.is_mvp >= 10) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 2 or aw.finals_played >= 3) and 1 or 0) + ((p_stats.tournaments_played >= 6) and 1 or 0) + ((p_stats.top5 >= 1 or p_stats.top10 >= 3) and 1 or 0)
     -- ==========================================
     if h_score >= 4 then return "Высокая" end
    log_cat("Проверка: Высокая")
    local h_c1 = any_award_exist; log_item(mark(h_c1) .. " 1. Минимум один любой Шар, Башмак или титул лучшего вратаря")
    local h_c2 = (titles >= 1); log_item(mark(h_c2) .. " 2. Завоёван хотя бы один титул")
    local h_c3 = (goals >= 40 or assists >= 25 or mvps >= 10); log_item(mark(h_c3) .. " 3. Голы >= 40 ИЛИ ассисты >= 25 ИЛИ MVP >= 10")
    local h_c4 = (finals_goals >= 1 or finals_assists >= 2 or finals_played >= 3); log_item(mark(h_c4) .. " 4. В финале: голы >= 1 ИЛИ ассисты >= 2 ИЛИ сыграно финалов >= 3")
    local h_c5 = (tournaments_played >= 6); log_item(mark(h_c5) .. " 5. Участие минимум в 6 турнирах")
    local h_c6 = (top5 >= 1 or top10 >= 3); log_item(mark(h_c6) .. " 6. Мегарейтинг: топ-5 >= 1 ИЛИ топ-10 >= 3")
   
    local h_score = (h_c1 and 1 or 0) + (h_c2 and 1 or 0) + (h_c3 and 1 or 0) + (h_c4 and 1 or 0) + (h_c5 and 1 or 0) + (h_c6 and 1 or 0)
    log_item("Итого критериев: " .. h_score .. "/6")
   
     if h_score >= 4 then
        return "Высокая", table.concat(logs, "\n")
    end


    -- ==========================================
     -- 3. СРЕДНЯЯ
     -- 3. СРЕДНЯЯ ЗНАЧИМОСТЬ
     local a_score = (any_award_exist and 1 or 0) + ((aw.titles >= 1) and 1 or 0) + ((p_stats.goals.total >= 20 or p_stats.assists.total >= 15 or p_stats.mvp.is_mvp >= 5) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 2 or aw.finals_played >= 3) and 1 or 0) + ((p_stats.tournaments_played >= 4) and 1 or 0) + ((p_stats.top5 >= 1 or p_stats.top10 >= 2) and 1 or 0)
     -- ==========================================
     if a_score >= 2 then return "Средняя" end
    log_cat("Проверка: Средняя")
    local a_c1 = any_award_exist; log_item(mark(a_c1) .. " 1. Минимум один любой Шар, Башмак или титул лучшего вратаря")
    local a_c2 = (titles >= 1); log_item(mark(a_c2) .. " 2. Завоёван хотя бы один титул")
    local a_c3 = (goals >= 20 or assists >= 15 or mvps >= 5); log_item(mark(a_c3) .. " 3. Голы >= 20 ИЛИ ассисты >= 15 ИЛИ MVP >= 5")
    local a_c4 = (finals_goals >= 1 or finals_assists >= 2 or finals_played >= 3); log_item(mark(a_c4) .. " 4. В финале: голы >= 1 ИЛИ ассисты >= 2 ИЛИ сыграно финалов >= 3")
    local a_c5 = (tournaments_played >= 4); log_item(mark(a_c5) .. " 5. Участие минимум в 4 турнирах")
    local a_c6 = (top5 >= 1 or top10 >= 2); log_item(mark(a_c6) .. " 6. Мегарейтинг: топ-5 >= 1 ИЛИ топ-10 >= 2")
   
    local a_score = (a_c1 and 1 or 0) + (a_c2 and 1 or 0) + (a_c3 and 1 or 0) + (a_c4 and 1 or 0) + (a_c5 and 1 or 0) + (a_c6 and 1 or 0)
    log_item("Итого критериев: " .. a_score .. "/6")
   
     if a_score >= 2 then
        return "Средняя", table.concat(logs, "\n")
    end


    -- ==========================================
     -- 4. НИЖЕ СРЕДНЕГО
     -- 4. НИЖЕ СРЕДНЕГО
     -- ==========================================
     local main_score = ((p_stats.goals.total >= 10) and 1 or 0) + ((aw.titles >= 1 or aw.finals_played >= 2) and 1 or 0) + ((p_stats.tournaments_played >= 3) and 1 or 0) + ((p_stats.mvp.is_mvp >= 3) and 1 or 0) + ((p_stats.assists.total >= 8) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 1) and 1 or 0) + ((p_stats.top10 >= 1) and 1 or 0)
    log_cat("Проверка: Ниже среднего")
     local sub_score = ((p_stats.goals.total >= 5) and 1 or 0) + ((aw.finals_played >= 1) and 1 or 0) + ((p_stats.tournaments_played >= 2) and 1 or 0) + ((p_stats.mvp.is_mvp >= 2) and 1 or 0) + ((p_stats.assists.total >= 4) and 1 or 0)
    local b_m1 = (goals >= 10); local b_s1 = (goals >= 5); log_item("1. Голы: " .. mark(b_m1) .. " осн (>=10) | " .. mark(b_s1) .. " доп (>=5)")
    if main_score >= 1 or sub_score >= 2 then return "Ниже среднего" end
     local b_m2 = (titles >= 1 or finals_played >= 2); local b_s2 = (finals_played >= 1); log_item("2. Титул или Финалы: " .. mark(b_m2) .. " осн (титул/финалы>=2) | " .. mark(b_s2) .. " доп (финалы>=1)")
 
     local b_m3 = (tournaments_played >= 3); local b_s3 = (tournaments_played >= 2); log_item("3. Турниры: " .. mark(b_m3) .. " осн (>=3) | " .. mark(b_s3) .. " доп (>=2)")
    -- 5. НИЗКАЯ
    local b_m4 = (mvps >= 3); local b_s4 = (mvps >= 2); log_item("4. MVP: " .. mark(b_m4) .. " осн (>=3) | " .. mark(b_s4) .. " доп (>=2)")
     local l_score = ((p_stats.goals.total >= 1) and 1 or 0) + ((aw.finals_played >= 1) and 1 or 0) + ((p_stats.tournaments_played >= 3) and 1 or 0) + ((p_stats.mvp.is_mvp >= 1) and 1 or 0) + ((p_stats.assists.total >= 2) and 1 or 0) + ((p_stats.matches_total >= 10) and 1 or 0)
    local b_m5 = (assists >= 8); local b_s5 = (assists >= 4); log_item("5. Ассисты: " .. mark(b_m5) .. " осн (>=8) | " .. mark(b_s5) .. " доп (>=4)")
    if l_score >= 1 or SPECIAL_CASES[p_stats.name] then return "Низкая" end
    local b_m6 = (finals_goals >= 1 or finals_assists >= 1); log_item("6. В финале гол или пас: " .. mark(b_m6) .. " осн")
 
    local b_m7 = (top10 >= 1); log_item("7. Мегарейтинг Топ-10: " .. mark(b_m7) .. " осн")
    return "Случайный прохожий"
   
end
    local main_score = (b_m1 and 1 or 0) + (b_m2 and 1 or 0) + (b_m3 and 1 or 0) + (b_m4 and 1 or 0) + (b_m5 and 1 or 0) + (b_m6 and 1 or 0) + (b_m7 and 1 or 0)
 
    local sub_score = (b_s1 and 1 or 0) + (b_s2 and 1 or 0) + (b_s3 and 1 or 0) + (b_s4 and 1 or 0) + (b_s5 and 1 or 0)
 
    log_item("Итого: Основных: " .. main_score .. ", Дополнительных: " .. sub_score)
-- =====================================================
   
-- ВНУТРЕННИЙ ФУНКЦИОНАЛ ДЛЯ ОТРИСОВКИ СТРАНИЦЫ
    if main_score >= 1 or sub_score >= 2 then
-- =====================================================
         return "Ниже среднего", table.concat(logs, "\n")
 
local function get_plural_players(count)
    local d10 = count % 10
    local d100 = count % 100
    if d10 == 1 and d100 ~= 11 then return count .. " игрок"
    elseif d10 >= 2 and d10 <= 4 and (d100 < 10 or d100 >= 20) then return count .. " игрока"
    else return count .. " игроков" end
end
 
local function cell(text, is_main, is_sub)
    local bg = ""
    if is_main then bg = Config.styles.lightgreen
    elseif is_sub then bg = Config.styles.palegoldenrod end
    return { text = tostring(text), style = Config.styles.center_nowrap .. bg }
end
 
local _grand_cache = nil
 
local function build_master_database()
    if _grand_cache then return _grand_cache end
    local GrandStats = {}
    local latest_year = Config.years[#Config.years]
    local is_latest_finished = Config.is_latest_finished
 
    for _, year in ipairs(Config.years) do
        local is_finished = (year ~= latest_year) or is_latest_finished
        local success, year_db = pcall(require, 'Module:Data/' .. year)
       
        if success and type(year_db) == "table" then
            local year_stats = StatEngine.Harvester.run(year_db, {need_players = true})
            for p_name, p_data in pairs(year_stats.Players) do
                if not GrandStats[p_name] then
                    -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
                    GrandStats[p_name] = Significance.createPlayerStruct(p_name)
                end
                GrandStats[p_name].tournaments_played = GrandStats[p_name].tournaments_played + 1
                -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
                Significance.mergeStats(GrandStats[p_name], p_data)
            end
           
            if is_finished then
                local mr_list = Megarating.evaluate_raw_stats(year, year_db, year_stats.Players)
                local spheres = Megarating.get_spheres_from_db(year_db)
                if #mr_list > 0 then
                    table.sort(mr_list, function(a, b) return Megarating.compare_players_public(a, b, year, spheres) end)
                    local current_rank = 1
                    for i, p in ipairs(mr_list) do
                        if i > 1 and p.total_points ~= mr_list[i-1].total_points then current_rank = i end
                        if current_rank <= 10 then
                            if GrandStats[p.name] then
                                GrandStats[p.name].top10 = GrandStats[p.name].top10 + 1
                                if current_rank <= 5 then GrandStats[p.name].top5 = GrandStats[p.name].top5 + 1 end
                            end
                        else break end
                    end
                end
            end
         end
     end
     end
    _grand_cache = GrandStats
    return _grand_cache
end
-- (Тут идёт функция build_tier_table без изменений)
local function build_tier_table(tier, list)
    if #list == 0 then return "" end
    local html
    for _, p in ipairs(list) do
        local aw = p.awards
        local g = p.goals.total
        local a = p.assists.total
        local m = p.mvp.is_mvp
        local fg = p.megarating.final_goals
        local fa = p.megarating.final_assists
        local fp = aw.finals_played
        local tp = p.tournaments_played
        local t5 = p.top5
        local t10 = p.top10
       
        -- Группировка наград для вывода
        local all_shoes = aw.golden_shoes + aw.other_shoes
        local all_spheres = aw.golden_spheres + aw.other_spheres
        local other_spheres = aw.other_spheres
        local goalies = aw.best_goalies
       
        local sum_aw = other_spheres + all_shoes + goalies
        local sum_all_aw = all_spheres + all_shoes + goalies
       
        if tier == "Максимальная" then
            if not html then html = Config.builder.start({"Игрок", "ЗШ", "Ч/СЧ", "Г/П/MVP", "ГФ/ПФ/УФ", "Ш/Б/В", "М5/М10"}) end
            local c1 = aw.golden_spheres >= 1
            local c2 = aw.titles >= 2 or aw.superchamps >= 1
            local c3 = g >= 75 or a >= 50 or m >= 20
            local c4 = fg >= 2 or fa >= 3 or fp >= 4
            local c5 = sum_aw >= 4
            local str_awards = other_spheres .. " / " .. all_shoes .. " / " .. goalies
            local c6 = t5 >= 2 or t10 >= 4
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(aw.golden_spheres, c1), cell(aw.titles .. " / " .. aw.superchamps, c2),
                cell(g .. " / " .. a .. " / " .. m, c3), cell(fg .. " / " .. fa .. " / " .. fp, c4),
                cell(str_awards, c5), cell(t5 .. " / " .. t10, c6)
            })
        elseif tier == "Высокая" or tier == "Средняя" then
            if not html then html = Config.builder.start({"Игрок", "Ш/Б/В", "Ч", "Г/П/MVP", "ГФ/ПФ/УФ", "ФТ", "М5/М10"}) end
            local c1 = sum_all_aw >= 1
            local c2 = aw.titles >= 1
            local c3, c4, c5, c6
            if tier == "Высокая" then
                c3 = g >= 40 or a >= 25 or m >= 10
                c4 = fg >= 1 or fa >= 2 or fp >= 3
                c5 = tp >= 6
                c6 = t5 >= 1 or t10 >= 3
            else
                c3 = g >= 20 or a >= 15 or m >= 5
                c4 = fg >= 1 or fa >= 2 or fp >= 3
                c5 = tp >= 4
                c6 = t5 >= 1 or t10 >= 2
            end
            local str_awards = all_spheres .. " / " .. all_shoes .. " / " .. goalies
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(str_awards, c1), cell(aw.titles, c2),
                cell(g .. " / " .. a .. " / " .. m, c3), cell(fg .. " / " .. fa .. " / " .. fp, c4),
                cell(tp, c5), cell(t5 .. " / " .. t10, c6)
            })
        elseif tier == "Ниже среднего" then
            if not html then html = Config.builder.start({"Игрок", "Г", "Ч/Ф", "ФТ", "MVP", "П", "ГФ/ПФ", "М10"}) end
            local cg_m, cg_s = g >= 10, g >= 5
            local ccf_m, ccf_s = (aw.titles >= 1 or fp >= 2), fp >= 1
            local cft_m, cft_s = tp >= 3, tp >= 2
            local cm_m, cm_s = m >= 3, m >= 2
            local cp_m, cp_s = a >= 8, a >= 4
            local cgf_m = fg >= 1 or fa >= 1
            local ct10_m = t10 >= 1
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(g, cg_m, cg_s and not cg_m), cell(aw.titles .. " / " .. fp, ccf_m, ccf_s and not ccf_m),
                cell(tp, cft_m, cft_s and not cft_m), cell(m, cm_m, cm_s and not cm_m),
                cell(a, cp_m, cp_s and not cp_m), cell(fg .. " / " .. fa, cgf_m), cell(t10, ct10_m)
            })


    -- ==========================================
        elseif tier == "Низкая" then
    -- 5. НИЗКАЯ ЗНАЧИМОСТЬ
            if not html then html = Config.builder.start({"Игрок", "Г", "Ф", "ФТ", "MVP", "П", "М", "О.случай"}) end
    -- ==========================================
            local cg = g >= 1; local cf = fp >= 1; local cft = tp >= 3
    log_cat("Проверка: Низкая")
            local cmvp = m >= 1; local cp = a >= 2; local cm = p.matches_total >= 10
    local l_c1 = (goals >= 1); log_item(mark(l_c1) .. " 1. Забит хотя бы 1 гол")
            local sp = SPECIAL_CASES[p.name]
    local l_c2 = (finals_played >= 1); log_item(mark(l_c2) .. " 2. Участие в финале")
            local csp = sp ~= nil
    local l_c3 = (tournaments_played >= 3); log_item(mark(l_c3) .. " 3. Участие в 3 турнирах")
            Config.builder.row(html, {
    local l_c4 = (mvps >= 1); log_item(mark(l_c4) .. " 4. Признание MVP")
                "'''[[" .. p.name .. "]]'''",
    local l_c5 = (assists >= 2); log_item(mark(l_c5) .. " 5. Ассисты >= 2")
                cell(g, cg), cell(fp, cf), cell(tp, cft),
    local l_c6 = (matches >= 10); log_item(mark(l_c6) .. " 6. Сыграно >= 10 матчей")
                cell(m, cmvp), cell(a, cp), cell(p.matches_total, cm),
   
                cell(sp or "", csp)
    local l_score = (l_c1 and 1 or 0) + (l_c2 and 1 or 0) + (l_c3 and 1 or 0) + (l_c4 and 1 or 0) + (l_c5 and 1 or 0) + (l_c6 and 1 or 0)
            })
    log_item("Итого критериев: " .. l_score)
         end
   
    if l_score >= 1 then
         return "Низкая", table.concat(logs, "\n")
     end
     end
    return html and tostring(html) or ""
end
-- (Тут идёт таблица TEXT_BLOCKS и ORDER без изменений)
local TEXT_BLOCKS = {
    ["Максимальная"] = [=[== Максимальная значимость ==
Критерии:
# Минимум один [[Золотой Шар]].
# Минимум два титула чемпиона третьего мира или одно [[суперчемпион]]ство.
# [[Голы|Забито]] не менее 75 голов, [[Передачи|отдано]] не менее 50 подтверждённых голевых передач или не менее 20 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забито хотя бы два гола в финале, отданы хотя бы три голевые передачи в финале или принято участие минимум в четырёх финалах.
# Минимум четыре любых [[Золотой Шар|Шара]] (кроме Золотого), любых [[Золотой Башмак|Башмака]] или титула [[Приз имени Эльнура|лучшего вратаря]] (все призы суммируются).
# Минимум два вхождения в пятёрку [[мегарейтинг]]а или четыре — в десятку.
Для получения максимальной значимости необходимо удовлетворять минимум четырём критериям из шести, при этом '''наличие Золотого Шара является обязательным'''.]=],
    ["Высокая"] = [=[== Высокая значимость ==
Критерии:
# Минимум один любой [[Золотой Шар|Шар]], любой [[Золотой Башмак|Башмак]] или титул [[Приз имени Эльнура|лучшего вратаря]].
# Завоёван хотя бы один титул чемпиона третьего мира.
# [[Голы|Забито]] не менее 40 голов, [[Передачи|отдано]] не менее 25 подтверждённых голевых передач или не менее 10 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забит хотя бы один гол в финале, отданы хотя бы две голевые передачи в финале или принято участие минимум в трёх финалах.
# Участие минимум в шести [[Список участий в финальных турнирах|финальных турнирах ЧТМ]].
# Минимум одно вхождение в пятёрку [[мегарейтинг]]а или три — в десятку.
Для получения высокой значимости необходимо удовлетворять минимум четырём критериям из шести.]=],
    ["Средняя"] = [=[== Средняя значимость ==
Критерии:
# Минимум один любой [[Золотой Шар|Шар]], любой [[Золотой Башмак|Башмак]] или титул [[Приз имени Эльнура|лучшего вратаря]].
# Завоёван хотя бы один титул чемпиона третьего мира.
# [[Голы|Забито]] не менее 20 голов, [[Передачи|отдано]] не менее 15 подтверждённых голевых передач или не менее 5 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забит хотя бы один гол в финале, отданы хотя бы две голевые передачи в финале или принято участие минимум в трёх финалах.
# Участие минимум в четырёх [[Список участий в финальных турнирах|финальных турнирах ЧТМ]].
# Минимум одно вхождение в пятёрку [[мегарейтинг]]а или два — в десятку.
Для получения средней значимости необходимо удовлетворять минимум минимум двум критериям из шести.]=],
    ["Ниже среднего"] = [=[== Ниже среднего ==
Критерии:
# [[Голы|Забито]] не менее 10 (основной показатель) или 5 (дополнительный) голов.
# Завоёван хотя бы один титул чемпиона третьего мира или участие минимум в двух (основной) или одном (дополнительный) финале.
# Участие минимум в трёх (основной) или двух (дополнительный) финальных турнирах ЧТМ.
# Признание [[Список лучших игроков всех матчей ЧТМ|игроком матча]] не менее трёх (основной показатель) или двух (дополнительный) раз.
# [[Передачи|Отдано]] не менее 8 (основной показатель) или 4 (дополнительный) подтверждённых голевых передач.
# Забит хотя бы один гол или отдана хотя бы одна голевая передача в финале (основной показатель).
# Минимум одно вхождение в десятку [[мегарейтинг]]а.
Необходимо соответствовать хотя бы одному из критериев в первом случае и хотя бы двум во втором.]=],
    ["Низкая"] = [=[== Низкая ==
Критерии:
# [[Голы|Забит]] хотя бы один гол.
# Участие минимум в одном финале.
# Участие минимум в трёх финальных турнирах ЧТМ.
# Признание [[Список лучших игроков всех матчей ЧТМ|игроком матча]] хотя бы один раз.
# [[Передачи|Отданы]] хотя бы две подтверждённые голевые передачи.
# [[Матчи|Сыграно]] не менее 10 подтверждённых матчей.
Необходимо соответствовать хотя бы одному из критериев. В указанных дополнительно особых случаях возможно присвоение этого уровня случайным игрокам, хоть чем-то запомнившимся.]=],
    ["Случайный прохожий"] = [=[== Случайный прохожий ==
Случайные люди, приходившие играть один-два раза в проходных матчах и абсолютно ничем не запомнившиеся.]=]
}
local ORDER = {"Максимальная", "Высокая", "Средняя", "Ниже среднего", "Низкая", "Случайный прохожий"}


     -- ==========================================
function Significance.drawAll(frame)
     -- 6. СЛУЧАЙНЫЙ ПРОХОЖИЙ
     local db = build_master_database()
    -- ==========================================
     local bins = { ["Максимальная"]={}, ["Высокая"]={}, ["Средняя"]={}, ["Ниже среднего"]={}, ["Низкая"]={}, ["Случайный прохожий"]={} }
    log_cat("Проверка: Случайный прохожий")
    log_item("Не выполнил ни одного критерия низкого уровня.")
    return "Случайный прохожий", table.concat(logs, "\n")
end


-- ==========================================
    for _, p_stats in pairs(db) do
-- ОТЛАДОЧНЫЙ ВЫВОД ДЛЯ СТРАНИЦЫ WIKI (Тестирование)
        -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
-- Вызов: {{#invoke:Significance|test_player|player=Диман}}
        local level = Significance.evaluatePlayer(p_stats)
-- ==========================================
        table.insert(bins[level], p_stats)
function Significance.test_player(frame)
     end
     local target_player = frame.args.player or "Диман"
      
      
     -- 1. Получаем глобальную стату (БД прогружается из кэша Lua один раз)
     for _, list in pairs(bins) do table.sort(list, function(a, b) return a.name < b.name end) end
     local grand_stats = StatEngine.Harvester.run_all_time({need_players = true, keep_years = true})
 
      
     local out = {}
    -- 2. Получаем историю мест в Мегарейтинге
     for _, tier in ipairs(ORDER) do
    local mr_history = Megarating.get_public_history()
        local list = bins[tier]
   
        table.insert(out, TEXT_BLOCKS[tier])
    -- 3. Находим игрока
       
    local p_stats = grand_stats.Players[target_player]
        if tier == "Случайный прохожий" then
    if not p_stats then return "Игрок '" .. target_player .. "' не найден в БД." end
            table.insert(out, "\n'''Точное число игроков неизвестно:'''")
   
            local links = {}
    local mr_data = mr_history.players[target_player]
            for _, p in ipairs(list) do table.insert(links, "[[" .. p.name .. "]]") end
   
            table.insert(out, table.concat(links, ", ") .. ".")
    -- 4. Запускаем калькулятор
        else
    local level, log_text = Significance.evaluate_player(p_stats, mr_data)
            table.insert(out, "\n'''" .. get_plural_players(#list) .. ":'''")
   
            table.insert(out, build_tier_table(tier, list))
    -- 5. Возвращаем красивый сырой текст
        end
    local result = "== Результат оценки: " .. target_player .. " ==\n"
        table.insert(out, "")
    result = result .. "'''Присвоенный уровень: " .. level .. "'''\n\n"
     end
    result = result .. log_text
 
      
     return frame:preprocess(Config.styles.wiki_templates .. "\n" .. table.concat(out, "\n"))
     return frame:preprocess(result)
end
end


return Significance
return Significance

Текущая версия от 19:46, 27 апреля 2026

Документация Документация

Модуль значимости игроков. Работает как для искомой страницы, полностью её собирая, так и как чистый движок в составе других модулей.

Использование

{{#invoke:Significance|drawAll}}


Пожалуйста, добавляйте категории на страницу документации.

-- =====================================================
-- Модуль:Significance (калькулятор значимости игроков)
-- Версия 1.0
-- =====================================================
local Significance = {}

local Config = require('Module:Config')
local StatEngine = require('Module:StatEngine')
local Megarating = require('Module:Megarating')

-- ==========================================
-- РУЧНЫЕ ИСКЛЮЧЕНИЯ (Особые случаи)
-- ==========================================
local SPECIAL_CASES = {
    ["Амид"] = "[[ЦАР-КИР2026|о.случай]]",
    ["Губа"] = "[[Финал ЧТМ-2014#Дополнительное время|о.случай]]",
    ["Другой Очкан"] = "[[ДОМ-АФГ2018#Серия пенальти|о.случай]]",
    ["Рамиз"] = "[[ДОМ-АФГ2018#Серия пенальти|о.случай]]",
}

-- =====================================================
-- API ДВИЖКА (Для использования во внешних "Монстрах")
-- =====================================================

-- 1. Выдает пустую "болванку" (схему) для нового игрока
function Significance.createPlayerStruct(name)
    return {
        name = name, 
        tournaments_played = 0, top5 = 0, top10 = 0,
        matches_total = 0, goals = {total=0}, assists = {total=0}, mvp = {is_mvp=0},
        megarating = {final_goals=0, final_assists=0},
        awards = {
            golden_spheres=0, other_spheres=0, golden_shoes=0, other_shoes=0, 
            golden_assistants=0, other_assistants=0, best_goalies=0, 
            superchamps=0, titles=0, finals_played=0
        }
    }
end

-- 2. Вливает статистику из БД одного года в общую копилку игрока
function Significance.mergeStats(target, source)
    target.matches_total = (target.matches_total or 0) + (source.matches_total or 0)
    target.goals.total = (target.goals.total or 0) + (source.goals.total or 0)
    target.assists.total = (target.assists.total or 0) + (source.assists.total or 0)
    target.mvp.is_mvp = (target.mvp.is_mvp or 0) + (source.mvp.is_mvp or 0)
    
    target.megarating.final_goals = (target.megarating.final_goals or 0) + (source.megarating.final_goals or 0)
    target.megarating.final_assists = (target.megarating.final_assists or 0) + (source.megarating.final_assists or 0)
    
    if source.awards then
        target.awards.golden_spheres = target.awards.golden_spheres + (source.awards.golden_spheres or 0)
        target.awards.other_spheres = target.awards.other_spheres + (source.awards.other_spheres or 0)
        target.awards.golden_shoes = target.awards.golden_shoes + (source.awards.golden_shoes or 0)
        target.awards.other_shoes = target.awards.other_shoes + (source.awards.other_shoes or 0)
        target.awards.golden_assistants = target.awards.golden_assistants + (source.awards.golden_assistants or 0)
        target.awards.other_assistants = target.awards.other_assistants + (source.awards.other_assistants or 0)
        target.awards.best_goalies = target.awards.best_goalies + (source.awards.best_goalies or 0)
        target.awards.superchamps = target.awards.superchamps + (source.awards.superchamps or 0)
        target.awards.titles = target.awards.titles + (source.awards.titles or 0)
        target.awards.finals_played = target.awards.finals_played + (source.awards.finals_played or 0)
    end
end

-- 3. ЧИСТЫЙ КАЛЬКУЛЯТОР. Принимает заполненную структуру, возвращает уровень значимости.
function Significance.evaluatePlayer(p_stats)
    local aw = p_stats.awards
    local sum_awards = aw.other_spheres + aw.golden_shoes + aw.other_shoes + aw.best_goalies
    local any_award_exist = (sum_awards > 0) or (aw.golden_spheres > 0)

    -- 1. МАКСИМАЛЬНАЯ
    local m_c1 = (aw.golden_spheres >= 1)
    local m_c2 = (aw.titles >= 2 or aw.superchamps >= 1)
    local m_c3 = (p_stats.goals.total >= 75 or p_stats.assists.total >= 50 or p_stats.mvp.is_mvp >= 20)
    local m_c4 = (p_stats.megarating.final_goals >= 2 or p_stats.megarating.final_assists >= 3 or aw.finals_played >= 4)
    local m_c5 = (sum_awards >= 4)
    local m_c6 = (p_stats.top5 >= 2 or p_stats.top10 >= 4)
    if m_c1 and ((m_c1 and 1 or 0) + (m_c2 and 1 or 0) + (m_c3 and 1 or 0) + (m_c4 and 1 or 0) + (m_c5 and 1 or 0) + (m_c6 and 1 or 0)) >= 4 then return "Максимальная" end

    -- 2. ВЫСОКАЯ
    local h_score = (any_award_exist and 1 or 0) + ((aw.titles >= 1) and 1 or 0) + ((p_stats.goals.total >= 40 or p_stats.assists.total >= 25 or p_stats.mvp.is_mvp >= 10) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 2 or aw.finals_played >= 3) and 1 or 0) + ((p_stats.tournaments_played >= 6) and 1 or 0) + ((p_stats.top5 >= 1 or p_stats.top10 >= 3) and 1 or 0)
    if h_score >= 4 then return "Высокая" end

    -- 3. СРЕДНЯЯ
    local a_score = (any_award_exist and 1 or 0) + ((aw.titles >= 1) and 1 or 0) + ((p_stats.goals.total >= 20 or p_stats.assists.total >= 15 or p_stats.mvp.is_mvp >= 5) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 2 or aw.finals_played >= 3) and 1 or 0) + ((p_stats.tournaments_played >= 4) and 1 or 0) + ((p_stats.top5 >= 1 or p_stats.top10 >= 2) and 1 or 0)
    if a_score >= 2 then return "Средняя" end

    -- 4. НИЖЕ СРЕДНЕГО
    local main_score = ((p_stats.goals.total >= 10) and 1 or 0) + ((aw.titles >= 1 or aw.finals_played >= 2) and 1 or 0) + ((p_stats.tournaments_played >= 3) and 1 or 0) + ((p_stats.mvp.is_mvp >= 3) and 1 or 0) + ((p_stats.assists.total >= 8) and 1 or 0) + ((p_stats.megarating.final_goals >= 1 or p_stats.megarating.final_assists >= 1) and 1 or 0) + ((p_stats.top10 >= 1) and 1 or 0)
    local sub_score = ((p_stats.goals.total >= 5) and 1 or 0) + ((aw.finals_played >= 1) and 1 or 0) + ((p_stats.tournaments_played >= 2) and 1 or 0) + ((p_stats.mvp.is_mvp >= 2) and 1 or 0) + ((p_stats.assists.total >= 4) and 1 or 0)
    if main_score >= 1 or sub_score >= 2 then return "Ниже среднего" end

    -- 5. НИЗКАЯ
    local l_score = ((p_stats.goals.total >= 1) and 1 or 0) + ((aw.finals_played >= 1) and 1 or 0) + ((p_stats.tournaments_played >= 3) and 1 or 0) + ((p_stats.mvp.is_mvp >= 1) and 1 or 0) + ((p_stats.assists.total >= 2) and 1 or 0) + ((p_stats.matches_total >= 10) and 1 or 0)
    if l_score >= 1 or SPECIAL_CASES[p_stats.name] then return "Низкая" end

    return "Случайный прохожий"
end


-- =====================================================
-- ВНУТРЕННИЙ ФУНКЦИОНАЛ ДЛЯ ОТРИСОВКИ СТРАНИЦЫ
-- =====================================================

local function get_plural_players(count)
    local d10 = count % 10
    local d100 = count % 100
    if d10 == 1 and d100 ~= 11 then return count .. " игрок"
    elseif d10 >= 2 and d10 <= 4 and (d100 < 10 or d100 >= 20) then return count .. " игрока"
    else return count .. " игроков" end
end

local function cell(text, is_main, is_sub)
    local bg = ""
    if is_main then bg = Config.styles.lightgreen
    elseif is_sub then bg = Config.styles.palegoldenrod end
    return { text = tostring(text), style = Config.styles.center_nowrap .. bg }
end

local _grand_cache = nil

local function build_master_database()
    if _grand_cache then return _grand_cache end
    local GrandStats = {}
    local latest_year = Config.years[#Config.years]
    local is_latest_finished = Config.is_latest_finished

    for _, year in ipairs(Config.years) do
        local is_finished = (year ~= latest_year) or is_latest_finished
        local success, year_db = pcall(require, 'Module:Data/' .. year)
        
        if success and type(year_db) == "table" then
            local year_stats = StatEngine.Harvester.run(year_db, {need_players = true})
            for p_name, p_data in pairs(year_stats.Players) do
                if not GrandStats[p_name] then
                    -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
                    GrandStats[p_name] = Significance.createPlayerStruct(p_name)
                end
                GrandStats[p_name].tournaments_played = GrandStats[p_name].tournaments_played + 1
                -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
                Significance.mergeStats(GrandStats[p_name], p_data)
            end
            
            if is_finished then
                local mr_list = Megarating.evaluate_raw_stats(year, year_db, year_stats.Players)
                local spheres = Megarating.get_spheres_from_db(year_db)
                if #mr_list > 0 then
                    table.sort(mr_list, function(a, b) return Megarating.compare_players_public(a, b, year, spheres) end)
                    local current_rank = 1
                    for i, p in ipairs(mr_list) do
                        if i > 1 and p.total_points ~= mr_list[i-1].total_points then current_rank = i end
                        if current_rank <= 10 then
                            if GrandStats[p.name] then
                                GrandStats[p.name].top10 = GrandStats[p.name].top10 + 1
                                if current_rank <= 5 then GrandStats[p.name].top5 = GrandStats[p.name].top5 + 1 end
                            end
                        else break end
                    end
                end
            end
        end
    end
    _grand_cache = GrandStats
    return _grand_cache
end

-- (Тут идёт функция build_tier_table без изменений)
local function build_tier_table(tier, list)
    if #list == 0 then return "" end
    local html

    for _, p in ipairs(list) do
        local aw = p.awards
        local g = p.goals.total
        local a = p.assists.total
        local m = p.mvp.is_mvp
        local fg = p.megarating.final_goals
        local fa = p.megarating.final_assists
        local fp = aw.finals_played
        local tp = p.tournaments_played
        local t5 = p.top5
        local t10 = p.top10
        
        -- Группировка наград для вывода
        local all_shoes = aw.golden_shoes + aw.other_shoes
        local all_spheres = aw.golden_spheres + aw.other_spheres
        local other_spheres = aw.other_spheres
        local goalies = aw.best_goalies
        
        local sum_aw = other_spheres + all_shoes + goalies
        local sum_all_aw = all_spheres + all_shoes + goalies
        
        if tier == "Максимальная" then
            if not html then html = Config.builder.start({"Игрок", "ЗШ", "Ч/СЧ", "Г/П/MVP", "ГФ/ПФ/УФ", "Ш/Б/В", "М5/М10"}) end
            local c1 = aw.golden_spheres >= 1
            local c2 = aw.titles >= 2 or aw.superchamps >= 1
            local c3 = g >= 75 or a >= 50 or m >= 20
            local c4 = fg >= 2 or fa >= 3 or fp >= 4
            local c5 = sum_aw >= 4
            local str_awards = other_spheres .. " / " .. all_shoes .. " / " .. goalies
            local c6 = t5 >= 2 or t10 >= 4
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(aw.golden_spheres, c1), cell(aw.titles .. " / " .. aw.superchamps, c2),
                cell(g .. " / " .. a .. " / " .. m, c3), cell(fg .. " / " .. fa .. " / " .. fp, c4),
                cell(str_awards, c5), cell(t5 .. " / " .. t10, c6)
            })

        elseif tier == "Высокая" or tier == "Средняя" then
            if not html then html = Config.builder.start({"Игрок", "Ш/Б/В", "Ч", "Г/П/MVP", "ГФ/ПФ/УФ", "ФТ", "М5/М10"}) end
            local c1 = sum_all_aw >= 1
            local c2 = aw.titles >= 1
            local c3, c4, c5, c6
            if tier == "Высокая" then
                c3 = g >= 40 or a >= 25 or m >= 10
                c4 = fg >= 1 or fa >= 2 or fp >= 3
                c5 = tp >= 6
                c6 = t5 >= 1 or t10 >= 3
            else
                c3 = g >= 20 or a >= 15 or m >= 5
                c4 = fg >= 1 or fa >= 2 or fp >= 3
                c5 = tp >= 4
                c6 = t5 >= 1 or t10 >= 2
            end
            local str_awards = all_spheres .. " / " .. all_shoes .. " / " .. goalies
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(str_awards, c1), cell(aw.titles, c2),
                cell(g .. " / " .. a .. " / " .. m, c3), cell(fg .. " / " .. fa .. " / " .. fp, c4),
                cell(tp, c5), cell(t5 .. " / " .. t10, c6)
            })

        elseif tier == "Ниже среднего" then
            if not html then html = Config.builder.start({"Игрок", "Г", "Ч/Ф", "ФТ", "MVP", "П", "ГФ/ПФ", "М10"}) end
            local cg_m, cg_s = g >= 10, g >= 5
            local ccf_m, ccf_s = (aw.titles >= 1 or fp >= 2), fp >= 1
            local cft_m, cft_s = tp >= 3, tp >= 2
            local cm_m, cm_s = m >= 3, m >= 2
            local cp_m, cp_s = a >= 8, a >= 4
            local cgf_m = fg >= 1 or fa >= 1
            local ct10_m = t10 >= 1
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(g, cg_m, cg_s and not cg_m), cell(aw.titles .. " / " .. fp, ccf_m, ccf_s and not ccf_m),
                cell(tp, cft_m, cft_s and not cft_m), cell(m, cm_m, cm_s and not cm_m),
                cell(a, cp_m, cp_s and not cp_m), cell(fg .. " / " .. fa, cgf_m), cell(t10, ct10_m)
            })

        elseif tier == "Низкая" then
            if not html then html = Config.builder.start({"Игрок", "Г", "Ф", "ФТ", "MVP", "П", "М", "О.случай"}) end
            local cg = g >= 1; local cf = fp >= 1; local cft = tp >= 3
            local cmvp = m >= 1; local cp = a >= 2; local cm = p.matches_total >= 10
            local sp = SPECIAL_CASES[p.name]
            local csp = sp ~= nil
            Config.builder.row(html, {
                "'''[[" .. p.name .. "]]'''",
                cell(g, cg), cell(fp, cf), cell(tp, cft),
                cell(m, cmvp), cell(a, cp), cell(p.matches_total, cm),
                cell(sp or "", csp)
            })
        end
    end
    return html and tostring(html) or ""
end

-- (Тут идёт таблица TEXT_BLOCKS и ORDER без изменений)
local TEXT_BLOCKS = {
    ["Максимальная"] = [=[== Максимальная значимость ==

Критерии:
# Минимум один [[Золотой Шар]].
# Минимум два титула чемпиона третьего мира или одно [[суперчемпион]]ство.
# [[Голы|Забито]] не менее 75 голов, [[Передачи|отдано]] не менее 50 подтверждённых голевых передач или не менее 20 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забито хотя бы два гола в финале, отданы хотя бы три голевые передачи в финале или принято участие минимум в четырёх финалах.
# Минимум четыре любых [[Золотой Шар|Шара]] (кроме Золотого), любых [[Золотой Башмак|Башмака]] или титула [[Приз имени Эльнура|лучшего вратаря]] (все призы суммируются).
# Минимум два вхождения в пятёрку [[мегарейтинг]]а или четыре — в десятку.
Для получения максимальной значимости необходимо удовлетворять минимум четырём критериям из шести, при этом '''наличие Золотого Шара является обязательным'''.]=],

    ["Высокая"] = [=[== Высокая значимость ==
Критерии:
# Минимум один любой [[Золотой Шар|Шар]], любой [[Золотой Башмак|Башмак]] или титул [[Приз имени Эльнура|лучшего вратаря]].
# Завоёван хотя бы один титул чемпиона третьего мира.
# [[Голы|Забито]] не менее 40 голов, [[Передачи|отдано]] не менее 25 подтверждённых голевых передач или не менее 10 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забит хотя бы один гол в финале, отданы хотя бы две голевые передачи в финале или принято участие минимум в трёх финалах.
# Участие минимум в шести [[Список участий в финальных турнирах|финальных турнирах ЧТМ]].
# Минимум одно вхождение в пятёрку [[мегарейтинг]]а или три — в десятку.
Для получения высокой значимости необходимо удовлетворять минимум четырём критериям из шести.]=],

    ["Средняя"] = [=[== Средняя значимость ==
Критерии:
# Минимум один любой [[Золотой Шар|Шар]], любой [[Золотой Башмак|Башмак]] или титул [[Приз имени Эльнура|лучшего вратаря]].
# Завоёван хотя бы один титул чемпиона третьего мира.
# [[Голы|Забито]] не менее 20 голов, [[Передачи|отдано]] не менее 15 подтверждённых голевых передач или не менее 5 признаний [[Список лучших игроков всех матчей ЧТМ|игроком матча]].
# Забит хотя бы один гол в финале, отданы хотя бы две голевые передачи в финале или принято участие минимум в трёх финалах.
# Участие минимум в четырёх [[Список участий в финальных турнирах|финальных турнирах ЧТМ]].
# Минимум одно вхождение в пятёрку [[мегарейтинг]]а или два — в десятку.
Для получения средней значимости необходимо удовлетворять минимум минимум двум критериям из шести.]=],

    ["Ниже среднего"] = [=[== Ниже среднего ==
Критерии:
# [[Голы|Забито]] не менее 10 (основной показатель) или 5 (дополнительный) голов.
# Завоёван хотя бы один титул чемпиона третьего мира или участие минимум в двух (основной) или одном (дополнительный) финале.
# Участие минимум в трёх (основной) или двух (дополнительный) финальных турнирах ЧТМ.
# Признание [[Список лучших игроков всех матчей ЧТМ|игроком матча]] не менее трёх (основной показатель) или двух (дополнительный) раз.
# [[Передачи|Отдано]] не менее 8 (основной показатель) или 4 (дополнительный) подтверждённых голевых передач.
# Забит хотя бы один гол или отдана хотя бы одна голевая передача в финале (основной показатель).
# Минимум одно вхождение в десятку [[мегарейтинг]]а.
Необходимо соответствовать хотя бы одному из критериев в первом случае и хотя бы двум во втором.]=],

    ["Низкая"] = [=[== Низкая ==
Критерии:
# [[Голы|Забит]] хотя бы один гол.
# Участие минимум в одном финале.
# Участие минимум в трёх финальных турнирах ЧТМ.
# Признание [[Список лучших игроков всех матчей ЧТМ|игроком матча]] хотя бы один раз.
# [[Передачи|Отданы]] хотя бы две подтверждённые голевые передачи.
# [[Матчи|Сыграно]] не менее 10 подтверждённых матчей.
Необходимо соответствовать хотя бы одному из критериев. В указанных дополнительно особых случаях возможно присвоение этого уровня случайным игрокам, хоть чем-то запомнившимся.]=],

    ["Случайный прохожий"] = [=[== Случайный прохожий ==
Случайные люди, приходившие играть один-два раза в проходных матчах и абсолютно ничем не запомнившиеся.]=]
}

local ORDER = {"Максимальная", "Высокая", "Средняя", "Ниже среднего", "Низкая", "Случайный прохожий"}

function Significance.drawAll(frame)
    local db = build_master_database()
    local bins = { ["Максимальная"]={}, ["Высокая"]={}, ["Средняя"]={}, ["Ниже среднего"]={}, ["Низкая"]={}, ["Случайный прохожий"]={} }

    for _, p_stats in pairs(db) do
        -- ИСПОЛЬЗУЕМ СОБСТВЕННЫЙ API
        local level = Significance.evaluatePlayer(p_stats)
        table.insert(bins[level], p_stats)
    end
    
    for _, list in pairs(bins) do table.sort(list, function(a, b) return a.name < b.name end) end

    local out = {}
    for _, tier in ipairs(ORDER) do
        local list = bins[tier]
        table.insert(out, TEXT_BLOCKS[tier])
        
        if tier == "Случайный прохожий" then
            table.insert(out, "\n'''Точное число игроков неизвестно:'''")
            local links = {}
            for _, p in ipairs(list) do table.insert(links, "[[" .. p.name .. "]]") end
            table.insert(out, table.concat(links, ", ") .. ".")
        else
            table.insert(out, "\n'''" .. get_plural_players(#list) .. ":'''")
            table.insert(out, build_tier_table(tier, list))
        end
        table.insert(out, "")
    end

    return frame:preprocess(Config.styles.wiki_templates .. "\n" .. table.concat(out, "\n"))
end

return Significance