Module:Mastery group: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
--
-------------------------------------------------------------------------------
-- Module for Mastery Groups
--  
--
--                            Module:Mastery group
--
-- This module implements Template:Mastery group
-------------------------------------------------------------------------------


local m_util = require('Module:Util')
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local m_cargo = require('Module:Cargo')
local getArgs = require('Module:Arguments').getArgs
 
local f_infocard = require('Module:Infocard')._main
local f_infocard = require('Module:Infocard')._main
local p = {}


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
Line 22: Line 23:
         keystone = 'Keystone passive skills',
         keystone = 'Keystone passive skills',
         notable = 'Notable passive skills',
         notable = 'Notable passive skills',
         basic = 'Basic passive skills',
         basic = 'Small passive skills',
         ascendancy_notable = 'Ascendancy notable passive skills',
         ascendancy_notable = 'Ascendancy notable passive skills',
         ascendancy_basic = 'Ascendancy basic passive skills',
         ascendancy_basic = 'Ascendancy small passive skills',
     },
     },
      
      
Line 36: Line 37:
      
      
     intro = {
     intro = {
         text = "Bonuses from the '''%s Mastery''' can be allocated for one passive point after allocating a [[Passive_skill#Notable_passives|notable passive skill]] within an applicable cluster. ",
         text = "Bonuses from the '''%s''' can be allocated for one passive point after allocating a [[Passive_skill#Notable_passives|notable passive skill]] within an applicable cluster. ",
     },
     },
      
      
Line 82: Line 83:
             field = 'icon',
             field = 'icon',
             type = 'Page',
             type = 'Page',
             func = function(tpl_args, frame, value)
             func = function(tpl_args, value)
                 if value then
                 if value then
                     return string.format(i18n.icon_name, value)
                     return string.format(i18n.icon_name, value)
Line 102: Line 103:
         key = 'mastery_effects',
         key = 'mastery_effects',
         header = nil,
         header = nil,
         display = function (tpl_args, frame, value)
         display = function (tpl_args, value)
             local results = m_cargo.map_results_to_id{
             local results = m_cargo.map_results_to_id{
                 field='mastery_effects.id',
                 field='mastery_effects.id',
Line 150: Line 151:
     local cls = 'passive-icon-type__mastery'
     local cls = 'passive-icon-type__mastery'
     local main_page = mastery_group['mastery_groups.main_page'] or mastery_group['main_pages._pageName'] or mastery_group['mastery_groups.name'] or mastery_group['mastery_groups.icon']
     local main_page = mastery_group['mastery_groups.main_page'] or mastery_group['main_pages._pageName'] or mastery_group['mastery_groups.name'] or mastery_group['mastery_groups.icon']
     div = mw.html.create('div')
     local div = mw.html.create('div')
     div:addClass('passive-icon-container')
     div:addClass('passive-icon-container')
     div:addClass(cls)
     div:addClass(cls)
Line 234: Line 235:
end
end


function h.intro_text(tpl_args, frame)
function h.intro_text(tpl_args)
     --[[
     --[[
     Display an introductory text about the passive skill.
     Display an introductory text about the passive skill.
Line 240: Line 241:
     local out = {}
     local out = {}
     -- if mw.ustring.find(tpl_args['id'], '_') then
     -- if mw.ustring.find(tpl_args['id'], '_') then
     --    out[#out+1] = frame:expandTemplate{
     --    out[#out+1] = mw.getCurrentFrame():expandTemplate{
     --        title='Incorrect title',  
     --        title='Incorrect title',  
     --        args = {title=tpl_args['id']}  
     --        args = {title=tpl_args['id']}  
Line 254: Line 255:
end
end


-- function h.stat_box(tpl_args, frame)
-- function h.stat_box(tpl_args)
--    --[[
--    --[[
--    Display the stat box.
--    Display the stat box.
Line 315: Line 316:
--    return tostring(container)
--    return tostring(container)
-- end
-- end


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- Page functions
-- Main functions
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------


local p = {}
local function _mastery_group(tpl_args)
 
-- This way the helper functions can be used in other modules
p.h = h
 
-- Declare cargo tables:
p.table_mastery_groups = m_cargo.declare_factory{data=tables.mastery_groups}
 
function p.mastery_group(frame)
     --[[
     --[[
     Stores data and displays a infobox about the passive skill.
     Stores data and displays a infobox about the passive skill.
Line 343: Line 335:
      
      
     ]]
     ]]
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)


     -- parse and store mastery group into cargo table
     -- parse and store mastery group into cargo table
     m_util.args.from_cargo_map{
     m_util.args.from_cargo_map{
         tpl_args=tpl_args,
         tpl_args=tpl_args,
        frame=frame,
         table_map=tables.mastery_groups,
         table_map=tables.mastery_groups,
     }
     }
    -- Attach to tables
    mw.getCurrentFrame():expandTemplate{title = 'Template:Mastery group/cargo/mastery groups/attach'}
      
      
     --
     --
Line 383: Line 371:
             local dsp
             local dsp
             if data.display then
             if data.display then
                 dsp = data.display(tpl_args, frame, value)
                 dsp = data.display(tpl_args, value)
             else
             else
                 dsp = value
                 dsp = value
Line 407: Line 395:
     local out = {
     local out = {
         f_infocard(infocard_args),
         f_infocard(infocard_args),
         h.intro_text(tpl_args, frame),
         h.intro_text(tpl_args),
         --h.stat_box(tpl_args, frame),
         --h.stat_box(tpl_args),
     }
     }
      
      
Line 419: Line 407:
end
end


function p.mastery_group_box(frame)
local function _mastery_group_box(tpl_args)
     --[[
     --[[
     Queries a mastery group and displays it.
     Queries a mastery group and displays it.
Line 428: Line 416:
      
      
     ]]
     ]]
   
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
      
      
     tpl_args.name = tpl_args.name or tpl_args[1]
     tpl_args.name = tpl_args.name or tpl_args[1]
Line 480: Line 462:
         for _, v in ipairs(results) do
         for _, v in ipairs(results) do
             m_cargo.store(
             m_cargo.store(
                frame,
                 {
                 {
                     _table='main_pages',  
                     _table='main_pages',  
Line 496: Line 477:
end
end


-- function p.passive_skill_link(frame)
-- ----------------------------------------------------------------------------
--     --[[
-- Exported functions
--     Links a passive skill
-- ----------------------------------------------------------------------------
   
--     Examples
--     --------
--     = p.passive_skill_link{id='AscendancyAscendant45', format='tablerow'}
--     ]]
   
--     -- Get args
--     tpl_args = getArgs(frame, {
--         parentFirst = true
--     })
--     frame = m_util.misc.get_frame(frame)
   
--     tpl_args.name = tpl_args.name or tpl_args[1]
--     if tpl_args.name then
--         tpl_args.q_where = string.format('passive_skills.name="%s"', tpl_args.name)
--     elseif tpl_args.id then
--         tpl_args.q_where = string.format('passive_skills.id="%s"', tpl_args.id)
--     elseif tpl_args.q_where then
--     else
--         error('Either name, id or q_where must be specified')
--     end
   
--     local results = m_cargo.query(
--         {'passive_skills', 'main_pages'},
--         {
--             'passive_skills._pageName',
--             'passive_skills.stat_text',
--             'passive_skills.main_page',
--             'passive_skills.name',
--             'passive_skills.icon',
--             'passive_skills.is_keystone',
--             'passive_skills.is_notable',
--             'passive_skills.ascendancy_class',
--             'main_pages._pageName',
--         },
--         { 
--             join='passive_skills.id=main_pages.id',
--             where=string.format('(%s) AND passive_skills.stat_text IS NOT NULL', tpl_args.q_where),
--             orderBy='passive_skills.stat_text',
--             limit=2,
--         }
--     )
   
--     if #results > 1 then
--         error('Too many passives found!')
--     elseif #results < 1 then
--         error('No passives found')
--     end
--     local passive = results[1]
   
--     if tpl_args.format == 'tablerow' then
--         local main_page = passive['passive_skills.main_page'] or passive['main_pages._pageName'] or passive['passive_skills.name']
--         return string.format(
--             '| [[%s|%s]]%s\n| %s',
--             main_page,
--             passive['passive_skills.name'],
--             h.format_mastery_icon(passive),
--             passive['passive_skills.stat_text']
--         )
--     elseif tpl_args.format == nil then
--         return
--     else
--         error(string.format('Invalid return format specified: %s', tpl_args.format))
--     end
-- end


-- -- Not sure whether we need a more sophisticated variant like item or mod tables here yet
local p = {}


-- function p.passive_skill_table2(frame)
-- Declare cargo tables:
--    -- Get args
p.table_mastery_groups = m_cargo.declare_factory{data=tables.mastery_groups}
--    tpl_args = getArgs(frame, {
--        parentFirst = true
--    })
--    frame = m_util.misc.get_frame(frame)
   
--    if tpl_args.q_tables then
--        tpl_args.q_tables = tpl_args.q_tables .. ',' .. 'passive_skill_stats'
--    else
--        tpl_args.q_tables = 'passive_skill_stats'
--    end
   
--    if tpl_args.q_join then
--        tpl_args.q_join = tpl_args.q_join .. ',' .. 'passive_skills._pageID=passive_skill_stats._pageID'
--    else
--        tpl_args.q_join = 'passive_skills._pageID=passive_skill_stats._pageID'
--    end
   
--    tpl_args.q_orderBy = 'passive_skills.ascendancy_class IS NULL DESC, passive_skills.is_keystone, passive_skills.is_notable, passive_skills.name'
   
--    return m_cargo.table_query{
--        tpl_args=tpl_args,
--        frame=frame,
--        main_table='passive_skills',
--        row_unique_fields = {'passive_skills.name'},
--        data={
--            tables = {
--                passive_skill_stats = {
--                    join='passive_skills._pageID=passive_skill_stats._pageID',
--                },
--            },
--            -- display data
--            {
--                args = {'ascendancy'},
--                header = i18n.passive_table.ascendancy_class,
--                fields = {
--                    'passive_skills.ascendancy_class',
--                },
--                display = function (tpl_args, frame, tr, data)
--                    local passive = data[1]
--                    if passive['passive_skills.ascendancy_class'] then
--                        tr:tag('td')
--                            :wikitext(string.format('[[%s]]<br>[[File:%s avatar.png|link=%s]]', passive['passive_skills.ascendancy_class'], passive['passive_skills.ascendancy_class'], passive['passive_skills.ascendancy_class']))
--                    else
--                        tr:wikitext(m_util.html.td.na{})
--                    end
--                end,
--                order = 0,
--                sort_type = 'text',
--            },
--            {
--                args = nil,
--                header = i18n.passive_table.name,
--                fields = {
--                    'passive_skills._pageName',
--                    'passive_skills.main_page',
--                    'passive_skills.name',
--                    'passive_skills.icon',
--                    'passive_skills.is_keystone',
--                    'passive_skills.is_notable',
--                    'passive_skills.ascendancy_class',
--                },
--                display = function (tpl_args, frame, tr, data)
--                    local passive = data[1]
--                    local type_key = h.get_type(passive)
--                    tr
--                        :tag('td')
--                            :attr('data-sort-value', passive['passive_skills.name'] .. type_key)
--                            :wikitext(string.format('[[%s|%s]]<br>%s', passive['passive_skills.main_page'] or passive['passive_skills.name'], passive['passive_skills.name'], h.format_mastery_icon(passive))
--                            :done()
--                end,
--                order = 1000,
--                sort_type = 'text',
--                options = {
--                    [7] = {
--                        optional=true,
--                    },
--                },
--            },
--            {
--                arg = {'default', 'stat', 'stats', 'stat_text'},
--                header = i18n.passive_table.stats,
--                fields = {
--                    'passive_skills.stat_text',
--                },
--                display = function (tpl_args, frame, tr, data)
--                    local passive = data[1]
--                    local stats, stat_order = h.make_stat_order(data)
--                    tr
--                        :tag('td')
--                            :wikitext(h.stat_page_links(stat_order, stats))
--                            :done()
--                end,
--                order = 1001,
--                sort_type = 'text',
--            }
--        },
--    }
-- end


-- function p.passive_skill_table(frame)
--
--     -- Get args
-- Template:Mastery group
--     tpl_args = getArgs(frame, {
--  
--        parentFirst = true
p.mastery_group = m_util.misc.invoker_factory(_mastery_group, {
--    })
     wrappers = 'Template:Mastery group',
--    frame = m_util.misc.get_frame(frame)
})
   
--    tpl_args.ascendancy = m_util.cast.boolean(tpl_args.ascendancy)
   
--    local prepend = {
--        q_join=true,
--    }
   
--    local query = {
--        join='passive_skills._pageID=passive_skill_stats._pageID',
--        limit=5000,
--        groupBy='passive_skills._pageID',
--    }
--    for key, value in pairs(tpl_args) do
--        if string.sub(key, 0, 2) == 'q_' then
--            if prepend[key] then
--                value = ',' .. value
--            end
           
--            query[string.sub(key, 3)] = value
--        end
--    end
   
--    local results = m_cargo.query(
--        {'passive_skills', 'passive_skill_stats'},
--        {
--            'passive_skills._pageName',
--            'passive_skills.main_page',
--            'passive_skills.name',
--            'passive_skills.stat_text',
--            'passive_skills.icon',
--            'passive_skills.is_keystone',
--            'passive_skills.is_notable',
--            'passive_skills.ascendancy_class',
--        },
--        query
--    )
--    result_map = m_cargo.map_results_to_id{
--        results=results,
--        field='passive_skills.name',
--        keep_id_field=true,
--    }
--    for key, rows in pairs(result_map) do
--        result_map[key] = h.sort_by_type(rows)
--    end
   
--    -- header
--    local tbl = mw.html.create('table')
--    tbl:addClass('wikitable')
--    tbl:addClass('sortable')
   
--    local tr = tbl:tag('tr')
--    if tpl_args.ascendancy then
--        tr:tag('th')
--            :wikitext(i18n.passive_table.ascendancy_class)
--    end
   
--    tr
--        :tag('th')
--            :wikitext(i18n.passive_table.name)
--            :done()
--        :tag('th')
--            :wikitext(i18n.passive_table.stats)
--            :done()
   
--    -- rows
--    local used_names = {}
--     for _, passive_row in ipairs(results) do
--        local pn = passive_row['passive_skills.name']
--        if used_names[pn] == nil then
--            local type_results_map = result_map[passive_row['passive_skills.name']]
--            used_names[pn] = true
--            for _, type_key in ipairs(h.type_order) do
--                local type_results = type_results_map[type_key]
--                if #type_results > 0 then
--                    local row = type_results[1]
--                    tr = tbl:tag('tr')
                       
--                    if tpl_args.ascendancy then
--                        if row['passive_skills.ascendancy_class'] then
--                            tr:tag('td')
--                                :wikitext(string.format('[[%s]]<br>[[File:%s avatar.png|link=%s]]', row['passive_skills.ascendancy_class'], row['passive_skills.ascendancy_class'], row['passive_skills.ascendancy_class']))
--                        else
--                            tr:wikitext(m_util.html.td.na{})
--                        end
--                    end
                   
--                    local stats, stat_order = h.make_stat_order(type_results)
--                    tr
--                        :tag('td')
--                            :attr('data-sort-value', row['passive_skills.name'] .. type_key)
--                            :wikitext(string.format('[[%s|%s]]<br>%s', row['passive_skills.main_page'] or row['passive_skills.name'], row['passive_skills.name'], h.format_mastery_icon(row)))
--                            :done()
--                        :tag('td')
--                            :wikitext(h.stat_page_links(stat_order, stats))
--                            :done()
--                end
--            end
--        end
--    end
   
--    return tostring(tbl)
-- end
 
-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------


return p
return p

Latest revision as of 00:40, 29 May 2023

Module documentation[view] [edit] [history] [purge]


Lua logo

This module depends on the following other modules:

This module is for specifying one passive mastery. Implements {{mastery group}}.

-------------------------------------------------------------------------------
-- 
--                            Module:Mastery group
-- 
-- This module implements Template:Mastery group
-------------------------------------------------------------------------------

local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')

local f_infocard = require('Module:Infocard')._main

-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------

local i18n = {
    icon_name = 'File:%s mastery icon.png',
    cats = {
        effect = 'Mastery Group',
        data = 'Mastery Groups',
        
        keystone = 'Keystone passive skills',
        notable = 'Notable passive skills',
        basic = 'Small passive skills',
        ascendancy_notable = 'Ascendancy notable passive skills',
        ascendancy_basic = 'Ascendancy small passive skills',
    },
    
    passive_box = {
        keystone = 'Keystone',
        notable = 'Notable Passive Skill',
        basic = 'Passive Skill',
        ascendancy_notable = 'Ascendancy Notable Passive Skill',
        ascendancy_basic = 'Ascendancy Passive Skill',
    },
    
    intro = {
        text = "Bonuses from the '''%s''' can be allocated for one passive point after allocating a [[Passive_skill#Notable_passives|notable passive skill]] within an applicable cluster. ",
    },
    
    mastery_group_box_table = {
        header = '%s Mastery',
        id = 'Id',
        mastery_effects = 'Mastery Effects',
    },
    
    passive_table = {
        ascendancy_class = 'Ascendancy<br>Class',
        name = 'Name',
        stats = 'Stats',
    },
    
    errors = {
        no_passives_found = 'No mastery groups with the given name were found',
    },
}

-- ----------------------------------------------------------------------------
-- Cargo
-- ----------------------------------------------------------------------------

local tables = {}

tables.mastery_groups = {
    table = 'mastery_groups',
    order = {'id', 'name', 'main_page', 'icon', 'mastery_effects',},
    fields = {
        id = {
            field = 'id',
            type = 'String',
            required = true,
        },
        name = {
            field = 'name',
            type = 'String',
        },
        main_page = {
            field = 'main_page',
            type = 'Page',
        },
        icon = {
            field = 'icon',
            type = 'Page',
            func = function(tpl_args, value)
                if value then
                    return string.format(i18n.icon_name, value)
                end
            end
        },
        mastery_effects = {
            field = 'mastery_effects',
            type = 'List (,) of String',
        },
    }
}


local display = {}
display.map_to_property = {'icon', 'mastery_effects'}
display.tbl = {
    {
        key = 'mastery_effects',
        header = nil,
        display = function (tpl_args, value)
            local results = m_cargo.map_results_to_id{
                field='mastery_effects.id',
                results=m_cargo.array_query{
                    tables={'mastery_effects'},
                    fields={'mastery_effects.id', 'mastery_effects._pageName', 'mastery_effects.stat_text'},
                    id_array=value,
                    id_field='mastery_effects.id',
                    ignore_missing=true,
                }
            }
            
            local ul = mw.html.create('ul')
            for _, key in ipairs(value) do
                local row = results[key]
                if row then
                    row = row[1]
                end
                local text
                if row then
                    text = string.format('[[%s|%s]]', row['mastery_effects._pageName'], row['mastery_effects.stat_text'] or row['mastery_effects.id'] or row['mastery_effects._pageName'])
                else
                    text = key
                end
                ul
                    :tag('li')
                        :wikitext(text)
                        :done()
            end
            
            return tostring(ul)
        end,
    },
}

-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------

local h = {}

function h.format_mastery_icon(mastery_group)
    if mastery_group['mastery_groups.icon'] == nil then
        return ''
    end
    
    local cls = 'passive-icon-type__mastery'
    local main_page = mastery_group['mastery_groups.main_page'] or mastery_group['main_pages._pageName'] or mastery_group['mastery_groups.name'] or mastery_group['mastery_groups.icon']
    local div = mw.html.create('div')
    div:addClass('passive-icon-container')
    div:addClass(cls)
    div:tag('div')
        :addClass('passive-icon-frame')
        :done()
    div:wikitext(
        string.format(
            '[[%s|link=%s]]', 
            mastery_group['mastery_groups.icon'], 
            main_page
        )
    )
    return tostring(div)
end

-- function h.make_stat_order(results)
--     local stats = {}
--     local stat_order = {}
--     for _, row in ipairs(results) do 
--         local stat = row['passive_skills.stat_text']
--         -- Can't show results here that don't have a stat line
--         if stat then
--             if stats[stat] == nil then
--                 stats[stat] = {row}
--                 table.insert(stat_order, stat)
--             else
--                 table.insert(stats[stat], row)
--             end
--         end
--     end
    
--     return stats, stat_order
-- end

-------------------------------------
-- Parameters:
--   results: the set of mastery_groups matching the query
-------------------------------------
function h.make_effects_order(results)
    local mastery_effects_list = {}
    local me_order = {}
    for _, row in ipairs(results) do 
        local mastery_effects = row['mastery_groups.mastery_effects']
        -- Can't show results here that don't have a stat line
        if mastery_effects then
            if mastery_effects_list[mastery_effects] == nil then
                mastery_effects_list[mastery_effects] = {row}
                table.insert(me_order, mastery_effects)
            else
                table.insert(mastery_effects_list[mastery_effects], row)
            end
        end
    end
    
    return mastery_effects_list, me_order
end

-- function h.stat_page_links(stat_order, stats)
--     local out = {}
--     for i, key in ipairs(stat_order) do
--         local links = {}
--         for j, row in ipairs(stats[key]) do
--             links[#links+1] = string.format('[[%s|&#91;%s&#93;]]', row['passive_skills._pageName'], j)
--         end
--         out[i] = string.format('<span class="passive-line">%s <span class="passive-hover">%s</span></span>', key, table.concat(links, ' '))
--     end
    
--     return table.concat(out, '<hr>')
-- end

function h.effect_page_links(effects_order, effects_list)
    local out = {}
    for i, key in ipairs(effects_order) do
        local links = {}
        for j, row in ipairs(effects_list[key]) do
            links[#links+1] = string.format('[[%s|&#91;%s&#93;]]', row['mastery_groups._pageName'], j)
        end
        out[i] = string.format('<span class="passive-line">%s <span class="passive-hover">%s</span></span>', key, table.concat(links, ' '))
    end
    
    return table.concat(out, '<hr>')
end

function h.intro_text(tpl_args)
    --[[
    Display an introductory text about the passive skill.
    ]]
    local out = {}
    -- if mw.ustring.find(tpl_args['id'], '_') then
    --     out[#out+1] = mw.getCurrentFrame():expandTemplate{
    --         title='Incorrect title', 
    --         args = {title=tpl_args['id']} 
    --     }
    -- end
    
    out[#out+1] = string.format(
        i18n.intro.text,
        tpl_args['name']
    )
    
    return table.concat(out)
end

-- function h.stat_box(tpl_args)
--     --[[
--     Display the stat box.
--     ]]
--     local container = mw.html.create('div')
--     container
--         :attr('class', 'modbox floatright')
        
--     -- stat table 
--     tbl = container:tag('table')
--     tbl
--         :attr('class', 'wikitable sortable')
--         -- :attr('style', 'style="width: 100%;"')
--         :tag('tr')
--             :tag('th')
--                 :attr('colspan', 3)
--                 :wikitext('Stats')
--                 :done()
--             :done()
--         :tag('tr')
--             :tag('th')
--                 :wikitext('#')
--                 :done()
--             :tag('th')
--                 :wikitext('Stat Id')
--                 :done()
--             :tag('th')
--                 :wikitext('Value')
--                 :done()
--             :done()
--             :done()
--         :done()
        
--     local i = 0
--     local value = nil
--     repeat
--         i = i + 1
--         value = {
--             id = tpl_args[string.format('stat%s_id', i)],
--             value = tpl_args[string.format('stat%s_value', i)],
--         }
        
--         if value.id then
--             tbl
--                 :tag('tr')
--                     :tag('td')
--                         :wikitext(i)
--                         :done()
--                     :tag('td')
--                         :wikitext(value.id)
--                         :done()
--                     :tag('td')
--                         :wikitext(value.value)
--                         :done()
--                     :done()
--                 :done()
--         end
--     until value.id == nil
    
--     return tostring(container)
-- end

-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------

local function _mastery_group(tpl_args)
    --[[
    Stores data and displays a infobox about the passive skill.
    
    Examples
    --------
    = p.mastery_group{
        id = 'Armour',
        name = 'Armour Mastery'
        mastery_effects = 'Armour1,Armour2,Armour3,Armour4,Armour5,Armour6',
        icon = 'PassiveMasteryArmourActive'
    }
    
    ]]

    -- parse and store mastery group into cargo table
    m_util.args.from_cargo_map{
        tpl_args=tpl_args,
        table_map=tables.mastery_groups,
    }

    -- Attach to tables
    mw.getCurrentFrame():expandTemplate{title = 'Template:Mastery group/cargo/mastery groups/attach'}
    
    --
    -- Infobox
    --
    local mastery = {}
    for _, key in ipairs(display.map_to_property) do
        local v = tpl_args[key]
        if type(v) == 'boolean' then
            if v then
                v = 1
            else
                v = 0
            end
        end
        mastery[string.format('%s.%s', tables.mastery_groups.table, tables.mastery_groups.fields[key].field)] = v
    end
    
    local infocard_args = {}
    infocard_args.header = tpl_args.name
    
    local tbl = mw.html.create('table')
    for _, data in ipairs(display.tbl) do
        local value = tpl_args[data.key]
        -- if default is nil, this will be compared against nil which is what we want, so value ~= nil isn't needed
        if value ~= tables.mastery_groups.fields[data.key].default then
            local dsp
            if data.display then
                dsp = data.display(tpl_args, value)
            else
                dsp = value
            end
            tbl
                :tag('tr')
                    :tag('th')
                        :wikitext(data.header)
                        :done()
                    :tag('td')
                        :attr('class', data.css)
                        :wikitext(dsp)
                        :done()
                    :done()
        end
    end
    
    infocard_args[1] = tostring(tbl)
    infocard_args[2] = h.format_mastery_icon(mastery)
    infocard_args.class = 'mastery_infocard'
    --infocard_args[3] = tpl_args.stat_text

    local out = {
        f_infocard(infocard_args),
        h.intro_text(tpl_args),
        --h.stat_box(tpl_args),
    }
    
    --mw.logObject(out)
    
    local cats = {
        i18n.cats.data,
    }
    return table.concat(out) .. m_util.misc.add_category(cats)
end

local function _mastery_group_box(tpl_args)
    --[[
    Queries a mastery group and displays it.
    
    Examples
    --------
    = p.mastery_group_box{name='Accuracy'}
    
    ]]
    
    tpl_args.name = tpl_args.name or tpl_args[1]
    
    if not tpl_args.q_where and tpl_args.name then
        tpl_args.q_where = string.format('mastery_groups.id="%s" AND mastery_groups.mastery_effects > ""', tpl_args.name)
    elseif not (tpl_args.q_where and not tpl_args.name) then
        error('q_where or name must be specified')
    end
    
    local results = m_cargo.query(
        {'mastery_groups'},
        {
            'mastery_groups.icon',
            'mastery_groups.mastery_effects',
            'mastery_groups.id'
        }, 
        {
            where=tpl_args.q_where,
            orderBy='mastery_groups.id',
            limit=5000,
        }
    )
    if #results == 0 then
        error(i18n.errors.no_passives_found)
    end
    
    local out = {}
    local cats = {}
    if #results > 0 then
        cats[#cats+1] = i18n.cats[type_key]
        local effects_list, effects_order = h.make_effects_order(results)
        
        local mastery_group = results[1]
        
        local infocard_args = {}
        infocard_args.header = mastery_group['mastery_groups.id']
        
        infocard_args[1] = h.format_mastery_icon(passive)
        infocard_args[2] = h.effect_page_links(effects_order, effects_list)
        infocard_args[3] = m_util.html.poe_color('flavour', passive['passive_skills.flavour_text'])
        
        out[#out+1] = f_infocard(infocard_args)
        
        -- Store as main page:
        for _, v in ipairs(results) do
            m_cargo.store(
                {
                    _table='main_pages', 
                    id=v['mastery_groups.id'],
                }
            )
        end
    end
    
    if tpl_args.cats == nil or m_util.cast.boolean(tpl_args.cats) then
        out[#out+1] = m_util.misc.add_category(cats)
    end
    
    return table.concat(out)
end

-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------

local p = {}

-- Declare cargo tables:
p.table_mastery_groups = m_cargo.declare_factory{data=tables.mastery_groups}

--
-- Template:Mastery group
-- 
p.mastery_group = m_util.misc.invoker_factory(_mastery_group, {
    wrappers = 'Template:Mastery group',
})

return p