Fixed leoalt slash command, better time format

Leandro Silva [10-27-18 - 10:30]
Fixed leoalt slash command, better time format
Filename
LeoAltholic.lua
LeoAltholic.xml
LeoAltholicUI.lua
LeoAltholic_API.lua
diff --git a/LeoAltholic.lua b/LeoAltholic.lua
index 6549b95..9fd204c 100644
--- a/LeoAltholic.lua
+++ b/LeoAltholic.lua
@@ -840,6 +840,10 @@ local function onQuestComplete(eventCode, questName, level, previousExperience,
 end

 local function migrateDataToV2()
+    LeoAltholic.globalData.settings.toolbar = {
+        enabled = false
+    }
+    if LeoAltholic.globalData.CharList == nil then return end -- fresh install?
     for charName, char in pairs(LeoAltholic.globalData.CharList) do
         local oldResearch = char.research
         LeoAltholic.globalData.CharList[charName].research = {}
@@ -894,7 +898,7 @@ local function initializeVars()
                 screen = true
             },
             toolbar = {
-                enabled = true
+                enabled = false
             }
         }
     end
@@ -1040,7 +1044,7 @@ local function onAddOnLoaded(event, addonName)
             ReloadUI()
         end
     end
-    SLASH_COMMANDS["/leoalt"] = function(cmd) LeoAltholic:ShowUI() end
+    SLASH_COMMANDS["/leoalt"] = function(cmd) LeoAltholic:ToggleUI() end

     initializeVars()

diff --git a/LeoAltholic.xml b/LeoAltholic.xml
index 27b93b6..97a2d69 100644
--- a/LeoAltholic.xml
+++ b/LeoAltholic.xml
@@ -19,8 +19,7 @@
                     <Dimensions x="1000" y="50"/>
                     <Edge edgeSize="1"/>
                 </Backdrop>
-                <Label name="$(parent)Title" color="39B027" font="ZoFontWinH3" wrapMode="ELLIPSIS"
-                       verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Title" color="39B027" font="ZoFontWinH3" wrapMode="ELLIPSIS" verticalAlignment="CENTER">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="16" offsetY="10"/>
                 </Label>
                 <Button name="$(parent)Close" clickSound="Click">
@@ -1036,7 +1035,7 @@
             <Controls>
                 <Texture name="$(parent)BG" inherits="ZO_ThinListBgStrip" />

-                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER">
                     <Dimensions x="180" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)BG" relativePoint="TOPLEFT"/>
                 </Label>
@@ -1048,15 +1047,15 @@
                     <Dimensions x="120" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Level" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
-                <Label name="$(parent)Class" font="LeoAltholicLargeFont" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Class" font="LeoAltholicLargeFont" verticalAlignment="CENTER">
                     <Dimensions x="120" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Race" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
-                <Label name="$(parent)Alliance" font="LeoAltholicLargeFont" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Alliance" font="LeoAltholicLargeFont" verticalAlignment="CENTER">
                     <Dimensions x="200" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Class" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
-                <Label name="$(parent)Riding" font="LeoAltholicLargeFont" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Riding" font="LeoAltholicLargeFont" verticalAlignment="CENTER">
                     <Dimensions x="240" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Alliance" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
@@ -1072,7 +1071,7 @@
             <Controls>
                 <Texture name="$(parent)BG" inherits="ZO_ThinListBgStrip" />

-                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER">
                     <Dimensions x="180" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)BG" relativePoint="TOPLEFT"/>
                 </Label>
@@ -1084,11 +1083,11 @@
                     <Dimensions x="200" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Points" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
-                <Label name="$(parent)Recovery" font="LeoAltholicLargeFont" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Recovery" font="LeoAltholicLargeFont" verticalAlignment="CENTER">
                     <Dimensions x="120" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Maximum" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
-                <Label name="$(parent)WeaponSpellCrit" font="LeoAltholicLargeFont" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)WeaponSpellCrit" font="LeoAltholicLargeFont" verticalAlignment="CENTER">
                     <Dimensions x="200" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Recovery" relativePoint="TOPRIGHT" offsetX="10"/>
                 </Label>
@@ -1115,12 +1114,12 @@
                     <OnMouseExit> ZO_Tooltips_HideTextTooltip() </OnMouseExit>
                 </Label>

-                <Label name="$(parent)Name" mouseEnabled="true" font="ZoFontWinH3" normalColor="ffffff" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Name" font="ZoFontWinH3" normalColor="ffffff" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="80" offsetY="20"/>
                     <Dimensions x="180" y="30"/>
                 </Label>

-                <Label name="$(parent)RaceClass" mouseEnabled="true" font="ZoFontGame" color="E8DFAF" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)RaceClass" font="ZoFontGame" color="E8DFAF" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="80" offsetY="50"/>
                     <Dimensions x="450" y="30"/>
                 </Label>
@@ -1221,36 +1220,36 @@
         <Control name="LeoAltholicWritsListTemplate" virtual="true" horizontalAlignment="LEFT" verticalAlignment="CENTER">
             <Dimensions x="990" y="30"/>
             <Controls>
-                <Label name="$(parent)Name" mouseEnabled="true" font="ZoFontGame" normalColor="ffffff" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Name" font="ZoFontGame" normalColor="ffffff" inheritAlpha="true" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="2" offsetY="0"/>
                     <Dimensions x="180" y="30"/>
                 </Label>

-                <Label name="$(parent)Craft1Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft1Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Name" relativePoint="TOPRIGHT" offsetX="10" offsetY="0"/>
                 </Label>
-                <Label name="$(parent)Craft2Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft2Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft1Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
-                <Label name="$(parent)Craft6Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft6Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft2Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
-                <Label name="$(parent)Craft7Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft7Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft6Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
-                <Label name="$(parent)Craft3Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft3Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft7Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
-                <Label name="$(parent)Craft4Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft4Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft3Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
-                <Label name="$(parent)Craft5Status" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Craft5Status" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Dimensions x="70" y="28"/>
                     <Anchor point="TOPLEFT" relativeTo="$(parent)Craft4Status" relativePoint="TOPRIGHT" offsetX="12"/>
                 </Label>
@@ -1265,7 +1264,7 @@
         <Control name="LeoAltholicSkillsListTemplate" virtual="true" horizontalAlignment="LEFT" verticalAlignment="CENTER">
             <Dimensions x="990" y="30"/>
             <Controls>
-                <Label name="$(parent)Name" mouseEnabled="true" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" verticalAlignment="CENTER" horizontalAlignment="LEFT" resizeToFitDescendents="false">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="0" offsetY="0"/>
                     <Dimensions x="180" y="30"/>
                 </Label>
@@ -1634,7 +1633,7 @@
             <Controls>
                 <Texture name="$(parent)BG" inherits="ZO_ThinListBgStrip" />

-                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER">
                     <Dimensions x="180" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)BG" relativePoint="TOPLEFT"/>
                 </Label>
@@ -1666,7 +1665,7 @@
         <Control name="LeoAltholicInventoryListTemplate" virtual="true" horizontalAlignment="LEFT" verticalAlignment="CENTER">
             <Dimensions x="990" y="105"/>
             <Controls>
-                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER">
                     <Dimensions x="180" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"/>
                 </Label>
@@ -1711,7 +1710,7 @@
         <Control name="LeoAltholicResearchListTemplate" virtual="true" horizontalAlignment="LEFT" verticalAlignment="CENTER">
             <Dimensions x="880" y="260"/>
             <Controls>
-                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Name" font="LeoAltholicLargeFont" color="ffffff" verticalAlignment="CENTER">
                     <Dimensions x="180" y="32" />
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"/>
                 </Label>
@@ -1763,7 +1762,7 @@
                     <Dimensions x="342" y="40"/>
                     <Edge edgeSize="1"/>
                 </Backdrop>
-                <Label name="$(parent)Title" color="39B027" font="ZoFontWinH3" wrapMode="ELLIPSIS" verticalAlignment="CENTER" mouseEnabled="true">
+                <Label name="$(parent)Title" color="39B027" font="ZoFontWinH3" wrapMode="ELLIPSIS" verticalAlignment="CENTER">
                     <Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" offsetX="16" offsetY="10"/>
                     <OnInitialized>self:SetText(GetString(SI_MAIN_MENU_INVENTORY))</OnInitialized>
                 </Label>
diff --git a/LeoAltholicUI.lua b/LeoAltholicUI.lua
index de8253f..512b86d 100644
--- a/LeoAltholicUI.lua
+++ b/LeoAltholicUI.lua
@@ -110,47 +110,6 @@ function LeoAltholic.ShowTab(tab)
     control:SetHidden(false)
 end

-function LeoAltholic.FormatTime(seconds, short, colorizeCountdown)
-    if short == nil then short = false end
-    local formats = {
-        dhm = SI_TIME_FORMAT_DDHHMM_DESC_SHORT,
-        day = SI_TIME_FORMAT_DAYS,
-        hm = SI_TIME_FORMAT_HHMM_DESC_SHORT,
-        hms = SI_TIME_FORMAT_HHMMSS_DESC_SHORT,
-        hour = SI_TIME_FORMAT_HOURS,
-        ms = SI_TIME_FORMAT_MMSS_DESC_SHORT,
-    }
-    if seconds and seconds > 0 then
-        local ss = seconds % 60
-        local mm = math.floor(seconds / 60)
-        local hh = math.floor(mm / 60)
-        mm = mm % 60
-        local dn = math.floor(hh / 24)
-        local result = ''
-        if dn > 0 then
-            if short then
-                result = zo_strformat(GetString(formats.day), dn) .." "..zo_strformat(GetString(formats.hour), hh - (dn*24))
-            else
-                result = zo_strformat(GetString(formats.dhm), dn, hh - (dn*24), mm)
-            end
-        elseif hh > 0 then
-            if short then
-                result = zo_strformat(GetString(formats.hm), hh, mm)
-            else
-                result = zo_strformat(GetString(formats.hms), hh, mm, ss)
-            end
-        elseif mm >= 0 then result = zo_strformat(GetString(formats.ms), mm, ss)
-        end
-        if colorizeCountdown == true then
-            if seconds < 3600 then result = '|cFF4020'..result..'|r'
-            elseif seconds < 86400 then result = '|cCCCC00'..result..'|r'
-            elseif seconds < 604800 then result = '|cFFFFFF'..result..'|r'
-            else result = '|c00FF00'..result..'|r' end
-        end
-        return result
-    else return '|cFF4020'..GetString(SI_GAMEPAD_CAMPAIGN_SCORING_DURATION_REMAINING_DONE)..'|r' end
-end
-
 function LeoAltholicUI.InitPanels()
     LeoAltholicUI.bioList = LeoAltholicBioList:New(LeoAltholicWindowBioPanelListScroll)
     LeoAltholicUI.bioList:RefreshData()
diff --git a/LeoAltholic_API.lua b/LeoAltholic_API.lua
index be17035..df93110 100644
--- a/LeoAltholic_API.lua
+++ b/LeoAltholic_API.lua
@@ -22,11 +22,62 @@ function LeoAltholic.IsBeforeReset(timestamp)
 end

 --[[
+Formats a time
+]]
+function LeoAltholic.FormatTime(seconds, short, colorizeCountdown)
+    if short == nil then short = false end
+    local formats = {
+        dhm = SI_TIME_FORMAT_DDHHMM_DESC_SHORT,
+        day = SI_TIME_FORMAT_DAYS,
+        hm = SI_TIME_FORMAT_HHMM_DESC_SHORT,
+        hms = SI_TIME_FORMAT_HHMMSS_DESC_SHORT,
+        hour = SI_TIME_FORMAT_HOURS,
+        ms = SI_TIME_FORMAT_MMSS_DESC_SHORT,
+    }
+    if seconds and seconds > 0 then
+        local ss = seconds % 60
+        local mm = math.floor(seconds / 60)
+        local hh = math.floor(mm / 60)
+        mm = mm % 60
+        local dn = math.floor(hh / 24)
+        local hhdn = hh - (dn*24)
+
+        local ssF = string.format("%02d", ss)
+        local mmF = string.format("%02d", mm)
+        local hhF = string.format("%02d", hh)
+        local hhdnF = string.format("%02d", hhdn)
+
+        local result = ''
+        if dn > 0 then
+            if short then
+                result = zo_strformat(GetString(formats.day), dn) .." "..zo_strformat(GetString(formats.hour), hhdnF)
+            else
+                result = zo_strformat(GetString(formats.dhm), dn, hhdnF, mmF)
+            end
+        elseif hh > 0 then
+            if short then
+                result = zo_strformat(GetString(formats.hm), hhF, mmF)
+            else
+                result = zo_strformat(GetString(formats.hms), hhF, mmF, ssF)
+            end
+        elseif mm >= 0 then result = zo_strformat(GetString(formats.ms), mmF, ssF)
+        end
+        if colorizeCountdown == true then
+            if seconds < 3600 then result = '|cFF4020'..result..'|r'
+            elseif seconds < 86400 then result = '|cCCCC00'..result..'|r'
+            elseif seconds < 604800 then result = '|cFFFFFF'..result..'|r'
+            else result = '|c00FF00'..result..'|r' end
+        end
+        return result
+    else return '|cFF4020'..GetString(SI_GAMEPAD_CAMPAIGN_SCORING_DURATION_REMAINING_DONE)..'|r' end
+end
+
+--[[
 Return if the craft is done for the day for the charName (if not specified, the current character is used)
 ]]
 function LeoAltholic.IsWritDoneToday(craft, charName)
-    local char
-    if not charName then char = LeoAltholic.globalData.CharList[LeoAltholic.CharName] end
+    if not charName then charName = LeoAltholic.CharName end
+    local char = LeoAltholic.globalData.CharList[charName]
     if not char then return end
     for _, writ in pairs(char.quests.writs) do
         if craft == writ.craft then
@@ -37,8 +88,8 @@ function LeoAltholic.IsWritDoneToday(craft, charName)
 end

 function LeoAltholic.IsWritStartedToday(craft, charName)
-    local char
-    if not charName then char = LeoAltholic.globalData.CharList[LeoAltholic.CharName] end
+    if not charName then charName = LeoAltholic.CharName end
+    local char = LeoAltholic.globalData.CharList[charName]
     if not char then return end
     for _, writ in pairs(char.quests.writs) do
         if craft == writ.craft then
@@ -49,8 +100,9 @@ function LeoAltholic.IsWritStartedToday(craft, charName)
 end

 function LeoAltholic.HasStillResearchFor(craft, charName)
-    local char
-    if not charName then char = LeoAltholic.globalData.CharList[LeoAltholic.CharName] end
+    if not charName then charName = LeoAltholic.CharName end
+    local char = LeoAltholic.globalData.CharList[charName]
+    if not char then return end
     for line = 1, GetNumSmithingResearchLines(craft) do
         local _, _, numTraits = GetSmithingResearchLineInfo(craft, line)
         for trait = 1, numTraits do
@@ -61,13 +113,41 @@ function LeoAltholic.HasStillResearchFor(craft, charName)
     end
 end

+function LeoAltholic.CharKnowsTrait(craft, line, trait, charName)
+    if not charName then charName = LeoAltholic.CharName end
+    local char = LeoAltholic.globalData.CharList[charName]
+    if not char then return end
+    if not char.research.done then return false end
+    if not char.research.done[craft] then return false end
+    if not char.research.done[craft][line] then return false end
+    if not char.research.done[craft][line][trait] then return false end
+    return true
+end
+
+function LeoAltholic.GetNumTraitKnownPerLine(charName)
+    local levels = {}
+    for _,craft in pairs(LeoAltholic.craftResearch) do
+        levels[craft] = {}
+        for line = 1, GetNumSmithingResearchLines(craft) do
+            levels[craft][line] = 0
+            local _, _, numTraits = GetSmithingResearchLineInfo(craft, line)
+            for trait = 1, numTraits do
+                if LeoAltholic.CharKnowsTrait(craft, line, trait, charName) then
+                    levels[craft][line] = levels[craft][line] + 1
+                end
+            end
+        end
+    end
+    return levels
+end
+
 --[[
 Return the number of researching in progress, the total and the time of the first one to be completed (can be 0 or negative,
   indicating it's done)
 ]]
 function LeoAltholic.GetResearchCounters(craft, charName)
-    local char
-    if not charName then char = LeoAltholic.globalData.CharList[LeoAltholic.CharName] end
+    if not charName then charName = LeoAltholic.CharName end
+    local char = LeoAltholic.globalData.CharList[charName]
     if not char then return end
     local lowest = -1
     if #char.research.doing[craft] > 0 then
@@ -78,13 +158,14 @@ function LeoAltholic.GetResearchCounters(craft, charName)
 end

 local function copy(obj, seen)
-    if type(obj) ~= 'table' then return obj end
+    return obj -- major performance boost ...
+    --[[if type(obj) ~= 'table' then return obj end
     if seen and seen[obj] then return seen[obj] end
     local s = seen or {}
     local res = setmetatable({}, getmetatable(obj))
     s[obj] = res
     for k, v in pairs(obj) do res[copy(k, s)] = copy(v, s) end
-    return res
+    return res]]
 end

 --[[