mNo edit summary |
mNo edit summary |
||
(28 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
local mathOps = require("Module:MathOps") |
local mathOps = require("Module:MathOps") |
||
local utils = require("Module:Utils") |
local utils = require("Module:Utils") |
||
+ | local prkz = require("Module:Datatable/Perks") |
||
+ | local perkImg = require("Module:PerkImage") |
||
+ | local str = require("Module:Strings") |
||
local frame = mw.getCurrentFrame() |
local frame = mw.getCurrentFrame() |
||
local defaultSpeed = 4 --m/s | 100% |
local defaultSpeed = 4 --m/s | 100% |
||
− | local bar = "|" -- code for | |
||
⚫ | |||
⚫ | |||
local strings = { |
local strings = { |
||
− | file = "File", |
||
killers = "Killers", |
killers = "Killers", |
||
the = "The", |
the = "The", |
||
Line 51: | Line 50: | ||
end |
end |
||
− | function |
+ | function p.getKillerById(id) |
− | for |
+ | for _, killer in ipairs(killers) do |
− | if |
+ | if killer.id == id then return killer end |
end |
end |
||
− | return |
+ | return nil |
end |
end |
||
function getKillerIdByName(name) |
function getKillerIdByName(name) |
||
for _, killer in ipairs(killers) do |
for _, killer in ipairs(killers) do |
||
− | if killer.realName |
+ | if killer.realName ~= nil then |
− | + | if killer.realName == name then |
|
+ | return killer.id |
||
+ | end |
||
+ | else |
||
+ | if killer.name == name then -- ex.Demogorgon without a real name |
||
+ | return killer.id |
||
+ | end |
||
end |
end |
||
end |
end |
||
Line 69: | Line 74: | ||
function p.resolveKillerCharTable(name) |
function p.resolveKillerCharTable(name) |
||
+ | local dlcs = require("Module:DLCs") |
||
name = utils.resolveParameter(name) |
name = utils.resolveParameter(name) |
||
killerId = getKillerIdByName(name) |
killerId = getKillerIdByName(name) |
||
Line 81: | Line 87: | ||
'! class = "center bold" colspan = 2 | ' .. strings.the .. ' ' .. killer.name .. nl .. |
'! class = "center bold" colspan = 2 | ' .. strings.the .. ' ' .. killer.name .. nl .. |
||
ntl .. nl .. |
ntl .. nl .. |
||
+ | |||
⚫ | |||
+ | -- '<tabber>' .. |
||
+ | -- '|-|First=' .. |
||
+ | -- 'First tab sample text.' .. |
||
+ | -- '|-|Second=' .. |
||
+ | -- 'Second tab content goes here. ' .. |
||
+ | -- '|-|Third Tab Title=' .. |
||
+ | -- 'Third tab content goes here.' .. |
||
+ | -- '</tabber>' .. |
||
+ | |||
⚫ | |||
ntl .. nl |
ntl .. nl |
||
if killer.realName ~= nil then |
if killer.realName ~= nil then |
||
Line 112: | Line 128: | ||
ntl .. nl |
ntl .. nl |
||
if killer.altSpeed ~= nil then |
if killer.altSpeed ~= nil then |
||
− | result = result .. '| class = "titleColumn" | ' .. strings. |
+ | result = result .. '| class = "titleColumn" | ' .. strings.altSpeed .. ' || class = "valueColumn" | ' .. resolveAltSpeed(killer) .. nl .. ntl .. nl |
end |
end |
||
result = result .. |
result = result .. |
||
Line 120: | Line 136: | ||
ntl .. nl |
ntl .. nl |
||
if killer.dlc ~= nil then |
if killer.dlc ~= nil then |
||
− | result = result .. '| class = "titleColumn" | ' .. strings.dlc .. ' || class = "valueColumn" | [[' .. getDlcById(killer.dlc).name .. ']] ' .. nl .. ntl .. nl |
+ | result = result .. '| class = "titleColumn" | ' .. strings.dlc .. ' || class = "valueColumn" | [[' .. dlcs.getDlcById(killer.dlc).name .. ']] ' .. nl .. ntl .. nl |
end |
end |
||
result = result .. |
result = result .. |
||
Line 237: | Line 253: | ||
result = result .. altSpeed[1] .. " % <b>" .. bar .. "</b> " .. speedMps .. " " .. strings.mps |
result = result .. altSpeed[1] .. " % <b>" .. bar .. "</b> " .. speedMps .. " " .. strings.mps |
||
if altSpeed[2] ~= nil then |
if altSpeed[2] ~= nil then |
||
− | result = result .. "(" .. altSpeed .. ")" |
+ | result = result .. pg .. "(" .. altSpeed[2] .. ")" |
end |
end |
||
if i < #killer.altSpeed then |
if i < #killer.altSpeed then |
||
− | result = result .. nl |
+ | result = result .. "<hr>" --.. nl .. nl |
end |
end |
||
end |
end |
||
Line 252: | Line 268: | ||
if type(killer.radius) == "number" then |
if type(killer.radius) == "number" then |
||
− | return killer.radius .. " |
+ | return killer.radius .. " " .. strings.metres |
elseif type(killer.radius) == "table" then |
elseif type(killer.radius) == "table" then |
||
for i, radius in ipairs(killer.radius) do |
for i, radius in ipairs(killer.radius) do |
||
Line 268: | Line 284: | ||
end |
end |
||
if i < #killer.radius then |
if i < #killer.radius then |
||
− | result = result .. nl |
+ | result = result .. nl .. nl |
end |
end |
||
end |
end |
||
end |
end |
||
+ | return result |
||
end |
end |
||
Line 292: | Line 309: | ||
result = result .. "<div style=\"display: inline-block; text-align:center; margin: 10px\">[[" .. name .. "]] - " .. killer.name |
result = result .. "<div style=\"display: inline-block; text-align:center; margin: 10px\">[[" .. name .. "]] - " .. killer.name |
||
− | result = result .. "[[ |
+ | result = result .. "[[" .. cstr.file .. fileName .. ".png|center|frameless|link=" .. strings.the .. " " .. killer.name .. "]]</div>" |
end |
end |
||
Line 305: | Line 322: | ||
local fileName |
local fileName |
||
− | result = result .. |
+ | result = result .. |
+ | '<div class = "fpbox" id = "fpkiller" style = "text-align: center;">' .. |
||
− | + | '<div class = "heading">' .. strings.the .. space .. '[[' .. strings.killers .. ']] [[' .. cstr.file .. 'IconHelpLoading killer.png|32px]]</div>' .. |
|
⚫ | |||
+ | '<div class = "fplinks charSection">' |
||
for i, killer in ipairs(killers) do |
for i, killer in ipairs(killers) do |
||
+ | |||
⚫ | |||
fileName = resolveKillersPortraitFileNameById(killer.id) |
fileName = resolveKillersPortraitFileNameById(killer.id) |
||
+ | result = result .. |
||
− | + | '<div class = "fplink charMainPageBox plainlinks image"><div class="box"><div class="row"><div class="cell">' .. |
|
⚫ | |||
− | + | '<div class = "image">[[' .. cstr.file .. fileName .. '.png|link=' .. strings.the .. space .. killer.name .. ']]</div>' .. |
|
⚫ | |||
+ | '<div class = "charPerkBox">' .. resolveCharPerksMainPage(killer) .. '</div>' .. |
||
+ | '</div></div></div></div>' |
||
end |
end |
||
− | result = result .. |
+ | result = result .. |
− | + | "</div>" .. |
|
+ | "</div>" |
||
+ | return result |
||
+ | end |
||
+ | |||
+ | function resolveCharPerksMainPage(character) |
||
+ | local mPerks = require("Module:Perks") |
||
⚫ | |||
+ | local perkList = mPerks.getPerksByCharacter(character) |
||
+ | |||
⚫ | |||
+ | result = result .. '[[' .. cstr.file .. mPerks.getTeachablePerkIcon(perk) .. '|link=' .. perk.name .. '|42px]]' |
||
+ | end |
||
+ | |||
return result |
return result |
||
end |
end |
||
Line 341: | Line 375: | ||
mw.log(id) |
mw.log(id) |
||
for j, sImage in ipairs(killerImages) do |
for j, sImage in ipairs(killerImages) do |
||
− | if sImage.id == id then |
+ | if sImage.id == id and sImage.preview ~= nil then |
return sImage.preview |
return sImage.preview |
||
end |
end |
||
Line 348: | Line 382: | ||
end |
end |
||
− | function |
+ | function getKillerListWithPerks() |
+ | local perkTable = {} |
||
⚫ | |||
+ | for _,perk in ipairs(perks) do |
||
− | if dlc.id == id then return dlc end |
||
+ | if perk.character ~= nil and perk.charType == 'K' then |
||
+ | if perkTable[perk.character] == nil then |
||
+ | perkTable[perk.character] = {} |
||
+ | end |
||
+ | perkTable[perk.character].id = perk.character |
||
+ | perkTable[perk.character][#perkTable[perk.character]+1] = perk |
||
+ | end |
||
end |
end |
||
+ | |||
+ | return perkTable |
||
+ | end |
||
+ | |||
+ | function p.resolveKillersEntries() |
||
+ | local perkTable = getKillerListWithPerks() |
||
⚫ | |||
+ | |||
+ | result = result .. '<div style = "display: flex; flex-flow: row wrap; justify-content:center;">' .. nl |
||
+ | |||
+ | for _, trio in ipairs(perkTable) do |
||
⚫ | |||
+ | '{| class = "wikitable"' .. nl |
||
⚫ | |||
+ | killer = p.getKillerById(trio.id) |
||
+ | result = result .. '|+ ' .. killer.name .. nl .. |
||
+ | ntl .. nl .. |
||
+ | '| rowspan = 3 | [[' .. cstr.file .. resolveKillerPortraitImageFileName(killer) .. '.png|99px|link=' .. killer.name .. ']]' .. nl |
||
+ | utils.sortPerksByLevel(trio) |
||
+ | for i, perk in ipairs(trio) do |
||
+ | result = result .. '! [[' .. cstr.file .. perkImg.main(perk.techName or perk.name) .. '|33px]]' .. nl .. |
||
+ | '! [[' .. perk.name .. ']]' .. nl .. |
||
+ | '| ' .. utils.clr(perk.level, 6) .. nl |
||
+ | if i < #trio then |
||
+ | result = result .. ntl .. nl |
||
+ | end |
||
+ | end |
||
+ | result = result .. '|}' .. nl .. |
||
+ | '</div>' .. nl |
||
+ | end |
||
+ | |||
+ | result = result .. '</div>' .. nl |
||
+ | |||
+ | mw.log(result) |
||
+ | --mw.log(mw.dumpObject(perkTable)) |
||
+ | return result |
||
end |
end |
||
Revision as of 01:22, 21 October 2021
local p = {}
local data = require("Module:Datatable")
local mathOps = require("Module:MathOps")
local utils = require("Module:Utils")
local prkz = require("Module:Datatable/Perks")
local perkImg = require("Module:PerkImage")
local str = require("Module:Strings")
local frame = mw.getCurrentFrame()
local defaultSpeed = 4 --m/s | 100%
local strings = {
killers = "Killers",
the = "The",
unknownKiller = "UnknownKiller",
realName = "Name",
noName = "None", --When the killer doesn't have the real name (ex. Demogorgon)
altName = "Game Alias(es)",
gender = "Gender",
nationality = "Nationality",
realm = "Realm", --link
power = "Power", --link
powerType = "Power [[Attack]] Type",
spAttackTrue = "Special Attack",
spAttackFalse = "Basic Attack",
weapon = "Weapon",
speed = "Movement speed", --iconlink
altSpeed = "Alternate Movement speed",
metres = "metres",
m = "m", --abbreviation of metres
terror = "Terror Radius", --iconlink
lullabyRadius = "[[Lullaby]] Radius",
height = "Height", --image
tall = "Tall",
avg = "Average",
dlc = "DLC",
actor = "Voice Actor",
breathing = "Breathing",
altBreathing = "Alternate Breathing",
menuMusic = "Menu Music",
terrorMusic = "Terror Radius Music",
lullaby = "Lullaby",
lullabies = "Lullabies",
mps = "m/s",
err = "Error"
}
function p.getCountOfKillers()
return utils.getCount("killer")
end
function p.getKillerById(id)
for _, killer in ipairs(killers) do
if killer.id == id then return killer end
end
return nil
end
function getKillerIdByName(name)
for _, killer in ipairs(killers) do
if killer.realName ~= nil then
if killer.realName == name then
return killer.id
end
else
if killer.name == name then -- ex.Demogorgon without a real name
return killer.id
end
end
end
return 0
end
function p.resolveKillerCharTable(name)
local dlcs = require("Module:DLCs")
name = utils.resolveParameter(name)
killerId = getKillerIdByName(name)
killer = utils.getCharacterById(killerId, killers)
reuslt = ""
if type(killer) ~= "table" then return killer end
result =
'{| class = "infoboxtable"' .. nl ..
ntl ..' class = "infoboxTitle" | ' .. nl ..
'! class = "center bold" colspan = 2 | ' .. strings.the .. ' ' .. killer.name .. nl ..
ntl .. nl ..
-- '<tabber>' ..
-- '|-|First=' ..
-- 'First tab sample text.' ..
-- '|-|Second=' ..
-- 'Second tab content goes here. ' ..
-- '|-|Third Tab Title=' ..
-- 'Third tab content goes here.' ..
-- '</tabber>' ..
'! class = "center" colspan = 2 | [[' .. cstr.file .. resolveKillerPortraitImageFileName(killer) .. '.png|150px]]' .. nl ..
ntl .. nl
if killer.realName ~= nil then
result = result .. '| class = "titleColumn" | ' .. strings.realName .. ' || class = "valueColumn" | ' .. (killer.realName or strings.noName) .. nl .. ntl .. nl
end
if killer.altName ~= nil then
result = result .. '| class = "titleColumn" | ' .. strings.altName .. ' || class = "valueColumn italic" | ' .. resolveAltName(killer) .. nl .. ntl .. nl
end
result = result ..
'| class = "titleColumn" | ' .. strings.gender .. ' || class = "valueColumn" | ' .. utils.resolveGender(killer.gender) .. nl ..
ntl .. nl ..
'| class = "titleColumn" | ' .. strings.nationality .. ' || class = "valueColumn" | ' .. killer.nationality .. nl ..
ntl .. nl
if killer.realm ~= nil or killer.dlc ~= nil then
local killerRealm = resolveKillerRealm(killer)
if killerRealm ~= 0 then
result = result .. '| class = "titleColumn" | ' .. strings.realm .. ' || class = "valueColumn" | [[' .. killerRealm .. ']] ' .. nl .. ntl .. nl
end
end
result = result ..
'| class = "titleColumn" | ' .. strings.power .. ' || class = "valueColumn" | [[' .. killer.power .. ']]' .. nl ..
ntl .. nl
if killer.specialAttack ~= nil then
result = result .. '| class = "titleColumn" | ' .. strings.powerType .. ' || class = "valueColumn" | ' .. resolvePowerAttack(killer) .. nl .. ntl .. nl
end
result = result ..
'| class = "titleColumn" | ' .. strings.weapon .. ' || class = "valueColumn" | [[' .. killer.weapon .. ']]' .. nl ..
ntl .. nl ..
'| class = "titleColumn" | ' .. strings.speed .. ' || class = "valueColumn" | ' .. resolveKillerSpeed(killer) .. nl ..
ntl .. nl
if killer.altSpeed ~= nil then
result = result .. '| class = "titleColumn" | ' .. strings.altSpeed .. ' || class = "valueColumn" | ' .. resolveAltSpeed(killer) .. nl .. ntl .. nl
end
result = result ..
'| class = "titleColumn" | ' .. strings.terror .. ' || class = "valueColumn" | ' .. resolveTerrorRadius(killer) .. nl ..
ntl .. nl ..
'| class = "titleColumn" | ' .. strings.height .. ' || class = "valueColumn" | ' .. resolveHeight(killer) .. nl ..
ntl .. nl
if killer.dlc ~= nil then
result = result .. '| class = "titleColumn" | ' .. strings.dlc .. ' || class = "valueColumn" | [[' .. dlcs.getDlcById(killer.dlc).name .. ']] ' .. nl .. ntl .. nl
end
result = result ..
'| class = "titleColumn" | ' .. strings.actor .. ' || class = "valueColumn" | ' .. (killer.actor or strings.uknownActor) .. nl ..
--TODO Check all music existence, this should be in separate table, Twinsuse Twins as a reference
ntl .. nl ..
'| class = "titleColumn center" colspan = 2 | ' .. strings.breathing .. nl ..
ntl .. nl ..
'| class = "valueColumn" | ' .. "Breathing" .. nl ..
ntl .. nl ..
'| class = "titleColumn center" colspan = 2 | ' .. strings.menuMusic .. nl ..
ntl .. nl ..
'| class = "valueColumn" | ' .. "Menu Music" .. nl ..
ntl .. nl ..
'| class = "titleColumn center" colspan = 2 | ' .. strings.terrorMusic .. nl ..
ntl .. nl ..
'| class = "valueColumn" | ' .. "Terror Radius Music" .. nl ..
ntl .. nl ..
'| class = "titleColumn center" colspan = 2 | ' .. strings.lullaby .. nl ..
ntl .. nl ..
'| class = "valueColumn" | ' .. "Lullaby" .. nl ..
'|}'
mw.log(result)
return result
end
function resolveKillerPortraitImageFileName(killer)
local fileConst = "_charSelect_portrait"
return "K" .. string.format("%02d", killer.id) .. fileConst
end
function resolveAltName(killer)
if type(killer.altName) == "string" then return '"' .. killer.altName .. '"'
elseif type(killer.altName) == "table" then
local result = ""
for i, name in ipairs(killer.altName) do
result = result .. '"' .. name .. '"'
if i < #killer.altName then
result = result .. nl
end
end
return result
end
return strings.err
end
function resolvePowerAttack(killer)
result = ""
if killer.specialAttack then
result = strings.spAttackTrue
else
result = strings.spAttackFalse
end
if killer.altAttackNote ~= nil then
result = result .. nl .. "(" .. killer.altAttackNote .. ")"
end
return result
end
function resolveKillerRealm(killer)
if killer.dlc == nil then
for _, realm in ipairs(realms) do
if realm.id == killer.realm then return realm.name end
end
else
for _, realm in ipairs(realms) do
if type(realm.dlc) == "number" and killer.dlc == realm.dlc then return realm.name
elseif type(realm.dlc) == "table" then
for i, dlc in ipairs(killer) do
if dlc.id == dlc[i] then return realm.name end
end
end
end
end
return 0
end
function resolveKillerSpeed(killer)
local speedPercent = 0
local speedMps = 0
local note
local result
if type(killer.speed) == "number" then
speedPercent = killer.speed
speedMps = defaultSpeed * (killer.speed / 100) --speed is in percentage
else --so the killer speed is table
speedPercent = killer.speed[1]
speedMps = defaultSpeed * (killer.speed[1] / 100)
note = killer.speed[2]
end
result = speedPercent .. " % <b>" .. bar .. "</b> " .. speedMps .. " " .. strings.mps
if note ~= nil then
result = result .. nl .. "(" .. note .. ")"
end
return result
end
function resolveAltSpeed(killer)
local result = ""
local speedMps
for i, altSpeed in ipairs(killer.altSpeed) do
speedMps = defaultSpeed * (altSpeed[1] / 100)
result = result .. altSpeed[1] .. " % <b>" .. bar .. "</b> " .. speedMps .. " " .. strings.mps
if altSpeed[2] ~= nil then
result = result .. pg .. "(" .. altSpeed[2] .. ")"
end
if i < #killer.altSpeed then
result = result .. "<hr>" --.. nl .. nl
end
end
return result
end
function resolveTerrorRadius(killer)
result = ""
if type(killer.radius) == "number" then
return killer.radius .. " " .. strings.metres
elseif type(killer.radius) == "table" then
for i, radius in ipairs(killer.radius) do
if radius[3] ~= nil then --open span with title hover
result = result .. '<span class = "valueTooltip" title = "' .. radius[3] .. '">'
end
result = result .. radius[1] --metres value
if radius[2] ~= nil then --note for alt speed, if there is a note for the speed the abbreviation for metres is used instead of full name
result = result .. strings.m .. " (" .. radius[2] .. ")"
else
result = result .. " " .. strings.metres
end
if radius[3] ~= nil then --close span hover
result = result .. '</span>'
end
if i < #killer.radius then
result = result .. nl .. nl
end
end
end
return result
end
function resolveHeight(killer)
if killer.height == 'T' then return strings.tall
elseif killer.height == 'A' then return strings.avg
else return strings.err
end
end
function p.resolveKillersTable()
local result = ""
local name
local fileName
result = result .. "<div style=\"color: #fff;\">"
for i, killer in ipairs(killers) do
name = killer.shortName or killer.realName or killer.name
fileName = resolveKillersPortraitFileNameById(killer.id)
result = result .. "<div style=\"display: inline-block; text-align:center; margin: 10px\">[[" .. name .. "]] - " .. killer.name
result = result .. "[[" .. cstr.file .. fileName .. ".png|center|frameless|link=" .. strings.the .. " " .. killer.name .. "]]</div>"
end
result = result .. "</div>"
return result
end
function p.resolveKillersTableMainPage()
local result = ""
local name
local fileName
result = result ..
'<div class = "fpbox" id = "fpkiller" style = "text-align: center;">' ..
'<div class = "heading">' .. strings.the .. space .. '[[' .. strings.killers .. ']] [[' .. cstr.file .. 'IconHelpLoading killer.png|32px]]</div>' ..
'<div class = "fplinks charSection">'
for i, killer in ipairs(killers) do
fileName = resolveKillersPortraitFileNameById(killer.id)
result = result ..
'<div class = "fplink charMainPageBox plainlinks image"><div class="box"><div class="row"><div class="cell">' ..
'<div class = "image">[[' .. cstr.file .. fileName .. '.png|link=' .. strings.the .. space .. killer.name .. ']]</div>' ..
'<div class = "charLink killerLink link">[[' .. strings.the .. space .. killer.name .. ']]</div>' ..
'<div class = "charPerkBox">' .. resolveCharPerksMainPage(killer) .. '</div>' ..
'</div></div></div></div>'
end
result = result ..
"</div>" ..
"</div>"
return result
end
function resolveCharPerksMainPage(character)
local mPerks = require("Module:Perks")
local result = ''
local perkList = mPerks.getPerksByCharacter(character)
for _, perk in ipairs(perkList) do
result = result .. '[[' .. cstr.file .. mPerks.getTeachablePerkIcon(perk) .. '|link=' .. perk.name .. '|42px]]'
end
return result
end
function resolveKillersPortraitFileNameById(id)
local fileConst = "_charPreview_portrait"
local fileName
fileName = getFileNameFromTableById(id) --get custom name from table
if not utils.isValidFileName(fileName) then --K{ID}_charPreview_portrait
fileName = "K" .. string.format("%02d", id) .. fileConst
end
if not utils.isValidFileName(fileName) then --File not Found
fileName = strings.unknownKiller .. fileConst
end
mw.log(fileName)
return fileName
end
function getFileNameFromTableById(id)
mw.log(id)
for j, sImage in ipairs(killerImages) do
if sImage.id == id and sImage.preview ~= nil then
return sImage.preview
end
end
return ""
end
function getKillerListWithPerks()
local perkTable = {}
for _,perk in ipairs(perks) do
if perk.character ~= nil and perk.charType == 'K' then
if perkTable[perk.character] == nil then
perkTable[perk.character] = {}
end
perkTable[perk.character].id = perk.character
perkTable[perk.character][#perkTable[perk.character]+1] = perk
end
end
return perkTable
end
function p.resolveKillersEntries()
local perkTable = getKillerListWithPerks()
local result = ""
result = result .. '<div style = "display: flex; flex-flow: row wrap; justify-content:center;">' .. nl
for _, trio in ipairs(perkTable) do
result = result .. '<div class = "entryTable">' .. nl ..
'{| class = "wikitable"' .. nl
killer = p.getKillerById(trio.id)
result = result .. '|+ ' .. killer.name .. nl ..
ntl .. nl ..
'| rowspan = 3 | [[' .. cstr.file .. resolveKillerPortraitImageFileName(killer) .. '.png|99px|link=' .. killer.name .. ']]' .. nl
utils.sortPerksByLevel(trio)
for i, perk in ipairs(trio) do
result = result .. '! [[' .. cstr.file .. perkImg.main(perk.techName or perk.name) .. '|33px]]' .. nl ..
'! [[' .. perk.name .. ']]' .. nl ..
'| ' .. utils.clr(perk.level, 6) .. nl
if i < #trio then
result = result .. ntl .. nl
end
end
result = result .. '|}' .. nl ..
'</div>' .. nl
end
result = result .. '</div>' .. nl
mw.log(result)
--mw.log(mw.dumpObject(perkTable))
return result
end
return p