Przejdź do zawartości

Moduł:H2H

Z Encyklopedia Poznanskiego Sportu

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:H2H/opis

local p = {}

-- =========================================================
-- Moduł:H2H
--
-- Historia bezpośrednich spotkań dwóch drużyn
--
-- Funkcje:
--   • bilans spotkań
--   • suma punktów obu drużyn
--   • wszystkie mecze
--   • najlepsi strzelcy rywalizacji
--   • trenerzy prowadzący zespół przeciwko rywalowi
--   • rekordy meczowe dom / wyjazd
--   • rekordy indywidualne dom / wyjazd
--   • serie zwycięstw / porażek
--   • porównanie wyniku poszczególnych kwart
--   • obsługa do 3 dogrywek
--
-- Identyfikacja drużyn odbywa się przez:
--   nazwa_statystyki1
--   nazwa_statystyki2
--
-- Dzięki temu można zachować jedną nazwę drużyny
-- niezależnie od późniejszych zmian sponsora.
-- =========================================================


function p.main(frame)

    -- =====================================================
    -- PARAMETRY
    -- =====================================================

    local team1 = mw.text.trim(frame.args.team1 or "")
    local team2 = mw.text.trim(frame.args.team2 or "")

    if team1 == "" then
        return "'''Błąd:''' nie podano parametru '''team1'''."
    end

    if team2 == "" then
        return "'''Błąd:''' nie podano parametru '''team2'''."
    end


    -- =====================================================
    -- BEZPIECZNE SQL
    -- =====================================================

    local team1SQL =
        mw.ustring.gsub(team1, "'", "''")

    local team2SQL =
        mw.ustring.gsub(team2, "'", "''")


    -- =====================================================
    -- FUNKCJE POMOCNICZE
    -- =====================================================

    local function liczba(value)

        if value == nil or value == "" then
            return 0
        end

        value = tostring(value)

        value =
            mw.ustring.gsub(value, "%s+", "")

        return tonumber(value) or 0

    end


    local function minutyNaSekundy(value)

        if value == nil or value == "" then
            return 0
        end

        local tekst = tostring(value)

        local min, sek =
            tekst:match("^(%d+):(%d+)$")

        if min and sek then
            return tonumber(min) * 60 + tonumber(sek)
        end

        return tonumber(tekst) or 0

    end


    local function sekundyNaMinuty(sek)

        if not sek then
            return "0:00"
        end

        local min =
            math.floor(sek / 60)

        local s =
            sek % 60

        return string.format(
            "%d:%02d",
            min,
            s
        )

    end


    local function wynikMeczu(row)

        local g1 =
            tonumber(row.gole1 or "")

        local g2 =
            tonumber(row.gole2 or "")

        if g1 and g2 then
            return g1, g2
        end

        local wynik =
            row.wynik or ""

        local a, b =
            wynik:match(
                "(%d+)%s*:%s*(%d+)"
            )

        if a and b then
            return tonumber(a), tonumber(b)
        end

        return nil, nil

    end


    local function miejsceMeczu(row)

        local d1 =
            row.nazwa_statystyki1 or ""

        local d2 =
            row.nazwa_statystyki2 or ""

        if d1 == team1 then
            return "dom"
        end

        if d2 == team1 then
            return "wyjazd"
        end

        return nil

    end


    local function przeciwnik(row)

        local d1 =
            row.nazwa_statystyki1 or ""

        local d2 =
            row.nazwa_statystyki2 or ""

        if d1 == team1 then
            return d2
        end

        if d2 == team1 then
            return d1
        end

        return ""

    end


    local function linkMeczu(row)

        local strona =
            row.strona_meczu or ""

        local d1 =
            row.druzyna1 or ""

        local d2 =
            row.druzyna2 or ""

        local tekst =
            d1 .. " – " .. d2

        if strona ~= "" then

            return "[[" ..
                strona ..
                "|" ..
                tekst ..
                "]]"

        end

        return tekst

    end


    local function bezpiecznyLinkOsoby(osoba)

        if not osoba or osoba == "" then
            return ""
        end

        return "[[" ..
            osoba ..
            "|" ..
            osoba ..
            "]]"

    end


    local function wartoscNajwieksza(lista)

        if not lista or #lista == 0 then
            return nil
        end

        local max = lista[1].wartosc

        for _, item in ipairs(lista) do

            if item.wartosc > max then
                max = item.wartosc
            end

        end

        return max

    end


    local function dodajRekord(lista, item)

        if #lista == 0 then

            table.insert(
                lista,
                item
            )

            return

        end

        local max =
            lista[1].wartosc

        if item.wartosc > max then

            lista = {}

        end

    end


    -- =====================================================
    -- POBRANIE MECZÓW H2H
    -- =====================================================

    local fieldsMecze = table.concat({

        "M.id=mecz",
        "M.data=data",
        "M.sezon=sezon",
        "M.rozgrywki=rozgrywki",
        "M.kolejka=kolejka",

        "M.druzyna1=druzyna1",
        "M.druzyna2=druzyna2",

        "M.nazwa_statystyki1=nazwa_statystyki1",
        "M.nazwa_statystyki2=nazwa_statystyki2",

        "M.wynik=wynik",
        "M.gole1=gole1",
        "M.gole2=gole2",

        "M.hala=hala",
        "M.widzowie=widzowie",
        "M.sedziowie=sedziowie",
        "M.strona_meczu=strona_meczu",

        "M.kwarta1=kwarta1",
        "M.kwarta2=kwarta2",
        "M.kwarta3=kwarta3",
        "M.kwarta4=kwarta4",

        "M.dogrywka1=dogrywka1",
        "M.dogrywka2=dogrywka2",
        "M.dogrywka3=dogrywka3"

    }, ",")


    local argsMecze = {

        where =
            "(M.nazwa_statystyki1='" ..
            team1SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team2SQL ..
            "')" ..
            " OR " ..
            "(M.nazwa_statystyki1='" ..
            team2SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team1SQL ..
            "')",

        orderBy =
            "M.data ASC",

        limit = 5000

    }


    local mecze =
        mw.ext.cargo.query(
            "Mecze=M",
            fieldsMecze,
            argsMecze
        )


    if not mecze or #mecze == 0 then

        return
            "'''Brak spotkań''' pomiędzy " ..
            "'''"
            .. team1 ..
            "''' i '''"
            .. team2 ..
            "'''."

    end


    -- =====================================================
    -- BILANS
    -- =====================================================

    local bilans = {

        mecze = 0,

        wygrane1 = 0,
        wygrane2 = 0,

        punkty1 = 0,
        punkty2 = 0,

        remisy = 0

    }


    -- =====================================================
    -- REKORDY MECZOWE
    -- =====================================================

    local rekordyMeczowe = {

        zwyciestwo = {
            dom = {},
            wyjazd = {}
        },

        porazka = {
            dom = {},
            wyjazd = {}
        }

    }


    -- =====================================================
    -- SERIE
    -- =====================================================

    local serie = {

        wszystkie = {
            W = 0,
            P = 0
        },

        dom = {
            W = 0,
            P = 0
        },

        wyjazd = {
            W = 0,
            P = 0
        }

    }


    local aktualna = {

        wszystkie = {
            W = 0,
            P = 0
        },

        dom = {
            W = 0,
            P = 0
        },

        wyjazd = {
            W = 0,
            P = 0
        }

    }


    -- =====================================================
    -- PORÓWNANIE KWART
    -- =====================================================

    local kwart = {

        [1] = {
            wygrane = 0,
            przegrane = 0,
            remis = 0
        },

        [2] = {
            wygrane = 0,
            przegrane = 0,
            remis = 0
        },

        [3] = {
            wygrane = 0,
            przegrane = 0,
            remis = 0
        },

        [4] = {
            wygrane = 0,
            przegrane = 0,
            remis = 0
        }

    }


    -- =====================================================
    -- PRZETWARZANIE MECZÓW
    -- =====================================================

    for _, row in ipairs(mecze) do

        local g1, g2 =
            wynikMeczu(row)

        if g1 and g2 then

            bilans.mecze =
                bilans.mecze + 1

            local miejsce =
                miejsceMeczu(row)

            local zdobyte
            local stracone

            if miejsce == "dom" then

                zdobyte = g1
                stracone = g2

            else

                zdobyte = g2
                stracone = g1

            end


            bilans.punkty1 =
                bilans.punkty1 + zdobyte

            bilans.punkty2 =
                bilans.punkty2 + stracone


            local roznica =
                zdobyte - stracone


            local item = {

                mecz =
                    row.mecz or "",

                data =
                    row.data or "",

                tekst =
                    linkMeczu(row),

                wynik =
                    tostring(g1) ..
                    ":" ..
                    tostring(g2),

                roznica =
                    roznica,

                miejsce =
                    miejsce,

                zdobyte =
                    zdobyte,

                stracone =
                    stracone

            }


            -- =============================================
            -- WYNIK
            -- =============================================

            local rezultat

            if roznica > 0 then

                rezultat = "W"

            elseif roznica < 0 then

                rezultat = "P"

            else

                rezultat = "R"

            end


            if rezultat == "W" then

                bilans.wygrane1 =
                    bilans.wygrane1 + 1

            elseif rezultat == "P" then

                bilans.wygrane2 =
                    bilans.wygrane2 + 1

            else

                bilans.remisy =
                    bilans.remisy + 1

            end


            -- =============================================
            -- REKORDY ZWYCIĘSTW
            -- =============================================

            if rezultat == "W" then

                local lista =
                    rekordyMeczowe.zwyciestwo[miejsce]

                if #lista == 0 or
                    roznica > lista[1].wartosc then

                    rekordyMeczowe.zwyciestwo[miejsce] = {
                        {
                            wartosc = roznica,
                            item = item
                        }
                    }

                elseif roznica ==
                    lista[1].wartosc then

                    table.insert(
                        lista,
                        {
                            wartosc = roznica,
                            item = item
                        }
                    )

                end

            end


            -- =============================================
            -- REKORDY PORAŻEK
            -- =============================================

            if rezultat == "P" then

                local przegrana =
                    math.abs(roznica)

                local lista =
                    rekordyMeczowe.porazka[miejsce]

                if #lista == 0 or
                    przegrana > lista[1].wartosc then

                    rekordyMeczowe.porazka[miejsce] = {
                        {
                            wartosc = przegrana,
                            item = item
                        }
                    }

                elseif przegrana ==
                    lista[1].wartosc then

                    table.insert(
                        lista,
                        {
                            wartosc = przegrana,
                            item = item
                        }
                    )

                end

            end


            -- =============================================
            -- SERIE OGÓŁEM
            -- =============================================

            if rezultat == "W" then

                aktualna.wszystkie.W =
                    aktualna.wszystkie.W + 1

                aktualna.wszystkie.P = 0

                if aktualna.wszystkie.W >
                    serie.wszystkie.W then

                    serie.wszystkie.W =
                        aktualna.wszystkie.W

                end

            elseif rezultat == "P" then

                aktualna.wszystkie.P =
                    aktualna.wszystkie.P + 1

                aktualna.wszystkie.W = 0

                if aktualna.wszystkie.P >
                    serie.wszystkie.P then

                    serie.wszystkie.P =
                        aktualna.wszystkie.P

                end

            else

                aktualna.wszystkie.W = 0
                aktualna.wszystkie.P = 0

            end


            -- =============================================
            -- SERIE DOM / WYJAZD
            -- =============================================

            local seria =
                aktualna[miejsce]

            local rekordSerii =
                serie[miejsce]


            if rezultat == "W" then

                seria.W =
                    seria.W + 1

                seria.P = 0

                if seria.W >
                    rekordSerii.W then

                    rekordSerii.W =
                        seria.W

                end

            elseif rezultat == "P" then

                seria.P =
                    seria.P + 1

                seria.W = 0

                if seria.P >
                    rekordSerii.P then

                    rekordSerii.P =
                        seria.P

                end

            else

                seria.W = 0
                seria.P = 0

            end


            -- =============================================
            -- KWARTY
            --
            -- kwart1-4 przechowujemy jako String,
            -- dlatego parsujemy pierwszą liczbę.
            -- =============================================

            local kwarty = {

                row.kwarta1,
                row.kwarta2,
                row.kwarta3,
                row.kwarta4

            }


            for nr = 1, 4 do

                local q =
                    kwarty[nr] or ""

                local q1, q2 =
                    q:match(
                        "^(%d+)%s*[:%-]%s*(%d+)"
                    )

                if q1 and q2 then

                    q1 =
                        tonumber(q1)

                    q2 =
                        tonumber(q2)

                    local nasz
                    local rywal

                    if miejsce == "dom" then

                        nasz = q1
                        rywal = q2

                    else

                        nasz = q2
                        rywal = q1

                    end


                    if nasz > rywal then

                        kwart[nr].wygrane =
                            kwart[nr].wygrane + 1

                    elseif nasz < rywal then

                        kwart[nr].przegrane =
                            kwart[nr].przegrane + 1

                    else

                        kwart[nr].remis =
                            kwart[nr].remis + 1

                    end

                end

            end

        end

    end


    -- =====================================================
    -- POBRANIE STATYSTYK ZAWODNIKÓW
    -- =====================================================

    local fieldsZawodnicy = table.concat({

        "U.zawodnik=zawodnik",
        "U.druzyna=druzyna_zawodnika",
        "U.gol=gol",
        "U.minuty=minuty",
        "U.minuty_format=minuty_format",
        "U.asysta=asysta",
        "U.zbiorka=zbiorka",
        "U.eval=eval",
        "U.plusminus=plusminus",

        "M.id=mecz",
        "M.data=data",
        "M.druzyna1=druzyna1",
        "M.druzyna2=druzyna2",

        "M.nazwa_statystyki1=nazwa_statystyki1",
        "M.nazwa_statystyki2=nazwa_statystyki2",

        "M.wynik=wynik",
        "M.strona_meczu=strona_meczu"

    }, ",")


    local argsZawodnicy = {

        join =
            "U.mecz=M.id",

        where =
            "(" ..
            "(M.nazwa_statystyki1='" ..
            team1SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team2SQL ..
            "')" ..
            " OR " ..
            "(M.nazwa_statystyki1='" ..
            team2SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team1SQL ..
            "')" ..
            ")" ..
            " AND U.minuty > 0",

        orderBy =
            "M.data ASC",

        limit = 10000

    }


    local zawodnicy =
        mw.ext.cargo.query(
            "UdzialZawodnika=U,Mecze=M",
            fieldsZawodnicy,
            argsZawodnicy
        )


    -- =====================================================
    -- REKORDY INDYWIDUALNE
    -- =====================================================

    local rekordy = {

        punkty = {
            dom = {},
            wyjazd = {}
        },

        minuty = {
            dom = {},
            wyjazd = {}
        },

        asysty = {
            dom = {},
            wyjazd = {}
        },

        zbiorki = {
            dom = {},
            wyjazd = {}
        },

        eval = {
            dom = {},
            wyjazd = {}
        },

        plusminus = {
            dom = {},
            wyjazd = {}
        }

    }


    local function dodajRekordIndywidualny(
        tabela,
        miejsce,
        wartosc,
        item
    )

        local lista =
            tabela[miejsce]

        if #lista == 0 then

            item.wartosc =
                wartosc

            table.insert(
                lista,
                item
            )

            return

        end


        local obecna =
            lista[1].wartosc


        if wartosc > obecna then

            item.wartosc =
                wartosc

            tabela[miejsce] = {
                item
            }

        elseif wartosc == obecna then

            item.wartosc =
                wartosc

            table.insert(
                lista,
                item
            )

        end

    end


    if zawodnicy then

        for _, row in ipairs(zawodnicy) do

            local miejsce =
                miejsceMeczu(row)

            if miejsce then

                local punkty =
                    liczba(row.gol)

                local minuty =
                    minutyNaSekundy(
                        row.minuty_format
                    )

                local asysty =
                    liczba(row.asysta)

                local zbiorki =
                    liczba(row.zbiorka)

                local eval =
                    liczba(row.eval)

                local plusminus =
                    liczba(row.plusminus)


                local item = {

                    zawodnik =
                        row.zawodnik or "",

                    mecz =
                        row.mecz or "",

                    data =
                        row.data or "",

                    miejsce =
                        miejsce,

                    punkty =
                        punkty,

                    minuty =
                        minuty,

                    minuty_format =
                        row.minuty_format or "",

                    asysty =
                        asysty,

                    zbiorki =
                        zbiorki,

                    eval =
                        eval,

                    plusminus =
                        plusminus,

                    tekst =
                        linkMeczu(row),

                    wynik =
                        row.wynik or ""

                }


                dodajRekordIndywidualny(
                    rekordy.punkty,
                    miejsce,
                    punkty,
                    item
                )


                dodajRekordIndywidualny(
                    rekordy.minuty,
                    miejsce,
                    minuty,
                    item
                )


                dodajRekordIndywidualny(
                    rekordy.asysty,
                    miejsce,
                    asysty,
                    item
                )


                dodajRekordIndywidualny(
                    rekordy.zbiorki,
                    miejsce,
                    zbiorki,
                    item
                )


                dodajRekordIndywidualny(
                    rekordy.eval,
                    miejsce,
                    eval,
                    item
                )


                dodajRekordIndywidualny(
                    rekordy.plusminus,
                    miejsce,
                    plusminus,
                    item
                )

            end

        end

    end


    -- =====================================================
    -- TRENERZY
    -- =====================================================

    local fieldsTrenerzy = table.concat({

        "S.osoba=osoba",
        "S.druzyna=druzyna",
        "S.rola=rola",
        "S.mecz=mecz"

    }, ",")


    local argsTrenerzy = {

        join =
            "S.mecz=M.id",

        where =
            "(" ..
            "(M.nazwa_statystyki1='" ..
            team1SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team2SQL ..
            "')" ..
            " OR " ..
            "(M.nazwa_statystyki1='" ..
            team2SQL ..
            "' AND M.nazwa_statystyki2='" ..
            team1SQL ..
            "')" ..
            ")" ..
            " AND S.druzyna='" ..
            team1SQL ..
            "'" ..
            " AND S.rola='Trener'",

        orderBy =
            "M.data ASC",

        limit = 5000

    }


    local trenerzy =
        mw.ext.cargo.query(
            "SztabMeczu=S,Mecze=M",
            fieldsTrenerzy,
            argsTrenerzy
        )


    local listaTrenerow = {}

    local trenerWidoczny = {}

    if trenerzy then

        for _, row in ipairs(trenerzy) do

            local osoba =
                row.osoba or ""

            if osoba ~= "" and
                not trenerWidoczny[osoba] then

                trenerWidoczny[osoba] = true

                table.insert(
                    listaTrenerow,
                    osoba
                )

            end

        end

    end


    -- =====================================================
    -- FORMAT REKORDÓW MECZOWYCH
    -- =====================================================

    local function tekstRekordowMeczowych(lista)

        if not lista or #lista == 0 then
            return "—"
        end

        local wynik = {}

        for _, rekord in ipairs(lista) do

            local item =
                rekord.item

            table.insert(
                wynik,
                item.tekst ..
                " (" ..
                item.wynik ..
                ", +" ..
                tostring(
                    item.roznica
                ) ..
                ")"
            )

        end

        return table.concat(
            wynik,
            "<br>"
        )

    end


    -- =====================================================
    -- FORMAT REKORDÓW INDYWIDUALNYCH
    -- =====================================================

    local function tekstRekordowIndywidualnych(
        lista,
        typ
    )

        if not lista or #lista == 0 then
            return "—"
        end

        local wynik = {}

        for _, item in ipairs(lista) do

            local wartosc = ""

            if typ == "punkty" then

                wartosc =
                    tostring(item.punkty) ..
                    " pkt"

            elseif typ == "minuty" then

                wartosc =
                    sekundyNaMinuty(
                        item.minuty
                    ) ..
                    " min"

            elseif typ == "asysty" then

                wartosc =
                    tostring(item.asysty) ..
                    " as."

            elseif typ == "zbiorki" then

                wartosc =
                    tostring(item.zbiorki) ..
                    " zb."

            elseif typ == "eval" then

                wartosc =
                    tostring(item.eval) ..
                    " EVAL"

            elseif typ == "plusminus" then

                if item.plusminus >= 0 then

                    wartosc =
                        "+" ..
                        tostring(
                            item.plusminus
                        )

                else

                    wartosc =
                        tostring(
                            item.plusminus
                        )

                end

                wartosc =
                    wartosc ..
                    " +/-"

            end


            table.insert(
                wynik,

                bezpiecznyLinkOsoby(
                    item.zawodnik
                ) ..
                " — " ..
                wartosc ..
                "<br>" ..
                item.tekst ..
                " (" ..
                item.wynik ..
                ")"
            )

        end

        return table.concat(
            wynik,
            "<br>"
        )

    end


    -- =====================================================
    -- GENEROWANIE WYNIKU
    -- =====================================================

    local wynik = {}


    table.insert(
        wynik,
        "== Bilans bezpośrednich spotkań =="
    )

    table.insert(
        wynik,
        ""
    )


    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )

    table.insert(
        wynik,
        "! Drużyna !! Mecze !! Wygrane !! Porażki !! Remisy !! Punkty zdobyte !! Punkty stracone"
    )

    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! " ..
        team1 ..
        " !! " ..
        bilans.mecze ..
        " !! " ..
        bilans.wygrane1 ..
        " !! " ..
        bilans.wygrane2 ..
        " !! " ..
        bilans.remisy ..
        " !! " ..
        bilans.punkty1 ..
        " !! " ..
        bilans.punkty2
    )

    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! " ..
        team2 ..
        " !! " ..
        bilans.mecze ..
        " !! " ..
        bilans.wygrane2 ..
        " !! " ..
        bilans.wygrane1 ..
        " !! " ..
        bilans.remisy ..
        " !! " ..
        bilans.punkty2 ..
        " !! " ..
        bilans.punkty1
    )

    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- TRENERZY
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Trenerzy " ..
        team1 ..
        " w rywalizacji z " ..
        team2 ..
        " =="
    )

    table.insert(
        wynik,
        ""
    )


    if #listaTrenerow == 0 then

        table.insert(
            wynik,
            "Brak danych."
        )

    else

        local trenerTekst = {}

        for _, trener in ipairs(listaTrenerow) do

            table.insert(
                trenerTekst,
                "[[" ..
                trener ..
                "]]"
            )

        end

        table.insert(
            wynik,
            table.concat(
                trenerTekst,
                ", "
            )
        )

    end


    -- =====================================================
    -- HISTORIA SPOTKAŃ
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Historia spotkań =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%;"'
    )

    table.insert(
        wynik,
        "! Data !! Sezon !! Gospodarz !! Gość !! Wynik !! Hala"
    )


    for _, row in ipairs(mecze) do

        table.insert(
            wynik,
            "|-"
        )

        table.insert(
            wynik,
            "| " ..
            (row.data or "") ..
            " || " ..
            (row.sezon or "") ..
            " || " ..
            (row.druzyna1 or "") ..
            " || " ..
            (row.druzyna2 or "") ..
            " || " ..
            (row.wynik or "") ..
            " || " ..
            (row.hala or "")
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- NAJLEPSI STRZELCY
    -- =====================================================

    local strzelcy = {}

    if zawodnicy then

        for _, row in ipairs(zawodnicy) do

            local zawodnik =
                row.zawodnik or ""

            if zawodnik ~= "" then

                if not strzelcy[zawodnik] then

                    strzelcy[zawodnik] = 0

                end

                strzelcy[zawodnik] =
                    strzelcy[zawodnik] +
                    liczba(row.gol)

            end

        end

    end


    local listaStrzelcow = {}

    for zawodnik, punkty in pairs(strzelcy) do

        table.insert(
            listaStrzelcow,
            {
                zawodnik = zawodnik,
                punkty = punkty
            }
        )

    end


    table.sort(
        listaStrzelcow,
        function(a, b)

            if a.punkty == b.punkty then

                return a.zawodnik <
                    b.zawodnik

            end

            return a.punkty >
                b.punkty

        end
    )


    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Najlepsi strzelcy rywalizacji =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%;"'
    )

    table.insert(
        wynik,
        "! Zawodnik !! Drużyna !! Punkty"
    )


    for _, item in ipairs(listaStrzelcow) do

        local druzynaZawodnika = ""

        if zawodnicy then

            for _, row in ipairs(zawodnicy) do

                if row.zawodnik ==
                    item.zawodnik then

                    druzynaZawodnika =
                        row.druzyna_zawodnika or ""

                    break

                end

            end

        end


        table.insert(
            wynik,
            "|-"
        )

        table.insert(
            wynik,
            "| [[" ..
            item.zawodnik ..
            "]] || " ..
            druzynaZawodnika ..
            " || '''" ..
            tostring(item.punkty) ..
            "'''"
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- REKORDY MECZOWE
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Rekordy meczowe =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )

    table.insert(
        wynik,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )

    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! 🏆 Najwyższe zwycięstwo"
    )

    table.insert(
        wynik,
        "| " ..
        tekstRekordowMeczowych(
            rekordyMeczowe.zwyciestwo.dom
        )
    )

    table.insert(
        wynik,
        "| " ..
        tekstRekordowMeczowych(
            rekordyMeczowe.zwyciestwo.wyjazd
        )
    )


    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! ❌ Najwyższa porażka"
    )

    table.insert(
        wynik,
        "| " ..
        tekstRekordowMeczowych(
            rekordyMeczowe.porazka.dom
        )
    )

    table.insert(
        wynik,
        "| " ..
        tekstRekordowMeczowych(
            rekordyMeczowe.porazka.wyjazd
        )
    )

    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- REKORDY INDYWIDUALNE
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Rekordy indywidualne =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )

    table.insert(
        wynik,
        "! Rekord !! 🏠 Dom !! ✈️ Wyjazd"
    )


    local rekordyLista = {

        {
            nazwa = "🏀 Najwięcej punktów",
            tabela = rekordy.punkty,
            typ = "punkty"
        },

        {
            nazwa = "⏱️ Najwięcej minut",
            tabela = rekordy.minuty,
            typ = "minuty"
        },

        {
            nazwa = "🎯 Najwięcej asyst",
            tabela = rekordy.asysty,
            typ = "asysty"
        },

        {
            nazwa = "🏀 Najwięcej zbiórek",
            tabela = rekordy.zbiorki,
            typ = "zbiorki"
        },

        {
            nazwa = "⭐ Najwyższy EVAL",
            tabela = rekordy.eval,
            typ = "eval"
        },

        {
            nazwa = "➕ Najwyższy +/-",
            tabela = rekordy.plusminus,
            typ = "plusminus"
        }

    }


    for _, rekord in ipairs(rekordyLista) do

        table.insert(
            wynik,
            "|-"
        )

        table.insert(
            wynik,
            "! " ..
            rekord.nazwa
        )

        table.insert(
            wynik,
            "| " ..
            tekstRekordowIndywidualnych(
                rekord.tabela.dom,
                rekord.typ
            )
        )

        table.insert(
            wynik,
            "| " ..
            tekstRekordowIndywidualnych(
                rekord.tabela.wyjazd,
                rekord.typ
            )
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- SERIE
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Serie zwycięstw i porażek =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )

    table.insert(
        wynik,
        "! Seria !! Wszystkie mecze !! 🏠 Dom !! ✈️ Wyjazd"
    )

    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! 🔥 Najdłuższa seria zwycięstw"
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.wszystkie.W
        )
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.dom.W
        )
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.wyjazd.W
        )
    )


    table.insert(
        wynik,
        "|-"
    )

    table.insert(
        wynik,
        "! 📉 Najdłuższa seria porażek"
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.wszystkie.P
        )
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.dom.P
        )
    )

    table.insert(
        wynik,
        "| " ..
        tostring(
            serie.wyjazd.P
        )
    )

    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- KWARTY
    -- =====================================================

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        "== Wynik meczu a wynik poszczególnych kwart =="
    )

    table.insert(
        wynik,
        ""
    )

    table.insert(
        wynik,
        '{| class="wikitable" style="width:100%; text-align:center;"'
    )

    table.insert(
        wynik,
        "! Kwarta !! Wygrana kwarta !! Przegrana kwarta !! Remis kwarty"
    )


    for nr = 1, 4 do

        table.insert(
            wynik,
            "|-"
        )

        table.insert(
            wynik,
            "! " ..
            tostring(nr) ..
            "."

        )

        table.insert(
            wynik,
            "| " ..
            tostring(
                kwart[nr].wygrane
            )
        )

        table.insert(
            wynik,
            "| " ..
            tostring(
                kwart[nr].przegrane
            )
        )

        table.insert(
            wynik,
            "| " ..
            tostring(
                kwart[nr].remis
            )
        )

    end


    table.insert(
        wynik,
        "|}"
    )


    -- =====================================================
    -- DOGRYWKI
    -- =====================================================

    local liczbaDogrywek = 0

    for _, row in ipairs(mecze) do

        if row.dogrywka1 and
            row.dogrywka1 ~= "" then

            liczbaDogrywek =
                liczbaDogrywek + 1

        end

        if row.dogrywka2 and
            row.dogrywka2 ~= "" then

            liczbaDogrywek =
                liczbaDogrywek + 1

        end

        if row.dogrywka3 and
            row.dogrywka3 ~= "" then

            liczbaDogrywek =
                liczbaDogrywek + 1

        end

    end


    if liczbaDogrywek > 0 then

        table.insert(
            wynik,
            ""
        )

        table.insert(
            wynik,
            "== Mecze z dogrywkami =="
        )

        table.insert(
            wynik,
            ""
        )

        table.insert(
            wynik,
            '{| class="wikitable" style="width:100%;"'
        )

        table.insert(
            wynik,
            "! Data !! Mecz !! Wynik !! Dogrywki"
        )


        for _, row in ipairs(mecze) do

            local dogrywki = {}

            if row.dogrywka1 and
                row.dogrywka1 ~= "" then

                table.insert(
                    dogrywki,
                    row.dogrywka1
                )

            end

            if row.dogrywka2 and
                row.dogrywka2 ~= "" then

                table.insert(
                    dogrywki,
                    row.dogrywka2
                )

            end

            if row.dogrywka3 and
                row.dogrywka3 ~= "" then

                table.insert(
                    dogrywki,
                    row.dogrywka3
                )

            end


            if #dogrywki > 0 then

                table.insert(
                    wynik,
                    "|-"
                )

                table.insert(
                    wynik,
                    "| " ..
                    (row.data or "") ..
                    " || " ..
                    linkMeczu(row) ..
                    " || " ..
                    (row.wynik or "") ..
                    " || " ..
                    table.concat(
                        dogrywki,
                        " | "
                    )
                )

            end

        end


        table.insert(
            wynik,
            "|}"
        )

    end


    -- =====================================================
    -- KONIEC
    -- =====================================================

    return table.concat(
        wynik,
        "\n"
    )

end


return p