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

Материал из Space Station 14 Вики
Нет описания правки
Нет описания правки
Метка: ручная отмена
 
(не показаны 4 промежуточные версии этого же участника)
Строка 107: Строка 107:


-- returns recipes which id is matched by pattern
-- returns recipes which id is matched by pattern
function getrecipesbyname(frame, tabl, str, ignore) -- should not be inviked
function getrecipesbyname(frame, tabl, str) -- should not be inviked
     local out = {}
     local out = {}
    local ign = ""
    if ignore ~= nil then ign = ignore end
     for type, recipes in pairs(tabl) do
     for type, recipes in pairs(tabl) do
         out[type] = {}
         out[type] = {}
         for recipeId, recipe in pairs(recipes) do
         for recipeId, recipe in pairs(recipes) do
             if string.match(recipeId, str) and not string.match(recipeId, ign) then
             if string.match(recipeId, str) then
                 table.insert(out[type], recipe)
                 table.insert(out[type], recipe)
             end
             end
Строка 123: Строка 121:


-- same as above, but returns recipes that *does not* match given pattern
-- same as above, but returns recipes that *does not* match given pattern
function getotherrecipes(frame, tabl, str, ignore) -- should not be invoked
function getotherrecipes(frame, tabl, str) -- should not be invoked
     local out = {}
     local out = {}
    local ign = ""
    if ignore ~= nil then ign = ignore end
     for type, recipes in pairs(tabl) do
     for type, recipes in pairs(tabl) do
         if not table.containsk(out, type) then
         if not table.containsk(out, type) then
Строка 132: Строка 128:
         end
         end
         for recipeId, recipe in pairs(recipes) do
         for recipeId, recipe in pairs(recipes) do
             if not string.match(recipeId, str) and not string.match(recipeId, ign) then
             if not string.match(recipeId, str) then
                 if not table.containsv(out[type], recipe) then
                 if not table.containsv(out[type], recipe) then
                     table.insert(out[type], recipe)
                     table.insert(out[type], recipe)
Строка 453: Строка 449:
     local out = ""
     local out = ""
     local tablo = p.meals
     local tablo = p.meals
    local ignore = frame.args["ignore"]
     for _, patt in pairs(frame.args) do
     for _, patt in pairs(frame.args) do
         local ids = getrecipesbyname(frame, tablo, patt, ignore)
         local ids = getrecipesbyname(frame, tablo, patt)
         out = out .. p.buildrecipeboxuniversal(frame, ids)
         out = out .. p.buildrecipeboxuniversal(frame, ids)
     end
     end
Строка 465: Строка 460:
     local out = ""
     local out = ""
     local tablo = p.meals
     local tablo = p.meals
    local ignore = frame.args["ignore"]
     for _, patt in pairs(frame.args) do
     for _, patt in pairs(frame.args) do
         local ids = getotherrecipes(frame, tablo, patt, ignore)
         local ids = getotherrecipes(frame, tablo, patt)
         out = out .. p.buildrecipeboxuniversal(frame, ids)
         out = out .. p.buildrecipeboxuniversal(frame, ids)
     end
     end
     return out
     return out
end
end
-- builds recipes list but does not constructs it, for debug purposes
function p.getrecipeslist(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getrecipesbyname(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end
-- same as getrecipeslist, but instead returns recipes that does not match the pattern
function p.getotherrecipeslist(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getotherrecipes(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end


--#endregion
--#endregion


--#region newdishestest
-- returns recipes which id is matched by pattern
function getrecipesbynamenew(frame, tabl, str) -- should not be inviked
    local out = {}
    for rtype, recipes in pairs(tabl) do
        for recipeId, recipe in pairs(recipes) do
            out[rtype] = {}
            if type(str) == "table" then do
                for _, patt in pairs(str) do
                    if string.match(recipeId, patt) and not table.containsv(recipe) then
                        table.insert(out[rtype], recipe)
                    end
                end
            end else do
                if string.match(recipeId, str) then
                    table.insert(out[rtype], recipe)
                end
            end
        end
        end
    end
    return out
end
-- same as above, but returns recipes that *does not* match given pattern
function getotherrecipesnew(frame, tabl, str) -- should not be invoked
    local out = {}
    for type, recipes in pairs(tabl) do
        if not table.containsk(out, type) then
            out[type] = {}
        end
        for recipeId, recipe in pairs(recipes) do
            if not string.match(recipeId, str) then
                if not table.containsv(out[type], recipe) then
                    table.insert(out[type], recipe)
                end
            end
        end
    end
    return out
end
-- you should not use this for building recipes inside lua
function p.buildnamedrecipesnew(frame) -- {{#invoke:Meals Lookup|buildnamedrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getrecipesbynamenew(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end
-- same as buildnamedrecipes, but instead builds recipes that does not match the pattern
function p.buildotherrecipesnew(frame) -- {{#invoke:Meals Lookup|buildotherrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getotherrecipesnew(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end
--#endregion


-- tests.
-- tests.
Строка 495: Строка 589:
     local out = ""
     local out = ""
     local tablo = p.meals
     local tablo = p.meals
    local ignore = frame.args["ignore"]
     for _, patt in pairs(frame.args) do
     for _, patt in pairs(frame.args) do
         for type, recipes in pairs(getrecipesbyname(frame, tablo, patt, ignore)) do
         for type, recipes in pairs(getrecipesbyname(frame, tablo, patt)) do
             out = out .. type .. "("
             out = out .. type .. "("
             for k, r in pairs(recipes) do
             for k, r in pairs(recipes) do
Строка 507: Строка 600:
     return out
     return out
end
end
-- function p.tests2(frame)
--    local out = ""
--    for type, recipes in pairs(getrecipesbyname(frame, "[Dd]ough")) do
--        out = out .. type .. "("
--        for k, r in pairs(recipes) do
--            out = out .. " " .. k .. ":" .. r["id"]
--        end
--        out = out .. ")"
--    end
--    return out
-- end


return p
return p

Текущая версия от 18:05, 2 июля 2024

Для документации этого модуля может быть создана страница Модуль:Meals Lookup/doc

local prototypes = mw.loadData("Module:Meals Lookup/data")
local chem = mw.loadData("Module:Chemistry Lookup/data")

local p = {}
p.meals = prototypes.meals
p.chemicals = chem.react

--#region universal

function table.containsv(table, value) -- FUCKING LUA
    -- containsv = contains value
    for _, v in pairs(table) do
        if v == value then
            return true
        end
    end
    return false
end

function table.containsk(table, key) -- FUCKING LUA
    -- containsk = contains key
    for k, _ in pairs(table) do
        if k == key then
            return true
        end
    end
    return false
end

function table.length(table)
    local out = 0
    for _ in pairs(table) do
        out = out + 1
    end
    return out
end

function table.isempty(t)
    local count = table.length(t)
    if count == 0 then
        do
            return true
        end
    end
    return false
end

function getrecipesfromtype(frame, type) -- should not be invoked
    return p.meals[type]
end

function getrecipe(frame, type, id) -- should not be invoked
    return getrecipesfromtype(frame, type)[id:gsub(' ', '')]
end

function getrecipetypes(frame, id) -- should not be invoked
    local out = {}
    for type, recipes in pairs(p.meals) do
        for recipeId, recipe in pairs(recipes) do
            if (recipeId:gsub(' ', '') == id:gsub(' ', '')) or (recipe["id"]:gsub(' ', '') == id:gsub(' ', '')) then
                table.insert(out, type)
                break
            end
        end
    end
    return out
end

function getimage(frame, fileid) -- should not be invoked
    local out = ""
    --[[
        WARNING!! THE NEXT THING IS "EXPENSIVE" AND DOES NOT WORKS AFTER 30 OR SMTHNG RUNS
        read https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Expensive_properties for more info
        local gifFileTitle = mw.title.new(fileid .. ".gif", "File")
        local pngFileTitle = mw.title.new(fileid .. ".png", "File")
        if gifFileTitle.file.exists then
            out = "File:" .. fileid .. ".gif"
        elseif pngFileTitle.file.exists then
            out = "File:" .. fileid .. ".png"
        else
            out = ""
        end
    --]]

    -- less expensive variant, but returns only png (AND BIG RED TEXT IF PNG DOES NOT EXISTS)
    out = "File:" .. fileid .. ".png"
    return out
end

function buildsolids(frame, array) -- should not be invoked
    local out = ""
    for solid, amount in pairs(array) do
        out = out ..
            frame:preprocess("{{Recipe Component|item={{#invoke:Entity Lookup|getname|" ..
                solid .. "}}|image=" .. getimage(frame, solid) .. "|amount=" .. amount .. "}}")
    end
    return out
end

function buildreagents(frame, array) -- should not be invoked
    local out = ""
    for item, amount in pairs(array) do
        out = out .. frame:preprocess("{{Chem Recipe Component|reagent=" .. item .. "|amount=" .. amount .. "}}")
    end
    return out
end

-- returns recipes which id is matched by pattern
function getrecipesbyname(frame, tabl, str) -- should not be inviked
    local out = {}
    for type, recipes in pairs(tabl) do
        out[type] = {}
        for recipeId, recipe in pairs(recipes) do
            if string.match(recipeId, str) then
                table.insert(out[type], recipe)
            end
        end
    end
    return out
end

-- same as above, but returns recipes that *does not* match given pattern
function getotherrecipes(frame, tabl, str) -- should not be invoked
    local out = {}
    for type, recipes in pairs(tabl) do
        if not table.containsk(out, type) then
            out[type] = {}
        end
        for recipeId, recipe in pairs(recipes) do
            if not string.match(recipeId, str) then
                if not table.containsv(out[type], recipe) then
                    table.insert(out[type], recipe)
                end
            end
        end
    end
    return out
end

function p.imageslist(frame)
    local out = "'''REQUIRED IMAGES:'''<br>"
    for cat, recipes in pairs(p.meals) do
        for id, recipe in pairs(recipes) do
            if cat == "microwaveRecipes" then
                do
                    out = out .. recipe["result"] .. ": [[:File:" .. recipe["result"] .. ".png]]<br>"
                    if #recipe["solids"] > 0 then
                        do
                            for solid in pairs(getmicrowaverecipesolids(recipe)) do
                                out = out .. solid .. ": [[:File:" .. solid .. ".png]]<br>"
                            end
                        end
                    end
                end
            end
            if cat == "sliceableRecipes" or cat == "heatableRecipes" or cat == "toolmadeRecipes" then
                do
                    out = out .. recipe["result"] .. ": [[:File:" .. recipe["result"] .. ".png]]<br>"
                    out = out .. recipe["input"] .. ": [[:File:" .. recipe["input"] .. ".png]]<br>"
                end
            end
            if cat == "grindableRecipes" then
                do
                    out = out .. recipe["input"] .. ": [[:File:" .. recipe["input"] .. ".png]]<br>"
                end
            end
        end
    end
    out = out .. "<br><hr>"
    return out
end

function p.buildeverything(frame) -- old code compatibility
    return p.buildeverythingnew(frame)
end

function p.buildeverythingold(frame)
    local out = ""
    out = out .. p.buildmicrowaverecipes(frame)
    out = out .. p.buildslicerecipes(frame)
    out = out .. p.buildgrindrecipes(frame)
    out = out .. p.buildheatrecipes(frame)
    out = out .. p.buildtoolmaderecipes(frame)
    out = out .. p.buildixablerecipes(frame)
    return out
end

--#endregion

--#region microwaveRecipes

function getmicrowaverecipesolids(frame, recipe) -- should not be invoked
    local out = {}
    for ingredient, amount in pairs(recipe["solids"]) do
        out[ingredient] = amount
    end
    return out
end

function getmicrowaverecipereagents(frame, recipe) -- should not be invoked
    local out = {}
    for ingredient, amount in pairs(recipe["reagents"]) do
        out[ingredient] = amount
    end
    return out
end

function p.buildmicrowaverecipebox(frame) -- {{#invoke:Meals Lookup|buildmicrowaverecipebox|MicrowaveRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = getrecipe(frame, "microwaveRecipes", id)
    local solids = buildsolids(frame, getmicrowaverecipesolids(frame, recipe))
    local reagents = buildreagents(frame, getmicrowaverecipereagents(frame, recipe))
    out = frame:preprocess("{{Recipe Box" ..
        "|name={{#invoke:Entity Lookup|getname|" .. recipe["result"] .. "}}" ..
        "|component-1=" .. solids .. "\n" .. reagents ..
        "|transformer={{Recipe Transformers|microwaveRecipes|" .. recipe["time"] .. "}}" ..
        "|result=" ..
        frame:preprocess("{{Result Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["result"] .. "}}|image=" .. getimage(frame, recipe["result"]) .. "}}") ..
        "}}")
    return out
end

function p.buildmicrowaverecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "microwaveRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildmicrowaverecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion microwaveRecipes

--#region sliceableRecipes

function p.buildslicerecipebox(frame) -- {{#invoke:Meals Lookup|buildslicerecipebox|SliceableRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = getrecipe(frame, "sliceableRecipes", id)
    out = frame:preprocess("{{Recipe Box" ..
        "|name={{#invoke:Entity Lookup|getname|" .. recipe["result"] .. "}}" ..
        "|component-1=" ..
        frame:preprocess("{{Recipe Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["input"] .. "}}|image=" .. getimage(frame, recipe["input"]) .. "}}") ..
        "|transformer={{Recipe Transformers|sliceableRecipes}}" ..
        "|result=" ..
        frame:preprocess("{{Result Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["result"] .. "}}|image=" .. getimage(frame, recipe["result"]) .. "|amount=" .. recipe["count"] .. "}}") ..
        "}}")
    return out
end

function p.buildslicerecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "sliceableRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildslicerecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion sliceableRecipes

--#region grindableRecipes

function p.buildgrindrecipebox(frame) -- {{#invoke:Meals Lookup|buildgrindrecipebox|GrindableRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = getrecipe(frame, "grindableRecipes", id)
    local reagents = buildreagents(frame, recipe["result"])
    out = frame:preprocess("{{Recipe Box" ..
        "|name={{#invoke:Entity Lookup|getname|" .. recipe["id"] .. "}}" ..
        "|component-1=" ..
        frame:preprocess("{{Result Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["input"] .. "}}|image=" .. getimage(frame, recipe["input"]) .. "}}") ..
        "|transformer={{Recipe Transformers|grindableRecipes}}" ..
        "|result=" .. reagents ..
        "}}")
    return out
end

function p.buildgrindrecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "grindableRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildgrindrecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion grindableRecipes

--#region heatableRecipes

function p.buildheatrecipebox(frame) -- {{#invoke:Meals Lookup|buildheatrecipebox|HeatableRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = getrecipe(frame, "heatableRecipes", id)
    out = frame:preprocess("{{Recipe Box" ..
        "|name={{#invoke:Entity Lookup|getname|" .. recipe["result"] .. "}}" ..
        "|component-1=" ..
        frame:preprocess("{{Recipe Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["input"] .. "}}|image=" .. getimage(frame, recipe["input"]) .. "}}") ..
        "|transformer={{Recipe Transformers|heatableRecipes|" .. recipe["minTemp"] .. "}}" ..
        "|result=" ..
        frame:preprocess("{{Result Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["result"] .. "}}|image=" .. getimage(frame, recipe["result"]) .. "}}") ..
        "}}")
    return out
end

function p.buildheatrecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "heatableRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildheatrecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion heatableRecipes

--#region toolmadeRecipes

function p.buildtoolmaderecipebox(frame) -- {{#invoke:Meals Lookup|buildtoolmaderecipebox|ToolmadeRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = getrecipe(frame, "toolmadeRecipes", id)
    local transformer = "toolmadeRecipes" .. recipe["tool"]
    out = frame:preprocess("{{Recipe Box" ..
        "|name={{#invoke:Entity Lookup|getname|" .. recipe["result"] .. "}}" ..
        "|component-1=" ..
        frame:preprocess("{{Recipe Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["input"] .. "}}|image=" .. getimage(frame, recipe["input"]) .. "}}") ..
        "|transformer={{Recipe Transformers|" .. transformer .. "}}" ..
        "|result=" ..
        frame:preprocess("{{Result Component|item={{#invoke:Entity Lookup|getname|" ..
            recipe["result"] .. "}}|image=" .. getimage(frame, recipe["result"]) .. "}}") ..
        "}}")
    return out
end

function p.buildtoolmaderecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "toolmadeRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildtoolmaderecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion toolmadeRecipes

--#region mixableRecipes

function getchemicalreagents(recipe) -- should not be invoked
    local out = {}
    for ingredient, data in pairs(recipe["reactants"]) do
        out[ingredient] = data["amount"]
    end
    return out
end

function p.buildmixablerecipebox(frame) -- {{#invoke:Meals Lookup|buildmixablerecipebox|MixableRecipeID}}
    local out = ""
    local id = frame.args[1]:gsub(' ', '')
    local recipe = p.chemicals[id]
    local input = buildreagents(frame, getchemicalreagents(recipe))

    local results = {}
    for _, v in pairs(recipe["effects"]) do
        table.insert(results, v.description)
    end

    local result = table.concat(results, "\n")

    out = frame:preprocess("{{Recipe Box" ..
        "|component-1=" .. input ..
        "|name= " ..
        "|transformer={{Recipe Transformers|mixableRecipes}}" ..
        "|result=" .. result .. "}}")
    return out
end

function p.buildixablerecipes(frame)
    local out = ""
    for id in pairs(getrecipesfromtype(frame, "mixableRecipes")) do
        out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildmixablerecipebox|" .. id .. "}}") .. "\n"
    end
    return out
end

--#endregion mixableRecipes

--#region dishes

function p.buildrecipeboxuniversal(frame, idtable)
    local out = ""
    for type, recipes in pairs(idtable) do
        -- INTRUDER ALERT: SHITCODE IS IN THE BASE
        local id = ""
        if type == "microwaveRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out ..
                    frame:preprocess("{{#invoke:Meals Lookup|buildmicrowaverecipebox|" .. id .. "}}") .. "\n"
                end
            end
        elseif type == "mixableRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildmixablerecipebox|" .. id .. "}}") .. "\n"
                end
            end
        elseif type == "sliceableRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildslicerecipebox|" .. id .. "}}") .. "\n"
                end
            end
        elseif type == "grindableRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildgrindrecipebox|" .. id .. "}}") .. "\n"
                end
            end
        elseif type == "heatableRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildheatrecipebox|" .. id .. "}}") .. "\n"
                end
            end
        elseif type == "toolmadeRecipes" and not table.isempty(recipes) then
            do
                for n, recipe in pairs(recipes) do
                    id = recipe["id"]
                    out = out .. frame:preprocess("{{#invoke:Meals Lookup|buildtoolmaderecipebox|" .. id .. "}}") .. "\n"
                end
            end
        end
    end
    return out
end

-- you should not use this for building recipes inside lua
function p.buildnamedrecipes(frame) -- {{#invoke:Meals Lookup|buildnamedrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getrecipesbyname(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end

-- same as buildnamedrecipes, but instead builds recipes that does not match the pattern
function p.buildotherrecipes(frame) -- {{#invoke:Meals Lookup|buildotherrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getotherrecipes(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end

-- builds recipes list but does not constructs it, for debug purposes 
function p.getrecipeslist(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getrecipesbyname(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end

-- same as getrecipeslist, but instead returns recipes that does not match the pattern
function p.getotherrecipeslist(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getotherrecipes(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end


--#endregion

--#region newdishestest

-- returns recipes which id is matched by pattern
function getrecipesbynamenew(frame, tabl, str) -- should not be inviked
    local out = {}
    for rtype, recipes in pairs(tabl) do
        for recipeId, recipe in pairs(recipes) do
            out[rtype] = {}
            if type(str) == "table" then do
                for _, patt in pairs(str) do
                    if string.match(recipeId, patt) and not table.containsv(recipe) then
                        table.insert(out[rtype], recipe)
                    end
                end
            end else do
                if string.match(recipeId, str) then
                    table.insert(out[rtype], recipe)
                end
            end
        end
        end
    end
    return out
end

-- same as above, but returns recipes that *does not* match given pattern
function getotherrecipesnew(frame, tabl, str) -- should not be invoked
    local out = {}
    for type, recipes in pairs(tabl) do
        if not table.containsk(out, type) then
            out[type] = {}
        end
        for recipeId, recipe in pairs(recipes) do
            if not string.match(recipeId, str) then
                if not table.containsv(out[type], recipe) then
                    table.insert(out[type], recipe)
                end
            end
        end
    end
    return out
end

-- you should not use this for building recipes inside lua
function p.buildnamedrecipesnew(frame) -- {{#invoke:Meals Lookup|buildnamedrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getrecipesbynamenew(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end

-- same as buildnamedrecipes, but instead builds recipes that does not match the pattern
function p.buildotherrecipesnew(frame) -- {{#invoke:Meals Lookup|buildotherrecipes|[Pattern1 | Pattern2 | Pattern3 | ...]}}
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        local ids = getotherrecipesnew(frame, tablo, patt)
        out = out .. p.buildrecipeboxuniversal(frame, ids)
    end
    return out
end


--#endregion

-- tests.
function p.tests1(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getotherrecipes(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end

function p.tests2(frame)
    local out = ""
    local tablo = p.meals
    for _, patt in pairs(frame.args) do
        for type, recipes in pairs(getrecipesbyname(frame, tablo, patt)) do
            out = out .. type .. "("
            for k, r in pairs(recipes) do
                out = out .. " " .. k .. ":" .. r["id"]
            end
            out = out .. ")"
        end
    end
    return out
end

return p