• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver
Resource icon

Release Endless Mana for MQ2Mage Update 2.0

Maybe I described my wish in an uncomprehensively manner.
As the last version is written in Lua, it could do an infinitive loop, waiting for the mage to get l,ow on mana, and than start to recover the mana.
As far as I could unterstand, actually 1 call of MM will do 1 cycle of manarecovering and than end its service for this time.
To have it work all amgic, you need somethiong else to start it again, once you get low on mana.

As Lua it can run contemporary with all else running, so it could be extendet by a main-loop waiting for the mana to get low.
 
I set up a react for it a long time ago (I think it monitors mana level and combat state). But if you want to have it monitor mana and kick off the cycle at that point, feel free to have a go at the changes. I'm in the middle of another project and really don't have the time to tackle this. As hellfyre eludes to, some sort of config file will be necessary to keep track of the mana level. And probably also one for whether to do the mana recovery while in combat (maybe even taking into account if doing this in a raid/mission vs normal group grinding).
 
has anyone got this to work when using Hunter Tank mode on your mage? For me it will not trigger the macro. When Mage gets to the low mana threshold he just sits and meds. Is this because of how Hunter Tank works?
 
It works but the React doesn't for me. I made a /mac mm button so when I need mana I hit the button, it pauses my MQ2Mage and does what it is supposed to do.
 
So I ended up using the Lua from rouneq
I've expanded this to account for Mages leveling 115 -> 120. Since neither MS XIV nor Gather Vigor are available until 120, those mages below still need MS XIII and Gather Potency. I've also encountered issues getting the MS spell to load (sometimes it won't and I have to do it manually). Lastly, I've also added all the elemental staffs and it'll use the first one it finds in inventory. There's a few other changes, but those should be seen as more of a cleanup. Sharing in case anyone else is interested. And num1 can take them to use going forward. Much of the additions are taken from other macros I use, so I can't claim credit for the basic ideas behind them. Just the tweaks for this particular usage.
and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
 
So I ended up using the LUA from rouneq

and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
Do you use MQ2Boxr? One of the first things the script does after verifying the operating environment is workable (i.e., initialization logic) is to use /squelch /docommand /boxr pause. Later followed by a /boxr unpause before ending. This should stop any macro/plugin activity while MM is doing the work.
 
No, I honestly never tried it. I will get it and see if it helps. Thanks Rouneq
 
So I ended up using the LUA from rouneq

and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
I can't seem to get the Lua from rouneq to work. Did you need to do any changes to that?
 
My Lua version. There is an issue if the "Gather" spell isn't available. Put in your lua folder. Extract into that folder (a couple files are put into lib).
I made some small changes on it, here is my version based on the Lua by @rouneq

[CODE lang="Lua" title="MM Brute Force"]--- @type Mq
local mq = require('mq')
local Note = require('lib.Note')

Note.prefix = 'MonsterMana'
Note.loglevel = 'info'

local workingStates = { Active=true, Cooldown=true, Resting=true, }
local MonsterSummoning
local MonsterSummoningSpell
local GatherMana
local GatherManaSpell
local ReclaimSet
local ReclaimItem
local RetryCount = 5
local MiscSpellGem = 7
local IsMemorizing = false

--[[ local function delay(timeout, condition)
if ((not timeout and not condition) or type(timeout) ~= "number") then
return
end

if (not condition) then
mq.delay(timeout)

return
end

local function predicate()
mq.doevents()

return condition()
end

mq.delay(timeout, predicate)
end ]]

local function CheckPlugin(plugin)
if (not mq.TLO.Plugin(plugin)()) then
mq.cmdf('/squelch /plugin %s noauto', plugin)
Note.Debug('\aw%s\ar not detected! \awThis script requires it! Loading ...', plugin)
end
end

local function ChooseAbility(set)
-- Create New spell holder as Outer if it doesn't already exist
local chosenSpell
local highestSpellLevel = 0

-- Iterate throught the spell set
for _, value in ipairs(set) do
Note.Debug('spell: %s', value)
local spellLevel = mq.TLO.Spell(value).Level()
Note.Debug('spellLevel: %s', spellLevel)
local spellRank = mq.TLO.Spell(value).RankName()
Note.Debug('spellRank: %s', spellRank)

-- Detect mispelled spells
if (not spellRank) then
Note.Info('\arSPELL NOT AVAILABLE: \ax%s', value)
-- If we can cast the spell and its in our book, see if we should use it
elseif (mq.TLO.Me.Book(spellRank)()) then
-- If it's higher than the spell we've already set, use it.
if (spellLevel > highestSpellLevel) then
-- This is the value we use for casting and buff checking so must be BaseName. RankName is only
-- for memorization and Me.Book checking.
if (mq.TLO.Me.SpellRankCap() > 1) then
chosenSpell = mq.TLO.Spell(spellRank).RankName()
else
chosenSpell = mq.TLO.Spell(spellRank).BaseName()
end

highestSpellLevel = spellLevel
end
end
end

Note.Debug('selected spell: %s', chosenSpell)

return chosenSpell
end

local function ChooseItem(set)
local reclaimItem

-- Iterate throught the staff set
for _, value in ipairs(set) do
if (mq.TLO.FindItemCount(value)()>0) then
reclaimItem = value

break
end
end

Note.Debug('reclaim item: %s', reclaimItem)

return reclaimItem
end

local function Init()
CheckPlugin('MQ2XAssist')
CheckPlugin('MQ2AdvPath')
CheckPlugin('MQ2MoveUtils')
CheckPlugin('MQ2Boxr')

MonsterSummoning = {
"Monster Summoning XV",
"Monster Summoning XIV",
"Monster Summoning XIII",
}

MonsterSummoningSpell = ChooseAbility(MonsterSummoning)

if (not MonsterSummoningSpell) then
Note.Info('A monster summoning spell is not available')

return false
end

GatherMana = {
"Gather Vigor",
"Gather Potency",
}

GatherManaSpell = ChooseAbility(GatherMana)

if (not GatherManaSpell) then
Note.Info('A gather mana spell is not available')

return false
end

-- There are multiple instant cast "Reclaim Energy" items, if yours is different, add to the set below.
ReclaimSet = {
"Staff of Elemental Mastery: Earth",
"Staff of Elemental Mastery: Fire",
"Staff of Elemental Mastery: Air",
"Staff of Elemental Mastery: Water",
"Broom of Trilon",
"Ancient Torch of Alna",
"Gemmed Gloves of Guile",
"Gloves of Dark Summoning",
"Shovel of Ponz",
"Stein of Ulissa",
"Torch of Alna"
}

ReclaimItem = ChooseItem(ReclaimSet)

if (not ReclaimItem) then
Note.Info('An item to reclaim energy is not present in inventory')

return false
end

return true
end

local function Event_BeginMemorizing(_, spellName)
IsMemorizing = true
end

local Event_EndMemorizing = function(_, spellName)
IsMemorizing = false
end

mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

local function LoadSpellGem(spellToMem, requestedMemGem)
if (mq.TLO.Me.Gem(spellToMem)()) then
Note.Debug('Requested spell "%s" is already in a gem slot. Returning that gem slot number instead', spellToMem)

return mq.TLO.Me.Gem(spellToMem)()
end

-- We want to pop out quickly if we're in combat or moving
if ( mq.TLO.AdvPath.Following() or
mq.TLO.MoveTo.Moving() or
mq.TLO.Me.Moving() or
-- mq.TLO.XAssist.XTFullHaterCount() > 0 or
mq.TLO.Navigation.Active()) then
Note.Info('Cannot mem a spell while moving')

return
end

-- Need to use RankName with Me.Book and /memspell
spellToMem = mq.TLO.Spell(spellToMem).RankName()

if (spellToMem == nil or spellToMem == '') then
Note.Info('Invalid spellToMem "%s"', spellToMem)

return
end

if (not mq.TLO.Me.Book(spellToMem)()) then
Note.Info('\awCould Not find the spell "%s" in the spell book.', spellToMem)

return
end

if (not mq.TLO.Me.Gem(requestedMemGem)() and requestedMemGem ~= MiscSpellGem) then
Note.Info('Requested gem slot, %s, is not available. Using default misc spell gem, %s, instead', requestedMemGem, MiscSpellGem)

requestedMemGem = MiscSpellGem
end

Note.Info('\agMeming \aw"%s" in \agslot %s', spellToMem, requestedMemGem)
mq.cmdf('/memspell %s "%s"', requestedMemGem, spellToMem)

-- Client settle delay to avoid getting stuck in loading spell gems.
mq.delay(2000, function()
--return mq.TLO.Window('SpellBookWnd').Open() and IsMemorizing
return IsMemorizing
end)

mq.delay(10000, function()
return mq.TLO.Me.Gem(requestedMemGem).Name() == spellToMem or not IsMemorizing
end)

if (mq.TLO.Me.Gem(requestedMemGem).Name() ~= spellToMem) then
--[[ if (mq.TLO.XAssist.XTFullHaterCount() > 0) then
Note.Info('I was interruped by combat while waiting to memorize ${spellToMem}.')

return
end ]]

if (not mq.TLO.Window('SpellBookWnd').Open()) then
Note.Info('My Spellbook Window closed while I tried to memorize a spell.')

return
end
end

return requestedMemGem
end

local function ReclaimMana()
Note.Info('Mana Loop Started')
mq.cmd('/squelch /beepontells off')
while (mq.TLO.Me.PctMana() < 90) do
if (mq.TLO.Cursor.ID()) then
mq.cmd('/autoinventory')
mq.delay(2000)
mq.cmd('/autoinventory')
end

-- move to MA

if mq.TLO.Group.MainAssist() and mq.TLO.Group.MainAssist.Distance() > 40 then
mq.cmdf('/squelch /nav id %s',mq.TLO.Group.MainAssist.ID())
Note.Info('Catching up with MA')
while mq.TLO.Navigation.Active() do mq.delay(100) end
mq.delay(500)
end

-- Checking if mana is under 8%
if (mq.TLO.Me.PctMana() < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)()) then
mq.cmdf('/cast "%s"', GatherManaSpell)
mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)
elseif (mq.TLO.Me.CurrentMana() < mq.TLO.Spell(MonsterSummoningSpell).Mana()) then
-- Sitting
if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
mq.TLO.Me.Sit()
end

mq.delay(6050)
else
if (mq.TLO.Me.Sitting()) then
mq.TLO.Me.Stand()
end

mq.delay(1000)

Note.Debug('Request load spell "%s" to gem %s', MonsterSummoningSpell, MiscSpellGem)
local actualSpellGem = LoadSpellGem(MonsterSummoningSpell, MiscSpellGem)

if (not actualSpellGem) then
Note.Info('Requested spell load failed...exting')

return
end

mq.delay(500)

if (mq.TLO.Me.SpellReady(MonsterSummoningSpell)()) then
mq.cmdf('/cast %s', actualSpellGem)
end

mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(500)
if (mq.TLO.Me.Pet.ID() > 0) then
mq.cmdf('/useitem %s', ReclaimItem)
end

mq.delay(500)
end
mq.delay(50)
end

mq.delay(1000)
Note.Info('Mana Loop Ended')
local counter = 0
while (mq.TLO.Me.Pet.ID() > 0 and counter < RetryCount) do
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
counter = counter + 1
end
end

local function Main()
if (mq.TLO.Me.Class.ShortName() ~= 'MAG') then
Note.Info('MonsterMana only works for Mage characters')

return false
end

if (mq.TLO.Me.PctMana() > 95) then
Note.Info('Mana is nearly full; nothing to do')

return false
end

-- Sets up the operational domain including which version of monster to summon, basic mana recovery spell to use (if low on mana), and reclaim item to use from inventory
if (not Init()) then
Note.Info('Macro initialization unsuccessful')

return false
end

mq.cmd('/squelch /docommand /boxr pause')
mq.delay(300)
mq.cmd('/squelch /attack off')
-- added auto inventory
local counter = 0
while (mq.TLO.Cursor.ID() and counter < RetryCount) do
mq.cmd('/autoinventory')
mq.delay(500)
mq.cmd('/autoinventory')
counter = counter + 1
end

mq.delay(500)

-- Section for if you already have a main pet summoned.
if (mq.TLO.Me.Pet.ID() and mq.TLO.Me.Pet.ID() > 0) then
Note.Info('Primary mana method started (with pet)!')

-- Stores main pet using Suspend Companion to keep items/buffs on pet.
Note.Info('Storing Pet')
local counter = 0
while (mq.TLO.Me.Pet.ID() > 0 and counter < RetryCount) do
mq.cmd('/pet hold')
mq.delay(300)
mq.cmd('/pet back off')
mq.delay(300)
mq.cmd('/alt act 1215') --summon companion
mq.delay(500)
if (mq.TLO.Me.Pet.ID()> 0) then mq.cmd('/alt act 176') end -- suspend pet
mq.delay(500)
mq.delay(8000, function() return not mq.TLO.Me.Casting.ID() end)
counter = counter + 1
end

ReclaimMana()

-- Returns main pet from Suspend Companion
Note.Info('Restoring Main Pet')
local counter = 0
while (mq.TLO.Me.Pet.ID() == 0 and counter < RetryCount) do
Note.Info('resummon pet')
mq.delay(300)
mq.cmd('/alt act 176')
mq.delay(300)
mq.delay(6000, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)
counter = counter + 1
end
-- Secondary method for if you reciently died, have 0 mana and no main pet.
else
Note.Info('Primary mana method started (no pet)!')
mq.delay(300)

while (mq.TLO.Me.PctMana() < 8) do
if (mq.TLO.Me.SpellReady(mq.TLO.Spell(GatherManaSpell).RankName())) then
mq.cmdf('/cast "%s"', mq.TLO.Spell(GatherManaSpell).RankName())
mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
elseif (workingStates[mq.TLO.Me.CombatState()]) then
-- Sitting
if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
mq.TLO.Me.Sit()
end

mq.delay(6050)
end
mq.delay(200)
end

ReclaimMana()
end

mq.delay(300)
mq.cmd('/pet hold')
mq.delay(300)
mq.cmd('/squelch /docommand /boxr unpause')
mq.delay(300)
Note.Info('Mana Macro Ending')
Note.Info('Mage Mana now: \ag%s', mq.TLO.Me.PctMana())
mq.cmd('/squelch /beepontells on')
end

Main()[/CODE]

Also here is a LEM to trigger it:

cmV0dXJuIHsKIFsibmFtZSJdID0gIk1hZ2VNYW5hQnJ1dGVmb3JjZSIsCiBbImxvYWQiXSA9IHsKICBbInpvbmUiXSA9ICIiLAogIFsiY2xhc3MiXSA9ICIiLAogIFsiYWx3YXlzIl0gPSBmYWxzZSwKIH0sCiBbInR5cGUiXSA9ICJjb25kaXRpb25zIiwKIFsiY29kZSJdID0gImJHOWpZV3dnYlhFZ1BTQnlaWEYxYVhKbEtDZHRjU2NwQ2dvdExTMUFjbVYwZFhKdUlHSnZiMnhsWVc0Z1FGSmxkSFZ5Ym5NZ2RISjFaU0JwWmlCMGFHVWdZV04wYVc5dUlITm9iM1ZzWkNCbWFYSmxMQ0J2ZEdobGNuZHBjMlVnWm1Gc2MyVXVDbXh2WTJGc0lHWjFibU4wYVc5dUlHTnZibVJwZEdsdmJpZ3BDaUFnSUNCc2IyTmhiQ0J0ZVY5amJHRnpjeUE5SUcxeExsUk1UeTVOWlM1RGJHRnpjeTVUYUc5eWRFNWhiV1VvS1FvZ0lDQWdiRzlqWVd3Z2JYbGZiV0Z1WVNBOUlHMXhMbFJNVHk1TlpTNVFZM1JOWVc1aEtDa0tJQ0FnSUd4dlkyRnNJR05vWldOclgzQmhkWE5sWkNBOUlHMXhMbFJNVHk1RFYxUk9MbEJoZFhObFpDZ3BDaUFnSUNCc2IyTmhiQ0J0YlY5emRHRjBkWE1nUFNCdGNTNVVURTh1VEhWaExsTmpjbWx3ZENnblRVMWljblYwWlNjcExsTjBZWFIxY3lncENpQWdJQ0J5WlhSMWNtNGdiWGxmWTJ4aGMzTWdQVDBnSjAxQlJ5Y2dZVzVrSUcxNVgyMWhibUVnUENBeU1DQmhibVFnYlcxZmMzUmhkSFZ6SUg0OUlDZFNWVTVPU1U1SEp5QmhibVFnWTJobFkydGZjR0YxYzJWa0lEMDlJR1poYkhObENtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdZV04wYVc5dUtDa0tJQ0FnSUcxeExtTnRaQ2duTDJ4MVlTQnlkVzRnVFUxaWNuVjBaU2NwQ21WdVpBb0tjbVYwZFhKdUlIdGpiMjVrWm5WdVl6MWpiMjVrYVhScGIyNHNJR0ZqZEdsdmJtWjFibU05WVdOMGFXOXVmUT09IiwKIFsiY2F0ZWdvcnkiXSA9ICJncmluZCIsCn0=
 

Attachments

I may have to just do I don't feel left out. My Druid doesn't even have mana problems. My FTP Druid. I'm serious.
Then they are underperforming what they are capable of or you are pulling 1 mob and have downtime between mobs. There's no way if those toons are pushing they are staying at 80%+ mana indeffinently.
 
Then they are underperforming what they are capable of or you are pulling 1 mob and have downtime between mobs. There's no way if those toons are pushing they are staying at 80%+ mana indeffinently.
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
 
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
Are you talking going through one mission and then dropping and medding or are you talking grind?
 
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
@RobRenfro my mages ftp or normal are usually tapped for mana no matter what…you need to nuke, pet swarm, and of many spell line constantly. You also need to learn to pull swarms (3+) mobs per pull so theres always something waiting to be hit and to fully utilize your enc or bard fully and to reduce downtime.

Rgmerc chain pull with ranger ranged is amazing if your tank plugin isn’t handling swarm pulls well. Give it a go you’ll see…this routine/Lua is amazing at reducing downtime and increasing dps output
 
I don't have 3 rezzers in my primary group because I under pull and at least 2 in every other group.
What do rezzers have to do with anything? Modern tanks even with auto as long as they are geared/aad for the content you are in can handle 3+ no mez
 
I have 3 rezzers because I pull hard Louis Roberts hard. I'll sink your battleship then I'm going after the kayaker and your uncle's fishing canoe pulling. So I have 3 toons to save my bacon if I slide off the razor's edge.
 
I have done exactly as the instructions stated but i still cant get this to work. Mage just stays OOM. any advice on how to fix? thank you
 
I've been away for awhile however I recently started playing again. Rather then having external Lua's and macros I integrated things into a LEM alone. I also added in where it will CotH ourselves to wipe agro as for some reason if we are in combat even after summoning pet it was not suspending. This is an early release of the LEM but any feedback is welcome.

Here is code:
[CODE lang="Lua" title="Endless Mana LEM"]local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
local my_class = mq.TLO.Me.Class.ShortName()
local my_mana = mq.TLO.Me.PctMana()
local check_paused = mq.TLO.CWTN.Paused()
local mm_status = mq.TLO.Lua.Script('MMbrute').Status()
return my_class == 'MAG' and my_mana < 20 and mm_status ~= 'RUNNING' and check_paused == false
end

-----------------------------------------------------------------------
-- Everything below runs inside LEM's action() when the condition is met
-----------------------------------------------------------------------

-- Lightweight logger (self-contained)
local Note = { prefix = 'MonsterMana', loglevel = 'info' }
function Note.Info(fmt, ...) print(('\ag[%s]\ax '..fmt):format(Note.prefix, ...)) end

-- State / config
local workingStates = { Active=true, Cooldown=true, Resting=true }
local MonsterSummoning, MonsterSummoningSpell
local GatherMana, GatherManaSpell
local ReclaimSet, ReclaimItem
local MiscSpellGem = 8 -- using gem 8
local IsMemorizing = false

-- -----------------------------
-- Helpers
-- -----------------------------
local function CheckPlugin(plugin)
if not mq.TLO.Plugin(plugin)() then
mq.cmdf('/squelch /plugin %s noauto', plugin)
Note.Info('\aw%s\ax not detected. Loading…', plugin)
end
end

-- Simple movement check: only your avatar’s motion.
local function IsMoving()
return mq.TLO.Me.Moving() or ((mq.TLO.Me.Speed() or 0) > 0)
end

-- Wait until we’ve been NOT moving for a continuous window (ms). No attempt limit.
local function WaitStill(min_ms)
min_ms = min_ms or 400
local stillStart = nil
while true do
if IsMoving() then
stillStart = nil
else
stillStart = stillStart or mq.gettime()
if (mq.gettime() - stillStart) >= min_ms then return true end
end
mq.delay(50)
end
end

-- Robust “am I in combat?” check
local function InCombat()
local cs = tostring(mq.TLO.Me.CombatState() or '')
if cs ~= '' and cs:upper() == 'COMBAT' then return true end
if mq.TLO.Me.Combat and mq.TLO.Me.Combat() then return true end
return false
end

local function ChooseAbility(set)
local chosenSpell, highestLevel = nil, 0
for _, name in ipairs(set) do
local s = mq.TLO.Spell(name)
local lvl, rank = s.Level(), s.RankName()
if rank and mq.TLO.Me.Book(rank)() and lvl > highestLevel then
chosenSpell = (mq.TLO.Me.SpellRankCap() > 1) and s.RankName() or s.BaseName()
highestLevel = lvl
end
end
return chosenSpell
end

local function ChooseItem(set)
for _, name in ipairs(set) do
if mq.TLO.FindItemCount(name)() > 0 then return name end
end
end

-- Spellbook events (registered inside action())
local function Event_BeginMemorizing(_, _) IsMemorizing = true end
local function Event_EndMemorizing(_, _) IsMemorizing = false end

-- Ensure spell is in a specific gem (blocking, no attempt limit). Only starts when stationary.
local function EnsureSpellInGem(spellToMem, gem)
gem = gem or MiscSpellGem
while true do
if mq.TLO.Me.Gem(spellToMem)() == gem then return gem end
local rn = mq.TLO.Spell(spellToMem).RankName()
if not rn or not mq.TLO.Me.Book(rn)() then
Note.Info('Cannot memorize (not in book): %s', tostring(spellToMem))
return
end
if not mq.TLO.Me.Gem(gem)() and gem ~= MiscSpellGem then gem = MiscSpellGem end
WaitStill(600)
Note.Info('\agMemming\ax "%s" into gem %d', rn, gem)
mq.cmdf('/memspell %d "%s"', gem, rn)
mq.delay(2000, function() return IsMemorizing or mq.TLO.Me.Gem(gem).Name() == rn end)
mq.delay(10000, function() return mq.TLO.Me.Gem(gem).Name() == rn or not IsMemorizing end)
if mq.TLO.Me.Gem(gem).Name() == rn then return gem end
end
end

-- Pet proximity helpers (with optional timeout to prevent hangs)
local function PetNear(maxDist) return (mq.TLO.Me.Pet.Distance() or 9999) <= (maxDist or 12) end
local function WaitPetNear(maxDist, timeout_ms)
maxDist = maxDist or 12
local start = mq.gettime()
while true do
if (mq.TLO.Me.Pet.ID() or 0) == 0 then return false end
if PetNear(maxDist) then return true end
if timeout_ms and (mq.gettime() - start) >= timeout_ms then return PetNear(maxDist) end
mq.delay(50)
end
end

-- Suspend pet with full sequence every pass.
-- Now: only use CoTH AA (7050) if we are IN COMBAT.
local function SuspendPrimaryPet_Blocking()
local origID = mq.TLO.Me.Pet.ID() or 0
if origID == 0 then return true end
Note.Info('Storing Pet (ID %s)', tostring(origID))

while (mq.TLO.Me.Pet.ID() or 0) > 0 do
-- Full sequence: ghold -> spellhold -> hold/back -> Summon Companion (1215) -> (CoTH if IN COMBAT) -> suspend
WaitStill(400)
mq.cmd('/pet ghold on') ; mq.delay(300)
mq.cmd('/pet spellhold on'); mq.delay(300)
mq.cmd('/pet back') ; mq.delay(300)

-- Summon Companion RIGHT BEFORE suspending, if ready (don’t block for CD)
if mq.TLO.Me.AltAbilityReady(1215)() or mq.TLO.Me.AltAbilityReady('Summon Companion')() then
WaitStill(300)
mq.cmd('/alt act 1215')
mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
WaitPetNear(12, 3000)
end

-- NEW: Only do CoTH if we are actually in combat
if InCombat() and mq.TLO.Me.AltAbilityReady(7050)() then
WaitStill(300)
mq.cmdf('/target id %d', mq.TLO.Me.ID() or 0)
mq.delay(200)
Note.Info('Using CoTH AA to wipe personal aggro (in combat).')
mq.cmd('/alt act 7050')
mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
end

-- Attempt to suspend
WaitStill(400)
if mq.TLO.Me.AltAbilityReady(176)() or mq.TLO.Me.AltAbilityReady('Suspend Minion')() then
Note.Info('Suspending Minion…')
mq.cmd('/alt act 176')
mq.delay(500)
mq.delay(3000, function() return not mq.TLO.Me.Casting.ID() end)
end

-- Success?
if (mq.TLO.Me.Pet.ID() or 0) == 0 then
Note.Info('Pet suspended.')
return true
end

-- Redo the entire sequence until success.
mq.delay(200)
end

return true
end

-- Core mana loop: summon monster pet (gem 8) & reclaim until 95% mana.
local function ReclaimMana()
Note.Info('Mana Loop Started')
mq.cmd('/squelch /beepontells off')

while (mq.TLO.Me.PctMana() or 100) < 95 do
if mq.TLO.Cursor.ID() then
mq.cmd('/autoinventory')
mq.delay(2000)
mq.cmd('/autoinventory')
end

if (mq.TLO.Me.PctMana() or 100) < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)() then
WaitStill(400)
mq.cmdf('/cast "%s"', GatherManaSpell)
mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)

elseif (mq.TLO.Me.CurrentMana() or 0) < (mq.TLO.Spell(MonsterSummoningSpell).Mana() or 0) then
if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
mq.delay(6050)

else
if mq.TLO.Me.Sitting() then mq.TLO.Me.Stand() end
mq.delay(250)

-- Ensure spell in gem 8
local actualGem = EnsureSpellInGem(MonsterSummoningSpell, MiscSpellGem)
if not actualGem then
Note.Info('Could not load Monster Summoning into gem %d; exiting mana loop.', MiscSpellGem)
break
end

-- Cast Monster Summoning
WaitStill(400)
if mq.TLO.Me.SpellReady(MonsterSummoningSpell)() then
mq.cmdf('/cast %d', actualGem)
end
mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)

-- Reclaim immediately if a pet is up
if (mq.TLO.Me.Pet.ID() or 0) > 0 and ReclaimItem then
WaitStill(200)
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
end
end

mq.delay(50)
end

Note.Info('Mana Loop Ended')
-- final cleanup: if temp pet still up, reclaim until gone
while (mq.TLO.Me.Pet.ID() or 0) > 0 do
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
end
end

-- Init spells/items
local function Init()
CheckPlugin('MQ2XAssist')
CheckPlugin('MQ2AdvPath')
CheckPlugin('MQ2MoveUtils')
CheckPlugin('MQ2Boxr')

MonsterSummoning = {
"Monster Summoning XV",
"Monster Summoning XIV",
"Monster Summoning XIII",
}
MonsterSummoningSpell = ChooseAbility(MonsterSummoning)
if not MonsterSummoningSpell then
Note.Info('A monster summoning spell is not available')
return false
end

-- Updated Gather line (includes level 125)
GatherMana = {
"Gather Zeal",
"Gather Vigor",
"Gather Potency",
}
GatherManaSpell = ChooseAbility(GatherMana)
if not GatherManaSpell then
Note.Info('A gather mana spell is not available')
return false
end

ReclaimSet = {
"Staff of Elemental Mastery: Earth",
"Staff of Elemental Mastery: Fire",
"Staff of Elemental Mastery: Air",
"Staff of Elemental Mastery: Water",
"Broom of Trilon",
"Ancient Torch of Alna",
"Gemmed Gloves of Guile",
"Gloves of Dark Summoning",
"Shovel of Ponz",
"Stein of Ulissa",
"Torch of Alna",
}
ReclaimItem = ChooseItem(ReclaimSet)
if not ReclaimItem then
Note.Info('No reclaim item found in inventory')
return false
end

return true
end

-- Main routine (merged into LEM action)
local function RunMonsterMana()
if mq.TLO.Me.Class.ShortName() ~= 'MAG' then
Note.Info('MonsterMana only works for Mage characters')
return false
end
if (mq.TLO.Me.PctMana() or 100) > 95 then
Note.Info('Mana is nearly full; nothing to do')
return false
end
if not Init() then
Note.Info('Initialization unsuccessful')
return false
end

mq.cmd('/squelch /docommand /boxr pause')
mq.delay(300)
mq.cmd('/squelch /attack off')

-- clear cursor
while mq.TLO.Cursor.ID() do
mq.cmd('/autoinventory')
mq.delay(500)
end

-- If we already have a main pet, suspend it FIRST (blocking)
if (mq.TLO.Me.Pet.ID() or 0) > 0 then
Note.Info('Primary mana method (with pet)')
if not SuspendPrimaryPet_Blocking() then
Note.Info('Unable to suspend pet safely; aborting.')
mq.cmd('/squelch /docommand /boxr unpause')
return false
end
else
-- No-pet fallback: build to 8% with Gather or sitting
Note.Info('Primary mana method (no pet)')
while (mq.TLO.Me.PctMana() or 0) < 8 do
local rankName = mq.TLO.Spell(GatherManaSpell).RankName()
if mq.TLO.Me.SpellReady(rankName)() then
WaitStill(400)
mq.cmdf('/cast "%s"', rankName)
mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
elseif workingStates[mq.TLO.Me.CombatState() or ''] then
if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
mq.delay(6050)
end
mq.delay(150)
end
end

-- Run mana loop (summon/reclaim)
ReclaimMana()

-- Try to restore main pet (unsuspend). Loop until a non-Warrior pet (i.e., your real elemental) returns.
Note.Info('Restoring main pet (unsuspending)')
while (mq.TLO.Me.Pet.ID() or 0) == 0 do
WaitStill(400)
mq.cmd('/alt act 176')
mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)
end
-- If a Monster Summoning warrior pet popped instead, reclaim and try again.
while (mq.TLO.Me.Pet.Class.Name() or '') == 'Warrior' do
if ReclaimItem then
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
else
break
end
while (mq.TLO.Me.Pet.ID() or 0) == 0 do
WaitStill(400)
mq.cmd('/alt act 176')
mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)
end
end

mq.delay(300)
mq.cmd('/pet hold')
mq.delay(300)
mq.cmd('/squelch /docommand /boxr unpause')
mq.delay(300)
Note.Info('Mana routine complete. Mage mana now: \ag%s', tostring(mq.TLO.Me.PctMana()))
mq.cmd('/squelch /beepontells on')
return true
end

local function action()
-- Register spellbook events (LEM-safe)
mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

local ok, err = pcall(RunMonsterMana)
if not ok then Note.Info('\arError:\ax %s', tostring(err)) end
end

return {condfunc=condition, actionfunc=action}[/CODE]

LEM import code:
cmV0dXJuIHsKIFsibmFtZSJdID0gIk1hZ2UgLSBFbmRsZXNzIE1hbmEiLAogWyJsb2FkIl0gPSB7CiAgWyJhbHdheXMiXSA9IGZhbHNlLAogIFsiem9uZSJdID0gIiIsCiAgWyJjbGFzcyJdID0gIiIsCiB9LAogWyJjb2RlIl0gPSAiYkc5allXd2diWEVnUFNCeVpYRjFhWEpsS0NkdGNTY3BDZ290TFMxQWNtVjBkWEp1SUdKdmIyeGxZVzRnUUZKbGRIVnlibk1nZEhKMVpTQnBaaUIwYUdVZ1lXTjBhVzl1SUhOb2IzVnNaQ0JtYVhKbExDQnZkR2hsY25kcGMyVWdabUZzYzJVdUNteHZZMkZzSUdaMWJtTjBhVzl1SUdOdmJtUnBkR2x2YmlncENpQWdJQ0JzYjJOaGJDQnRlVjlqYkdGemN5QTlJRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LUW9nSUNBZ2JHOWpZV3dnYlhsZmJXRnVZU0E5SUcxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrS0lDQWdJR3h2WTJGc0lHTm9aV05yWDNCaGRYTmxaQ0E5SUcxeExsUk1UeTVEVjFST0xsQmhkWE5sWkNncENpQWdJQ0JzYjJOaGJDQnRiVjl6ZEdGMGRYTWdQU0J0Y1M1VVRFOHVUSFZoTGxOamNtbHdkQ2duVFUxaWNuVjBaU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F5TUNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISnlCaGJtUWdZMmhsWTJ0ZmNHRjFjMlZrSUQwOUlHWmhiSE5sQ21WdVpBb0tMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMEtMUzBnUlhabGNubDBhR2x1WnlCaVpXeHZkeUJ5ZFc1eklHbHVjMmxrWlNCTVJVMG5jeUJoWTNScGIyNG9LU0IzYUdWdUlIUm9aU0JqYjI1a2FYUnBiMjRnYVhNZ2JXVjBDaTB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRDZ290TFNCTWFXZG9kSGRsYVdkb2RDQnNiMmRuWlhJZ0tITmxiR1l0WTI5dWRHRnBibVZrS1Fwc2IyTmhiQ0JPYjNSbElEMGdleUJ3Y21WbWFYZ2dQU0FuVFc5dWMzUmxjazFoYm1FbkxDQnNiMmRzWlhabGJDQTlJQ2RwYm1adkp5QjlDbVoxYm1OMGFXOXVJRTV2ZEdVdVNXNW1ieWhtYlhRc0lDNHVMaWtnY0hKcGJuUW9LQ2RjWVdkYkpYTmRYR0Y0SUNjdUxtWnRkQ2s2Wm05eWJXRjBLRTV2ZEdVdWNISmxabWw0TENBdUxpNHBLU0JsYm1RS0NpMHRJRk4wWVhSbElDOGdZMjl1Wm1sbkNteHZZMkZzSUhkdmNtdHBibWRUZEdGMFpYTWdQU0I3SUVGamRHbDJaVDEwY25WbExDQkRiMjlzWkc5M2JqMTBjblZsTENCU1pYTjBhVzVuUFhSeWRXVWdmUXBzYjJOaGJDQk5iMjV6ZEdWeVUzVnRiVzl1YVc1bkxDQk5iMjV6ZEdWeVUzVnRiVzl1YVc1blUzQmxiR3dLYkc5allXd2dSMkYwYUdWeVRXRnVZU3dnUjJGMGFHVnlUV0Z1WVZOd1pXeHNDbXh2WTJGc0lGSmxZMnhoYVcxVFpYUXNJRkpsWTJ4aGFXMUpkR1Z0Q214dlkyRnNJRTFwYzJOVGNHVnNiRWRsYlNBOUlEZ2dMUzBnZFhOcGJtY2daMlZ0SURnS2JHOWpZV3dnU1hOTlpXMXZjbWw2YVc1bklEMGdabUZzYzJVS0NpMHRJQzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0Q2kwdElFaGxiSEJsY25NS0xTMGdMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzBLYkc5allXd2dablZ1WTNScGIyNGdRMmhsWTJ0UWJIVm5hVzRvY0d4MVoybHVLUW9nSUNBZ2FXWWdibTkwSUcxeExsUk1UeTVRYkhWbmFXNG9jR3gxWjJsdUtTZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCdGNTNWpiV1JtS0NjdmMzRjFaV3hqYUNBdmNHeDFaMmx1SUNWeklHNXZZWFYwYnljc0lIQnNkV2RwYmlrS0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0oxeGhkeVZ6WEdGNElHNXZkQ0JrWlhSbFkzUmxaQzRnVEc5aFpHbHVaK0tBcGljc0lIQnNkV2RwYmlrS0lDQWdJR1Z1WkFwbGJtUUtDaTB0SUZOcGJYQnNaU0J0YjNabGJXVnVkQ0JqYUdWamF6b2diMjVzZVNCNWIzVnlJR0YyWVhSaGN1S0FtWE1nYlc5MGFXOXVMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQkpjMDF2ZG1sdVp5Z3BDaUFnSUNCeVpYUjFjbTRnYlhFdVZFeFBMazFsTGsxdmRtbHVaeWdwSUc5eUlDZ29iWEV1VkV4UExrMWxMbE53WldWa0tDa2diM0lnTUNrZ1BpQXdLUXBsYm1RS0NpMHRJRmRoYVhRZ2RXNTBhV3dnZDJYaWdKbDJaU0JpWldWdUlFNVBWQ0J0YjNacGJtY2dabTl5SUdFZ1kyOXVkR2x1ZFc5MWN5QjNhVzVrYjNjZ0tHMXpLUzRnVG04Z1lYUjBaVzF3ZENCc2FXMXBkQzRLYkc5allXd2dablZ1WTNScGIyNGdWMkZwZEZOMGFXeHNLRzFwYmw5dGN5a0tJQ0FnSUcxcGJsOXRjeUE5SUcxcGJsOXRjeUJ2Y2lBME1EQUtJQ0FnSUd4dlkyRnNJSE4wYVd4c1UzUmhjblFnUFNCdWFXd0tJQ0FnSUhkb2FXeGxJSFJ5ZFdVZ1pHOEtJQ0FnSUNBZ0lDQnBaaUJKYzAxdmRtbHVaeWdwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYzNScGJHeFRkR0Z5ZENBOUlHNXBiQW9nSUNBZ0lDQWdJR1ZzYzJVS0lDQWdJQ0FnSUNBZ0lDQWdjM1JwYkd4VGRHRnlkQ0E5SUhOMGFXeHNVM1JoY25RZ2IzSWdiWEV1WjJWMGRHbHRaU2dwQ2lBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2h0Y1M1blpYUjBhVzFsS0NrZ0xTQnpkR2xzYkZOMFlYSjBLU0ErUFNCdGFXNWZiWE1nZEdobGJpQnlaWFIxY200Z2RISjFaU0JsYm1RS0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRkp2WW5WemRDRGlnSnhoYlNCSklHbHVJR052YldKaGREL2lnSjBnWTJobFkyc0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1NXNURiMjFpWVhRb0tRb2dJQ0FnYkc5allXd2dZM01nUFNCMGIzTjBjbWx1WnlodGNTNVVURTh1VFdVdVEyOXRZbUYwVTNSaGRHVW9LU0J2Y2lBbkp5a0tJQ0FnSUdsbUlHTnpJSDQ5SUNjbklHRnVaQ0JqY3pwMWNIQmxjaWdwSUQwOUlDZERUMDFDUVZRbklIUm9aVzRnY21WMGRYSnVJSFJ5ZFdVZ1pXNWtDaUFnSUNCcFppQnRjUzVVVEU4dVRXVXVRMjl0WW1GMElHRnVaQ0J0Y1M1VVRFOHVUV1V1UTI5dFltRjBLQ2tnZEdobGJpQnlaWFIxY200Z2RISjFaU0JsYm1RS0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlFTm9iMjl6WlVGaWFXeHBkSGtvYzJWMEtRb2dJQ0FnYkc5allXd2dZMmh2YzJWdVUzQmxiR3dzSUdocFoyaGxjM1JNWlhabGJDQTlJRzVwYkN3Z01Bb2dJQ0FnWm05eUlGOHNJRzVoYldVZ2FXNGdhWEJoYVhKektITmxkQ2tnWkc4S0lDQWdJQ0FnSUNCc2IyTmhiQ0J6SUQwZ2JYRXVWRXhQTGxOd1pXeHNLRzVoYldVcENpQWdJQ0FnSUNBZ2JHOWpZV3dnYkhac0xDQnlZVzVySUQwZ2N5NU1aWFpsYkNncExDQnpMbEpoYm10T1lXMWxLQ2tLSUNBZ0lDQWdJQ0JwWmlCeVlXNXJJR0Z1WkNCdGNTNVVURTh1VFdVdVFtOXZheWh5WVc1cktTZ3BJR0Z1WkNCc2Rtd2dQaUJvYVdkb1pYTjBUR1YyWld3Z2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCamFHOXpaVzVUY0dWc2JDQTlJQ2h0Y1M1VVRFOHVUV1V1VTNCbGJHeFNZVzVyUTJGd0tDa2dQaUF4S1NCaGJtUWdjeTVTWVc1clRtRnRaU2dwSUc5eUlITXVRbUZ6WlU1aGJXVW9LUW9nSUNBZ0lDQWdJQ0FnSUNCb2FXZG9aWE4wVEdWMlpXd2dQU0JzZG13S0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUdWdVpBb2dJQ0FnY21WMGRYSnVJR05vYjNObGJsTndaV3hzQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1EyaHZiM05sU1hSbGJTaHpaWFFwQ2lBZ0lDQm1iM0lnWHl3Z2JtRnRaU0JwYmlCcGNHRnBjbk1vYzJWMEtTQmtid29nSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVHYVc1a1NYUmxiVU52ZFc1MEtHNWhiV1VwS0NrZ1BpQXdJSFJvWlc0Z2NtVjBkWEp1SUc1aGJXVWdaVzVrQ2lBZ0lDQmxibVFLWlc1a0Nnb3RMU0JUY0dWc2JHSnZiMnNnWlhabGJuUnpJQ2h5WldkcGMzUmxjbVZrSUdsdWMybGtaU0JoWTNScGIyNG9LU2tLYkc5allXd2dablZ1WTNScGIyNGdSWFpsYm5SZlFtVm5hVzVOWlcxdmNtbDZhVzVuS0Y4c0lGOHBJRWx6VFdWdGIzSnBlbWx1WnlBOUlIUnlkV1VnWlc1a0NteHZZMkZzSUdaMWJtTjBhVzl1SUVWMlpXNTBYMFZ1WkUxbGJXOXlhWHBwYm1jb1h5d2dYeWtnU1hOTlpXMXZjbWw2YVc1bklEMGdabUZzYzJVZ1pXNWtDZ290TFNCRmJuTjFjbVVnYzNCbGJHd2dhWE1nYVc0Z1lTQnpjR1ZqYVdacFl5Qm5aVzBnS0dKc2IyTnJhVzVuTENCdWJ5QmhkSFJsYlhCMElHeHBiV2wwS1M0Z1QyNXNlU0J6ZEdGeWRITWdkMmhsYmlCemRHRjBhVzl1WVhKNUxncHNiMk5oYkNCbWRXNWpkR2x2YmlCRmJuTjFjbVZUY0dWc2JFbHVSMlZ0S0hOd1pXeHNWRzlOWlcwc0lHZGxiU2tLSUNBZ0lHZGxiU0E5SUdkbGJTQnZjaUJOYVhOalUzQmxiR3hIWlcwS0lDQWdJSGRvYVd4bElIUnlkV1VnWkc4S0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVSMlZ0S0hOd1pXeHNWRzlOWlcwcEtDa2dQVDBnWjJWdElIUm9aVzRnY21WMGRYSnVJR2RsYlNCbGJtUUtJQ0FnSUNBZ0lDQnNiMk5oYkNCeWJpQTlJRzF4TGxSTVR5NVRjR1ZzYkNoemNHVnNiRlJ2VFdWdEtTNVNZVzVyVG1GdFpTZ3BDaUFnSUNBZ0lDQWdhV1lnYm05MElISnVJRzl5SUc1dmRDQnRjUzVVVEU4dVRXVXVRbTl2YXloeWJpa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUTJGdWJtOTBJRzFsYlc5eWFYcGxJQ2h1YjNRZ2FXNGdZbTl2YXlrNklDVnpKeXdnZEc5emRISnBibWNvYzNCbGJHeFViMDFsYlNrcENpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJnb2dJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJR2xtSUc1dmRDQnRjUzVVVEU4dVRXVXVSMlZ0S0dkbGJTa29LU0JoYm1RZ1oyVnRJSDQ5SUUxcGMyTlRjR1ZzYkVkbGJTQjBhR1Z1SUdkbGJTQTlJRTFwYzJOVGNHVnNiRWRsYlNCbGJtUUtJQ0FnSUNBZ0lDQlhZV2wwVTNScGJHd29OakF3S1FvZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblhHRm5UV1Z0YldsdVoxeGhlQ0FpSlhNaUlHbHVkRzhnWjJWdElDVmtKeXdnY200c0lHZGxiU2tLSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2YldWdGMzQmxiR3dnSldRZ0lpVnpJaWNzSUdkbGJTd2djbTRwQ2lBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdTWE5OWlcxdmNtbDZhVzVuSUc5eUlHMXhMbFJNVHk1TlpTNUhaVzBvWjJWdEtTNU9ZVzFsS0NrZ1BUMGdjbTRnWlc1a0tRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtERXdNREF3TENCbWRXNWpkR2x2YmlncElISmxkSFZ5YmlCdGNTNVVURTh1VFdVdVIyVnRLR2RsYlNrdVRtRnRaU2dwSUQwOUlISnVJRzl5SUc1dmRDQkpjMDFsYlc5eWFYcHBibWNnWlc1a0tRb2dJQ0FnSUNBZ0lHbG1JRzF4TGxSTVR5NU5aUzVIWlcwb1oyVnRLUzVPWVcxbEtDa2dQVDBnY200Z2RHaGxiaUJ5WlhSMWNtNGdaMlZ0SUdWdVpBb2dJQ0FnWlc1a0NtVnVaQW9LTFMwZ1VHVjBJSEJ5YjNocGJXbDBlU0JvWld4d1pYSnpJQ2gzYVhSb0lHOXdkR2x2Ym1Gc0lIUnBiV1Z2ZFhRZ2RHOGdjSEpsZG1WdWRDQm9ZVzVuY3lrS2JHOWpZV3dnWm5WdVkzUnBiMjRnVUdWMFRtVmhjaWh0WVhoRWFYTjBLU0J5WlhSMWNtNGdLRzF4TGxSTVR5NU5aUzVRWlhRdVJHbHpkR0Z1WTJVb0tTQnZjaUE1T1RrNUtTQThQU0FvYldGNFJHbHpkQ0J2Y2lBeE1pa2daVzVrQ214dlkyRnNJR1oxYm1OMGFXOXVJRmRoYVhSUVpYUk9aV0Z5S0cxaGVFUnBjM1FzSUhScGJXVnZkWFJmYlhNcENpQWdJQ0J0WVhoRWFYTjBJRDBnYldGNFJHbHpkQ0J2Y2lBeE1nb2dJQ0FnYkc5allXd2djM1JoY25RZ1BTQnRjUzVuWlhSMGFXMWxLQ2tLSUNBZ0lIZG9hV3hsSUhSeWRXVWdaRzhLSUNBZ0lDQWdJQ0JwWmlBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQwOUlEQWdkR2hsYmlCeVpYUjFjbTRnWm1Gc2MyVWdaVzVrQ2lBZ0lDQWdJQ0FnYVdZZ1VHVjBUbVZoY2lodFlYaEVhWE4wS1NCMGFHVnVJSEpsZEhWeWJpQjBjblZsSUdWdVpBb2dJQ0FnSUNBZ0lHbG1JSFJwYldWdmRYUmZiWE1nWVc1a0lDaHRjUzVuWlhSMGFXMWxLQ2tnTFNCemRHRnlkQ2tnUGowZ2RHbHRaVzkxZEY5dGN5QjBhR1Z1SUhKbGRIVnliaUJRWlhST1pXRnlLRzFoZUVScGMzUXBJR1Z1WkFvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd0tRb2dJQ0FnWlc1a0NtVnVaQW9LTFMwZ1UzVnpjR1Z1WkNCd1pYUWdkMmwwYUNCbWRXeHNJSE5sY1hWbGJtTmxJR1YyWlhKNUlIQmhjM011Q2kwdElFNXZkem9nYjI1c2VTQjFjMlVnUTI5VVNDQkJRU0FvTnpBMU1Da2dhV1lnZDJVZ1lYSmxJRWxPSUVOUFRVSkJWQzRLYkc5allXd2dablZ1WTNScGIyNGdVM1Z6Y0dWdVpGQnlhVzFoY25sUVpYUmZRbXh2WTJ0cGJtY29LUW9nSUNBZ2JHOWpZV3dnYjNKcFowbEVJRDBnYlhFdVZFeFBMazFsTGxCbGRDNUpSQ2dwSUc5eUlEQUtJQ0FnSUdsbUlHOXlhV2RKUkNBOVBTQXdJSFJvWlc0Z2NtVjBkWEp1SUhSeWRXVWdaVzVrQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMU4wYjNKcGJtY2dVR1YwSUNoSlJDQWxjeWtuTENCMGIzTjBjbWx1WnlodmNtbG5TVVFwS1FvS0lDQWdJSGRvYVd4bElDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR1J2Q2lBZ0lDQWdJQ0FnTFMwZ1JuVnNiQ0J6WlhGMVpXNWpaVG9nWjJodmJHUWdMVDRnYzNCbGJHeG9iMnhrSUMwK0lHaHZiR1F2WW1GamF5QXRQaUJUZFcxdGIyNGdRMjl0Y0dGdWFXOXVJQ2d4TWpFMUtTQXRQaUFvUTI5VVNDQnBaaUJKVGlCRFQwMUNRVlFwSUMwK0lITjFjM0JsYm1RS0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJRzF4TG1OdFpDZ25MM0JsZENCbmFHOXNaQ0J2YmljcElDQWdJRHNnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzQmxkQ0J6Y0dWc2JHaHZiR1FnYjI0bktUc2diWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNCbGRDQmlZV05ySnlrZ0lDQWdJQ0FnSURzZ2JYRXVaR1ZzWVhrb016QXdLUW9LSUNBZ0lDQWdJQ0F0TFNCVGRXMXRiMjRnUTI5dGNHRnVhVzl1SUZKSlIwaFVJRUpGUms5U1JTQnpkWE53Wlc1a2FXNW5MQ0JwWmlCeVpXRmtlU0FvWkc5dTRvQ1pkQ0JpYkc5amF5Qm1iM0lnUTBRcENpQWdJQ0FnSUNBZ2FXWWdiWEV1VkV4UExrMWxMa0ZzZEVGaWFXeHBkSGxTWldGa2VTZ3hNakUxS1NncElHOXlJRzF4TGxSTVR5NU5aUzVCYkhSQlltbHNhWFI1VW1WaFpIa29KMU4xYlcxdmJpQkRiMjF3WVc1cGIyNG5LU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RNd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVd4MElHRmpkQ0F4TWpFMUp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTXpVd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQlhZV2wwVUdWMFRtVmhjaWd4TWl3Z016QXdNQ2tLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdUa1ZYT2lCUGJteDVJR1J2SUVOdlZFZ2dhV1lnZDJVZ1lYSmxJR0ZqZEhWaGJHeDVJR2x1SUdOdmJXSmhkQW9nSUNBZ0lDQWdJR2xtSUVsdVEyOXRZbUYwS0NrZ1lXNWtJRzF4TGxSTVR5NU5aUzVCYkhSQlltbHNhWFI1VW1WaFpIa29OekExTUNrb0tTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lGZGhhWFJUZEdsc2JDZ3pNREFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OTBZWEpuWlhRZ2FXUWdKV1FuTENCdGNTNVVURTh1VFdVdVNVUW9LU0J2Y2lBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TURBcENpQWdJQ0FnSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVlhOcGJtY2dRMjlVU0NCQlFTQjBieUIzYVhCbElIQmxjbk52Ym1Gc0lHRm5aM0p2SUNocGJpQmpiMjFpWVhRcExpY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTnpBMU1DY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RNMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNCbGJtUUtDaUFnSUNBZ0lDQWdMUzBnUVhSMFpXMXdkQ0IwYnlCemRYTndaVzVrQ2lBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLREUzTmlrb0tTQnZjaUJ0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLQ2RUZFhOd1pXNWtJRTFwYm1sdmJpY3BLQ2tnZEdobGJnb2dJQ0FnSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFOMWMzQmxibVJwYm1jZ1RXbHVhVzl1NG9DbUp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVd4MElHRmpkQ0F4TnpZbktRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2cxTURBcENpQWdJQ0FnSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRE13TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UTJGemRHbHVaeTVKUkNncElHVnVaQ2tLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdVM1ZqWTJWemN6OEtJQ0FnSUNBZ0lDQnBaaUFvYlhFdVZFeFBMazFsTGxCbGRDNUpSQ2dwSUc5eUlEQXBJRDA5SURBZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0oxQmxkQ0J6ZFhOd1pXNWtaV1F1SnlrS0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIUnlkV1VLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdVbVZrYnlCMGFHVWdaVzUwYVhKbElITmxjWFZsYm1ObElIVnVkR2xzSUhOMVkyTmxjM011Q2lBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd0tRb2dJQ0FnWlc1a0Nnb2dJQ0FnY21WMGRYSnVJSFJ5ZFdVS1pXNWtDZ290TFNCRGIzSmxJRzFoYm1FZ2JHOXZjRG9nYzNWdGJXOXVJRzF2Ym5OMFpYSWdjR1YwSUNoblpXMGdPQ2tnSmlCeVpXTnNZV2x0SUhWdWRHbHNJRGsxSlNCdFlXNWhMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlNaV05zWVdsdFRXRnVZU2dwQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMDFoYm1FZ1RHOXZjQ0JUZEdGeWRHVmtKeWtLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wySmxaWEJ2Ym5SbGJHeHpJRzltWmljcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tnYjNJZ01UQXdLU0E4SURrMUlHUnZDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMa04xY25OdmNpNUpSQ2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVhWMGIybHVkbVZ1ZEc5eWVTY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJd01EQXBDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGMWRHOXBiblpsYm5SdmNua25LUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJqZEUxaGJtRW9LU0J2Y2lBeE1EQXBJRHdnT0NCaGJtUWdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvUjJGMGFHVnlUV0Z1WVZOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDJOaGMzUWdJaVZ6SWljc0lFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NakF3TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHMXhMbFJNVHk1TlpTNURZWE4wYVc1bkxrbEVLQ2tnUFQwZ2JtbHNJR1Z1WkNrS0NpQWdJQ0FnSUNBZ1pXeHpaV2xtSUNodGNTNVVURTh1VFdVdVEzVnljbVZ1ZEUxaGJtRW9LU0J2Y2lBd0tTQThJQ2h0Y1M1VVRFOHVVM0JsYkd3b1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLUzVOWVc1aEtDa2diM0lnTUNrZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVVM1JoYm1ScGJtY29LU0JoYm1RZ2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ2RHaGxiaUJ0Y1M1VVRFOHVUV1V1VTJsMEtDa2daVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2dvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExsTnBkSFJwYm1jb0tTQjBhR1Z1SUcxeExsUk1UeTVOWlM1VGRHRnVaQ2dwSUdWdVpBb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TlRBcENnb2dJQ0FnSUNBZ0lDQWdJQ0F0TFNCRmJuTjFjbVVnYzNCbGJHd2dhVzRnWjJWdElEZ0tJQ0FnSUNBZ0lDQWdJQ0FnYkc5allXd2dZV04wZFdGc1IyVnRJRDBnUlc1emRYSmxVM0JsYkd4SmJrZGxiU2hOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3c0lFMXBjMk5UY0dWc2JFZGxiU2tLSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdibTkwSUdGamRIVmhiRWRsYlNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KME52ZFd4a0lHNXZkQ0JzYjJGa0lFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklHbHVkRzhnWjJWdElDVmtPeUJsZUdsMGFXNW5JRzFoYm1FZ2JHOXZjQzRuTENCTmFYTmpVM0JsYkd4SFpXMHBDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnSUNBZ0lDMHRJRU5oYzNRZ1RXOXVjM1JsY2lCVGRXMXRiMjVwYm1jS0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGxOd1pXeHNVbVZoWkhrb1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OWpZWE4wSUNWa0p5d2dZV04wZFdGc1IyVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTnpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2dvZ0lDQWdJQ0FnSUNBZ0lDQXRMU0JTWldOc1lXbHRJR2x0YldWa2FXRjBaV3g1SUdsbUlHRWdjR1YwSUdseklIVndDaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR0Z1WkNCU1pXTnNZV2x0U1hSbGJTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrWmlnbkwzVnpaV2wwWlcwZ0pYTW5MQ0JTWldOc1lXbHRTWFJsYlNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnWlc1a0NpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ2dvZ0lDQWdUbTkwWlM1SmJtWnZLQ2ROWVc1aElFeHZiM0FnUlc1a1pXUW5LUW9nSUNBZ0xTMGdabWx1WVd3Z1kyeGxZVzUxY0RvZ2FXWWdkR1Z0Y0NCd1pYUWdjM1JwYkd3Z2RYQXNJSEpsWTJ4aGFXMGdkVzUwYVd3Z1oyOXVaUW9nSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVpYUXVTVVFvS1NCdmNpQXdLU0ErSURBZ1pHOEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkWE5sYVhSbGJTQWxjeWNzSUZKbFkyeGhhVzFKZEdWdEtRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRWx1YVhRZ2MzQmxiR3h6TDJsMFpXMXpDbXh2WTJGc0lHWjFibU4wYVc5dUlFbHVhWFFvS1FvZ0lDQWdRMmhsWTJ0UWJIVm5hVzRvSjAxUk1saEJjM05wYzNRbktRb2dJQ0FnUTJobFkydFFiSFZuYVc0b0owMVJNa0ZrZGxCaGRHZ25LUW9nSUNBZ1EyaGxZMnRRYkhWbmFXNG9KMDFSTWsxdmRtVlZkR2xzY3ljcENpQWdJQ0JEYUdWamExQnNkV2RwYmlnblRWRXlRbTk0Y2ljcENnb2dJQ0FnVFc5dWMzUmxjbE4xYlcxdmJtbHVaeUE5SUhzS0lDQWdJQ0FnSUNBaVRXOXVjM1JsY2lCVGRXMXRiMjVwYm1jZ1dGWWlMQW9nSUNBZ0lDQWdJQ0pOYjI1emRHVnlJRk4xYlcxdmJtbHVaeUJZU1ZZaUxBb2dJQ0FnSUNBZ0lDSk5iMjV6ZEdWeUlGTjFiVzF2Ym1sdVp5QllTVWxKSWl3S0lDQWdJSDBLSUNBZ0lFMXZibk4wWlhKVGRXMXRiMjVwYm1kVGNHVnNiQ0E5SUVOb2IyOXpaVUZpYVd4cGRIa29UVzl1YzNSbGNsTjFiVzF2Ym1sdVp5a0tJQ0FnSUdsbUlHNXZkQ0JOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3Z2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUVNCdGIyNXpkR1Z5SUhOMWJXMXZibWx1WnlCemNHVnNiQ0JwY3lCdWIzUWdZWFpoYVd4aFlteGxKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvS0lDQWdJQzB0SUZWd1pHRjBaV1FnUjJGMGFHVnlJR3hwYm1VZ0tHbHVZMngxWkdWeklHeGxkbVZzSURFeU5Ta0tJQ0FnSUVkaGRHaGxjazFoYm1FZ1BTQjdDaUFnSUNBZ0lDQWdJa2RoZEdobGNpQmFaV0ZzSWl3S0lDQWdJQ0FnSUNBaVIyRjBhR1Z5SUZacFoyOXlJaXdLSUNBZ0lDQWdJQ0FpUjJGMGFHVnlJRkJ2ZEdWdVkza2lMQW9nSUNBZ2ZRb2dJQ0FnUjJGMGFHVnlUV0Z1WVZOd1pXeHNJRDBnUTJodmIzTmxRV0pwYkdsMGVTaEhZWFJvWlhKTllXNWhLUW9nSUNBZ2FXWWdibTkwSUVkaGRHaGxjazFoYm1GVGNHVnNiQ0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZEJJR2RoZEdobGNpQnRZVzVoSUhOd1pXeHNJR2x6SUc1dmRDQmhkbUZwYkdGaWJHVW5LUW9nSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFvZ0lDQWdaVzVrQ2dvZ0lDQWdVbVZqYkdGcGJWTmxkQ0E5SUhzS0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFVmhjblJvSWl3S0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFWnBjbVVpTEFvZ0lDQWdJQ0FnSUNKVGRHRm1aaUJ2WmlCRmJHVnRaVzUwWVd3Z1RXRnpkR1Z5ZVRvZ1FXbHlJaXdLSUNBZ0lDQWdJQ0FpVTNSaFptWWdiMllnUld4bGJXVnVkR0ZzSUUxaGMzUmxjbms2SUZkaGRHVnlJaXdLSUNBZ0lDQWdJQ0FpUW5KdmIyMGdiMllnVkhKcGJHOXVJaXdLSUNBZ0lDQWdJQ0FpUVc1amFXVnVkQ0JVYjNKamFDQnZaaUJCYkc1aElpd0tJQ0FnSUNBZ0lDQWlSMlZ0YldWa0lFZHNiM1psY3lCdlppQkhkV2xzWlNJc0NpQWdJQ0FnSUNBZ0lrZHNiM1psY3lCdlppQkVZWEpySUZOMWJXMXZibWx1WnlJc0NpQWdJQ0FnSUNBZ0lsTm9iM1psYkNCdlppQlFiMjU2SWl3S0lDQWdJQ0FnSUNBaVUzUmxhVzRnYjJZZ1ZXeHBjM05oSWl3S0lDQWdJQ0FnSUNBaVZHOXlZMmdnYjJZZ1FXeHVZU0lzQ2lBZ0lDQjlDaUFnSUNCU1pXTnNZV2x0U1hSbGJTQTlJRU5vYjI5elpVbDBaVzBvVW1WamJHRnBiVk5sZENrS0lDQWdJR2xtSUc1dmRDQlNaV05zWVdsdFNYUmxiU0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZE9ieUJ5WldOc1lXbHRJR2wwWlcwZ1ptOTFibVFnYVc0Z2FXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlVLSUNBZ0lHVnVaQW9LSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS0xTMGdUV0ZwYmlCeWIzVjBhVzVsSUNodFpYSm5aV1FnYVc1MGJ5Qk1SVTBnWVdOMGFXOXVLUXBzYjJOaGJDQm1kVzVqZEdsdmJpQlNkVzVOYjI1emRHVnlUV0Z1WVNncENpQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVEyeGhjM011VTJodmNuUk9ZVzFsS0NrZ2ZqMGdKMDFCUnljZ2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVFc5dWMzUmxjazFoYm1FZ2IyNXNlU0IzYjNKcmN5Qm1iM0lnVFdGblpTQmphR0Z5WVdOMFpYSnpKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvZ0lDQWdhV1lnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNVEF3S1NBK0lEazFJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owMWhibUVnYVhNZ2JtVmhjbXg1SUdaMWJHdzdJRzV2ZEdocGJtY2dkRzhnWkc4bktRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ1pXNWtDaUFnSUNCcFppQnViM1FnU1c1cGRDZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owbHVhWFJwWVd4cGVtRjBhVzl1SUhWdWMzVmpZMlZ6YzJaMWJDY3BDaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWmhiSE5sQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZZWFIwWVdOcklHOW1aaWNwQ2dvZ0lDQWdMUzBnWTJ4bFlYSWdZM1Z5YzI5eUNpQWdJQ0IzYUdsc1pTQnRjUzVVVEU4dVEzVnljMjl5TGtsRUtDa2daRzhLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTloZFhSdmFXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNREFwQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JKWmlCM1pTQmhiSEpsWVdSNUlHaGhkbVVnWVNCdFlXbHVJSEJsZEN3Z2MzVnpjR1Z1WkNCcGRDQkdTVkpUVkNBb1lteHZZMnRwYm1jcENpQWdJQ0JwWmlBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQ0Z01DQjBhR1Z1Q2lBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkUWNtbHRZWEo1SUcxaGJtRWdiV1YwYUc5a0lDaDNhWFJvSUhCbGRDa25LUW9nSUNBZ0lDQWdJR2xtSUc1dmRDQlRkWE53Wlc1a1VISnBiV0Z5ZVZCbGRGOUNiRzlqYTJsdVp5Z3BJSFJvWlc0S0lDQWdJQ0FnSUNBZ0lDQWdUbTkwWlM1SmJtWnZLQ2RWYm1GaWJHVWdkRzhnYzNWemNHVnVaQ0J3WlhRZ2MyRm1aV3g1T3lCaFltOXlkR2x1Wnk0bktRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzlrYjJOdmJXMWhibVFnTDJKdmVISWdkVzV3WVhWelpTY3BDaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJtWVd4elpRb2dJQ0FnSUNBZ0lHVnVaQW9nSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQzB0SUU1dkxYQmxkQ0JtWVd4c1ltRmphem9nWW5WcGJHUWdkRzhnT0NVZ2QybDBhQ0JIWVhSb1pYSWdiM0lnYzJsMGRHbHVad29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVUhKcGJXRnllU0J0WVc1aElHMWxkR2h2WkNBb2JtOGdjR1YwS1NjcENpQWdJQ0FnSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNQ2tnUENBNElHUnZDaUFnSUNBZ0lDQWdJQ0FnSUd4dlkyRnNJSEpoYm10T1lXMWxJRDBnYlhFdVZFeFBMbE53Wld4c0tFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrdVVtRnVhMDVoYldVb0tRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVUzQmxiR3hTWldGa2VTaHlZVzVyVG1GdFpTa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MMk5oYzNRZ0lpVnpJaWNzSUhKaGJtdE9ZVzFsS1FvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdaV3h6WldsbUlIZHZjbXRwYm1kVGRHRjBaWE5iYlhFdVZFeFBMazFsTGtOdmJXSmhkRk4wWVhSbEtDa2diM0lnSnlkZElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1VGRHRnVaR2x1WnlncElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0IwYUdWdUlHMXhMbFJNVHk1TlpTNVRhWFFvS1NCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNneE5UQXBDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JTZFc0Z2JXRnVZU0JzYjI5d0lDaHpkVzF0YjI0dmNtVmpiR0ZwYlNrS0lDQWdJRkpsWTJ4aGFXMU5ZVzVoS0NrS0NpQWdJQ0F0TFNCVWNua2dkRzhnY21WemRHOXlaU0J0WVdsdUlIQmxkQ0FvZFc1emRYTndaVzVrS1M0Z1RHOXZjQ0IxYm5ScGJDQmhJRzV2YmkxWFlYSnlhVzl5SUhCbGRDQW9hUzVsTGl3Z2VXOTFjaUJ5WldGc0lHVnNaVzFsYm5SaGJDa2djbVYwZFhKdWN5NEtJQ0FnSUU1dmRHVXVTVzVtYnlnblVtVnpkRzl5YVc1bklHMWhhVzRnY0dWMElDaDFibk4xYzNCbGJtUnBibWNwSnlrS0lDQWdJSGRvYVd4bElDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BUMGdNQ0JrYndvZ0lDQWdJQ0FnSUZkaGFYUlRkR2xzYkNnME1EQXBDaUFnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZZV3gwSUdGamRDQXhOelluS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RZMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnek1EQXBDaUFnSUNCbGJtUUtJQ0FnSUMwdElFbG1JR0VnVFc5dWMzUmxjaUJUZFcxdGIyNXBibWNnZDJGeWNtbHZjaUJ3WlhRZ2NHOXdjR1ZrSUdsdWMzUmxZV1FzSUhKbFkyeGhhVzBnWVc1a0lIUnllU0JoWjJGcGJpNEtJQ0FnSUhkb2FXeGxJQ2h0Y1M1VVRFOHVUV1V1VUdWMExrTnNZWE56TGs1aGJXVW9LU0J2Y2lBbkp5a2dQVDBnSjFkaGNuSnBiM0luSUdSdkNpQWdJQ0FnSUNBZ2FXWWdVbVZqYkdGcGJVbDBaVzBnZEdobGJnb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2ZFhObGFYUmxiU0FsY3ljc0lGSmxZMnhoYVcxSmRHVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnMU1EQXBDaUFnSUNBZ0lDQWdaV3h6WlFvZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUdWdVpBb2dJQ0FnSUNBZ0lIZG9hV3hsSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUFQwZ01DQmtid29nSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5aGJIUWdZV04wSURFM05pY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RZMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUdWdVpBb2dJQ0FnWlc1a0Nnb2dJQ0FnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnYlhFdVkyMWtLQ2N2Y0dWMElHaHZiR1FuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZaRzlqYjIxdFlXNWtJQzlpYjNoeUlIVnVjR0YxYzJVbktRb2dJQ0FnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnVG05MFpTNUpibVp2S0NkTllXNWhJSEp2ZFhScGJtVWdZMjl0Y0d4bGRHVXVJRTFoWjJVZ2JXRnVZU0J1YjNjNklGeGhaeVZ6Snl3Z2RHOXpkSEpwYm1jb2JYRXVWRXhQTGsxbExsQmpkRTFoYm1Fb0tTa3BDaUFnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5aVpXVndiMjUwWld4c2N5QnZiaWNwQ2lBZ0lDQnlaWFIxY200Z2RISjFaUXBsYm1RS0NteHZZMkZzSUdaMWJtTjBhVzl1SUdGamRHbHZiaWdwQ2lBZ0lDQXRMU0JTWldkcGMzUmxjaUJ6Y0dWc2JHSnZiMnNnWlhabGJuUnpJQ2hNUlUwdGMyRm1aU2tLSUNBZ0lHMXhMbVYyWlc1MEtDZENaV2RwYmsxbGJXOXlhWHBwYm1jbkxDQWlJeW9qUW1WbmFXNXVhVzVuSUhSdklHMWxiVzl5YVhwbElDTXhJeTR1TGlNcUl5SXNJRVYyWlc1MFgwSmxaMmx1VFdWdGIzSnBlbWx1WnlrS0lDQWdJRzF4TG1WMlpXNTBLQ2RHYVc1cGMyaE5aVzF2Y21sNmFXNW5KeXdnSWlNcUkxbHZkU0JvWVhabElHWnBibWx6YUdWa0lHMWxiVzl5YVhwcGJtY2dJekVqSXlvaklpd2dSWFpsYm5SZlJXNWtUV1Z0YjNKcGVtbHVaeWtLSUNBZ0lHMXhMbVYyWlc1MEtDZEJZbTl5ZEUxbGJXOXlhWHBwYm1jbkxDQWlJeW9qUVdKdmNuUnBibWNnYldWdGIzSnBlbUYwYVc5dUlHOW1JSE53Wld4c0xpTXFJeUlzSUVWMlpXNTBYMFZ1WkUxbGJXOXlhWHBwYm1jcENnb2dJQ0FnYkc5allXd2diMnNzSUdWeWNpQTlJSEJqWVd4c0tGSjFiazF2Ym5OMFpYSk5ZVzVoS1FvZ0lDQWdhV1lnYm05MElHOXJJSFJvWlc0Z1RtOTBaUzVKYm1adktDZGNZWEpGY25KdmNqcGNZWGdnSlhNbkxDQjBiM04wY21sdVp5aGxjbklwS1NCbGJtUUtaVzVrQ2dweVpYUjFjbTRnZTJOdmJtUm1kVzVqUFdOdmJtUnBkR2x2Yml3Z1lXTjBhVzl1Wm5WdVl6MWhZM1JwYjI1OUNnPT0iLAogWyJ0eXBlIl0gPSAiY29uZGl0aW9ucyIsCiBbImNhdGVnb3J5Il0gPSAiR2VuZXJhbCIsCn0=
 
Updated LEM Version that fixed some bugs:

Import String:
[CODE title="Import String"]cmV0dXJuIHsKIFsibG9hZCJdID0gewogIFsiYWx3YXlzIl0gPSBmYWxzZSwKICBbInpvbmUiXSA9ICIiLAogIFsiY2xhc3MiXSA9ICIiLAogfSwKIFsidHlwZSJdID0gImNvbmRpdGlvbnMiLAogWyJuYW1lIl0gPSAiTWFnZSAtIEVuZGxlc3MgTWFuYSIsCiBbImNhdGVnb3J5Il0gPSAiR2VuZXJhbCIsCiBbImNvZGUiXSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUdOb1pXTnJYM0JoZFhObFpDQTlJRzF4TGxSTVR5NURWMVJPTGxCaGRYTmxaQ2dwQ2lBZ0lDQnNiMk5oYkNCdGJWOXpkR0YwZFhNZ1BTQnRjUzVVVEU4dVRIVmhMbE5qY21sd2RDZ25UVTFpY25WMFpTY3BMbE4wWVhSMWN5Z3BDaUFnSUNCeVpYUjFjbTRnYlhsZlkyeGhjM01nUFQwZ0owMUJSeWNnWVc1a0lHMTVYMjFoYm1FZ1BDQXlNQ0JoYm1RZ2JXMWZjM1JoZEhWeklINDlJQ2RTVlU1T1NVNUhKeUJoYm1RZ1kyaGxZMnRmY0dGMWMyVmtJRDA5SUdaaGJITmxDbVZ1WkFvS0xTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwS0xTMGdSWFpsY25sMGFHbHVaeUJpWld4dmR5QnlkVzV6SUdsdWMybGtaU0JNUlUwbmN5QmhZM1JwYjI0b0tTQjNhR1Z1SUhSb1pTQmpiMjVrYVhScGIyNGdhWE1nYldWMENpMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdENnb3RMU0JNYVdkb2RIZGxhV2RvZENCc2IyZG5aWElnS0hObGJHWXRZMjl1ZEdGcGJtVmtLUXBzYjJOaGJDQk9iM1JsSUQwZ2V5QndjbVZtYVhnZ1BTQW5UVzl1YzNSbGNrMWhibUVuTENCc2IyZHNaWFpsYkNBOUlDZHBibVp2SnlCOUNtWjFibU4wYVc5dUlFNXZkR1V1U1c1bWJ5aG1iWFFzSUM0dUxpa2djSEpwYm5Rb0tDZGNZV2RiSlhOZFhHRjRJQ2N1TG1adGRDazZabTl5YldGMEtFNXZkR1V1Y0hKbFptbDRMQ0F1TGk0cEtTQmxibVFLQ2kwdElGTjBZWFJsSUM4Z1kyOXVabWxuQ214dlkyRnNJSGR2Y210cGJtZFRkR0YwWlhNZ1BTQjdJRUZqZEdsMlpUMTBjblZsTENCRGIyOXNaRzkzYmoxMGNuVmxMQ0JTWlhOMGFXNW5QWFJ5ZFdVZ2ZRcHNiMk5oYkNCTmIyNXpkR1Z5VTNWdGJXOXVhVzVuTENCTmIyNXpkR1Z5VTNWdGJXOXVhVzVuVTNCbGJHd0tiRzlqWVd3Z1IyRjBhR1Z5VFdGdVlTd2dSMkYwYUdWeVRXRnVZVk53Wld4c0NteHZZMkZzSUZKbFkyeGhhVzFUWlhRc0lGSmxZMnhoYVcxSmRHVnRDbXh2WTJGc0lFMXBjMk5UY0dWc2JFZGxiU0E5SURnZ0xTMGdkWE5wYm1jZ1oyVnRJRGdLYkc5allXd2dTWE5OWlcxdmNtbDZhVzVuSUQwZ1ptRnNjMlVLYkc5allXd2daR2xrVTNWemNHVnVaRTFoYVc1UVpYUWdQU0JtWVd4elpTQXRMU0JPUlZjNklIUnlZV05ySUhkb1pYUm9aWElnZDJVZ1lXTjBkV0ZzYkhrZ2MzVnpjR1Z1WkdWa0lHRWdiV0ZwYmlCd1pYUWdkR2hwY3lCeWRXNEtDaTB0SUMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdENpMHRJRWhsYkhCbGNuTUtMUzBnTFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwS2JHOWpZV3dnWm5WdVkzUnBiMjRnUTJobFkydFFiSFZuYVc0b2NHeDFaMmx1S1FvZ0lDQWdhV1lnYm05MElHMXhMbFJNVHk1UWJIVm5hVzRvY0d4MVoybHVLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZjM0YxWld4amFDQXZjR3gxWjJsdUlDVnpJRzV2WVhWMGJ5Y3NJSEJzZFdkcGJpa0tJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KMXhoZHlWelhHRjRJRzV2ZENCa1pYUmxZM1JsWkM0Z1RHOWhaR2x1WitLQXBpY3NJSEJzZFdkcGJpa0tJQ0FnSUdWdVpBcGxibVFLQ2kwdElGTnBiWEJzWlNCdGIzWmxiV1Z1ZENCamFHVmphem9nYjI1c2VTQjViM1Z5SUdGMllYUmhjdUtBbVhNZ2JXOTBhVzl1TGdwc2IyTmhiQ0JtZFc1amRHbHZiaUJKYzAxdmRtbHVaeWdwQ2lBZ0lDQnlaWFIxY200Z2JYRXVWRXhQTGsxbExrMXZkbWx1WnlncElHOXlJQ2dvYlhFdVZFeFBMazFsTGxOd1pXVmtLQ2tnYjNJZ01Da2dQaUF3S1FwbGJtUUtDaTB0SUZkaGFYUWdkVzUwYVd3Z2QyWGlnSmwyWlNCaVpXVnVJRTVQVkNCdGIzWnBibWNnWm05eUlHRWdZMjl1ZEdsdWRXOTFjeUIzYVc1a2IzY2dLRzF6S1M0Z1RtOGdZWFIwWlcxd2RDQnNhVzFwZEM0S2JHOWpZV3dnWm5WdVkzUnBiMjRnVjJGcGRGTjBhV3hzS0cxcGJsOXRjeWtLSUNBZ0lHMXBibDl0Y3lBOUlHMXBibDl0Y3lCdmNpQTBNREFLSUNBZ0lHeHZZMkZzSUhOMGFXeHNVM1JoY25RZ1BTQnVhV3dLSUNBZ0lIZG9hV3hsSUhSeWRXVWdaRzhLSUNBZ0lDQWdJQ0JwWmlCSmMwMXZkbWx1WnlncElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ2MzUnBiR3hUZEdGeWRDQTlJRzVwYkFvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYzNScGJHeFRkR0Z5ZENBOUlITjBhV3hzVTNSaGNuUWdiM0lnYlhFdVoyVjBkR2x0WlNncENpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNodGNTNW5aWFIwYVcxbEtDa2dMU0J6ZEdsc2JGTjBZWEowS1NBK1BTQnRhVzVmYlhNZ2RHaGxiaUJ5WlhSMWNtNGdkSEoxWlNCbGJtUUtJQ0FnSUNBZ0lDQmxibVFLSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2cxTUNrS0lDQWdJR1Z1WkFwbGJtUUtDaTB0SUZKdlluVnpkQ0RpZ0p4aGJTQkpJR2x1SUdOdmJXSmhkRC9pZ0owZ1kyaGxZMnNLYkc5allXd2dablZ1WTNScGIyNGdTVzVEYjIxaVlYUW9LUW9nSUNBZ2JHOWpZV3dnWTNNZ1BTQjBiM04wY21sdVp5aHRjUzVVVEU4dVRXVXVRMjl0WW1GMFUzUmhkR1VvS1NCdmNpQW5KeWtLSUNBZ0lHbG1JR056SUg0OUlDY25JR0Z1WkNCamN6cDFjSEJsY2lncElEMDlJQ2REVDAxQ1FWUW5JSFJvWlc0Z2NtVjBkWEp1SUhSeWRXVWdaVzVrQ2lBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UTI5dFltRjBJR0Z1WkNCdGNTNVVURTh1VFdVdVEyOXRZbUYwS0NrZ2RHaGxiaUJ5WlhSMWNtNGdkSEoxWlNCbGJtUUtJQ0FnSUhKbGRIVnliaUJtWVd4elpRcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJRU5vYjI5elpVRmlhV3hwZEhrb2MyVjBLUW9nSUNBZ2JHOWpZV3dnWTJodmMyVnVVM0JsYkd3c0lHaHBaMmhsYzNSTVpYWmxiQ0E5SUc1cGJDd2dNQW9nSUNBZ1ptOXlJRjhzSUc1aGJXVWdhVzRnYVhCaGFYSnpLSE5sZENrZ1pHOEtJQ0FnSUNBZ0lDQnNiMk5oYkNCeklEMGdiWEV1VkV4UExsTndaV3hzS0c1aGJXVXBDaUFnSUNBZ0lDQWdiRzlqWVd3Z2JIWnNMQ0J5WVc1cklEMGdjeTVNWlhabGJDZ3BMQ0J6TGxKaGJtdE9ZVzFsS0NrS0lDQWdJQ0FnSUNCcFppQnlZVzVySUdGdVpDQnRjUzVVVEU4dVRXVXVRbTl2YXloeVlXNXJLU2dwSUdGdVpDQnNkbXdnUGlCb2FXZG9aWE4wVEdWMlpXd2dkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQmphRzl6Wlc1VGNHVnNiQ0E5SUNodGNTNVVURTh1VFdVdVUzQmxiR3hTWVc1clEyRndLQ2tnUGlBeEtTQmhibVFnY3k1U1lXNXJUbUZ0WlNncElHOXlJSE11UW1GelpVNWhiV1VvS1FvZ0lDQWdJQ0FnSUNBZ0lDQm9hV2RvWlhOMFRHVjJaV3dnUFNCc2Rtd0tJQ0FnSUNBZ0lDQmxibVFLSUNBZ0lHVnVaQW9nSUNBZ2NtVjBkWEp1SUdOb2IzTmxibE53Wld4c0NtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdRMmh2YjNObFNYUmxiU2h6WlhRcENpQWdJQ0JtYjNJZ1h5d2dibUZ0WlNCcGJpQnBjR0ZwY25Nb2MyVjBLU0JrYndvZ0lDQWdJQ0FnSUdsbUlHMXhMbFJNVHk1R2FXNWtTWFJsYlVOdmRXNTBLRzVoYldVcEtDa2dQaUF3SUhSb1pXNGdjbVYwZFhKdUlHNWhiV1VnWlc1a0NpQWdJQ0JsYm1RS1pXNWtDZ290TFNCVGNHVnNiR0p2YjJzZ1pYWmxiblJ6SUNoeVpXZHBjM1JsY21Wa0lHbHVjMmxrWlNCaFkzUnBiMjRvS1NrS2JHOWpZV3dnWm5WdVkzUnBiMjRnUlhabGJuUmZRbVZuYVc1TlpXMXZjbWw2YVc1bktGOHNJRjhwSUVselRXVnRiM0pwZW1sdVp5QTlJSFJ5ZFdVZ1pXNWtDbXh2WTJGc0lHWjFibU4wYVc5dUlFVjJaVzUwWDBWdVpFMWxiVzl5YVhwcGJtY29YeXdnWHlrZ1NYTk5aVzF2Y21sNmFXNW5JRDBnWm1Gc2MyVWdaVzVrQ2dvdExTQkZibk4xY21VZ2MzQmxiR3dnYVhNZ2FXNGdZU0J6Y0dWamFXWnBZeUJuWlcwZ0tHSnNiMk5yYVc1bkxDQnVieUJoZEhSbGJYQjBJR3hwYldsMEtTNGdUMjVzZVNCemRHRnlkSE1nZDJobGJpQnpkR0YwYVc5dVlYSjVMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQkZibk4xY21WVGNHVnNiRWx1UjJWdEtITndaV3hzVkc5TlpXMHNJR2RsYlNrS0lDQWdJR2RsYlNBOUlHZGxiU0J2Y2lCTmFYTmpVM0JsYkd4SFpXMEtJQ0FnSUhkb2FXeGxJSFJ5ZFdVZ1pHOEtJQ0FnSUNBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UjJWdEtITndaV3hzVkc5TlpXMHBLQ2tnUFQwZ1oyVnRJSFJvWlc0Z2NtVjBkWEp1SUdkbGJTQmxibVFLSUNBZ0lDQWdJQ0JzYjJOaGJDQnliaUE5SUcxeExsUk1UeTVUY0dWc2JDaHpjR1ZzYkZSdlRXVnRLUzVTWVc1clRtRnRaU2dwQ2lBZ0lDQWdJQ0FnYVdZZ2JtOTBJSEp1SUc5eUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UW05dmF5aHliaWtvS1NCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblEyRnVibTkwSUcxbGJXOXlhWHBsSUNodWIzUWdhVzRnWW05dmF5azZJQ1Z6Snl3Z2RHOXpkSEpwYm1jb2MzQmxiR3hVYjAxbGJTa3BDaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliZ29nSUNBZ0lDQWdJR1Z1WkFvZ0lDQWdJQ0FnSUdsbUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UjJWdEtHZGxiU2tvS1NCaGJtUWdaMlZ0SUg0OUlFMXBjMk5UY0dWc2JFZGxiU0IwYUdWdUlHZGxiU0E5SUUxcGMyTlRjR1ZzYkVkbGJTQmxibVFLSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTmpBd0tRb2dJQ0FnSUNBZ0lFNXZkR1V1U1c1bWJ5Z25YR0ZuVFdWdGJXbHVaMXhoZUNBaUpYTWlJR2x1ZEc4Z1oyVnRJQ1ZrSnl3Z2NtNHNJR2RsYlNrS0lDQWdJQ0FnSUNCdGNTNWpiV1JtS0NjdmJXVnRjM0JsYkd3Z0pXUWdJaVZ6SWljc0lHZGxiU3dnY200cENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb01qQXdNQ3dnWm5WdVkzUnBiMjRvS1NCeVpYUjFjbTRnU1hOTlpXMXZjbWw2YVc1bklHOXlJRzF4TGxSTVR5NU5aUzVIWlcwb1oyVnRLUzVPWVcxbEtDa2dQVDBnY200Z1pXNWtLUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLREV3TURBd0xDQm1kVzVqZEdsdmJpZ3BJSEpsZEhWeWJpQnRjUzVVVEU4dVRXVXVSMlZ0S0dkbGJTa3VUbUZ0WlNncElEMDlJSEp1SUc5eUlHNXZkQ0JKYzAxbGJXOXlhWHBwYm1jZ1pXNWtLUW9nSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1SFpXMG9aMlZ0S1M1T1lXMWxLQ2tnUFQwZ2NtNGdkR2hsYmlCeVpYUjFjbTRnWjJWdElHVnVaQW9nSUNBZ1pXNWtDbVZ1WkFvS0xTMGdVR1YwSUhCeWIzaHBiV2wwZVNCb1pXeHdaWEp6SUNoM2FYUm9JRzl3ZEdsdmJtRnNJSFJwYldWdmRYUWdkRzhnY0hKbGRtVnVkQ0JvWVc1bmN5a0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1VHVjBUbVZoY2lodFlYaEVhWE4wS1NCeVpYUjFjbTRnS0cxeExsUk1UeTVOWlM1UVpYUXVSR2x6ZEdGdVkyVW9LU0J2Y2lBNU9UazVLU0E4UFNBb2JXRjRSR2x6ZENCdmNpQXhNaWtnWlc1a0NteHZZMkZzSUdaMWJtTjBhVzl1SUZkaGFYUlFaWFJPWldGeUtHMWhlRVJwYzNRc0lIUnBiV1Z2ZFhSZmJYTXBDaUFnSUNCdFlYaEVhWE4wSUQwZ2JXRjRSR2x6ZENCdmNpQXhNZ29nSUNBZ2JHOWpZV3dnYzNSaGNuUWdQU0J0Y1M1blpYUjBhVzFsS0NrS0lDQWdJSGRvYVd4bElIUnlkV1VnWkc4S0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJsZEM1SlJDZ3BJRzl5SURBcElEMDlJREFnZEdobGJpQnlaWFIxY200Z1ptRnNjMlVnWlc1a0NpQWdJQ0FnSUNBZ2FXWWdVR1YwVG1WaGNpaHRZWGhFYVhOMEtTQjBhR1Z1SUhKbGRIVnliaUIwY25WbElHVnVaQW9nSUNBZ0lDQWdJR2xtSUhScGJXVnZkWFJmYlhNZ1lXNWtJQ2h0Y1M1blpYUjBhVzFsS0NrZ0xTQnpkR0Z5ZENrZ1BqMGdkR2x0Wlc5MWRGOXRjeUIwYUdWdUlISmxkSFZ5YmlCUVpYUk9aV0Z5S0cxaGVFUnBjM1FwSUdWdVpBb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdLUW9nSUNBZ1pXNWtDbVZ1WkFvS0xTMGdVM1Z6Y0dWdVpDQndaWFFnZDJsMGFDQm1kV3hzSUhObGNYVmxibU5sSUdWMlpYSjVJSEJoYzNNdUNpMHRJRTl1YkhrZ2RYTmxJRU52VkVnZ1FVRWdLRGN3TlRBcElHbG1JSGRsSUdGeVpTQkpUaUJEVDAxQ1FWUXVDaTB0SUZKbGRIVnlibk1nVkZKVlJTQnZibXg1SUdsbUlIUm9aU0J3WlhRZ1pXNWtjeUIxY0NCemRYTndaVzVrWldRZ0tFbEVJRDA5SURBcExncHNiMk5oYkNCbWRXNWpkR2x2YmlCVGRYTndaVzVrVUhKcGJXRnllVkJsZEY5Q2JHOWphMmx1WnlncENpQWdJQ0JzYjJOaGJDQnZjbWxuU1VRZ1BTQnRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUFvZ0lDQWdhV1lnYjNKcFowbEVJRDA5SURBZ2RHaGxiaUJ5WlhSMWNtNGdabUZzYzJVZ1pXNWtJQzB0SUc1dmRHaHBibWNnZEc4Z2MzVnpjR1Z1WkFvS0lDQWdJRTV2ZEdVdVNXNW1ieWduVTNSdmNtbHVaeUJRWlhRZ0tFbEVJQ1Z6S1Njc0lIUnZjM1J5YVc1bktHOXlhV2RKUkNrcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWlhRdVNVUW9LU0J2Y2lBd0tTQStJREFnWkc4S0lDQWdJQ0FnSUNBdExTQkdkV3hzSUhObGNYVmxibU5sT2lCbmFHOXNaQ0F0UGlCemNHVnNiR2h2YkdRZ0xUNGdZbUZqYXlBdFBpQlRkVzF0YjI0Z1EyOXRjR0Z1YVc5dUlDZ3hNakUxS1NBdFBpQW9RMjlVU0NCcFppQkpUaUJEVDAxQ1FWUXBJQzArSUhOMWMzQmxibVFLSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTkRBd0tRb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzQmxkQ0JuYUc5c1pDQnZiaWNwSUNBZ0lEc2diWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNCbGRDQnpjR1ZzYkdodmJHUWdiMjRuS1RzZ2JYRXVaR1ZzWVhrb016QXdLUW9nSUNBZ0lDQWdJRzF4TG1OdFpDZ25MM0JsZENCaVlXTnJKeWtnSUNBZ0lDQWdJRHNnYlhFdVpHVnNZWGtvTXpBd0tRb0tJQ0FnSUNBZ0lDQXRMU0JUZFcxdGIyNGdRMjl0Y0dGdWFXOXVJRkpKUjBoVUlFSkZSazlTUlNCemRYTndaVzVrYVc1bkxDQnBaaUJ5WldGa2VTQW9aRzl1NG9DWmRDQmliRzlqYXlCbWIzSWdRMFFwQ2lBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExrRnNkRUZpYVd4cGRIbFNaV0ZrZVNneE1qRTFLU2dwSUc5eUlHMXhMbFJNVHk1TlpTNUJiSFJCWW1sc2FYUjVVbVZoWkhrb0oxTjFiVzF2YmlCRGIyMXdZVzVwYjI0bktTZ3BJSFJvWlc0S0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRE13TUNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZZV3gwSUdGamRDQXhNakUxSnlrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NelV3TUN3Z1puVnVZM1JwYjI0b0tTQnlaWFIxY200Z2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ1pXNWtLUW9nSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVR1YwVG1WaGNpZ3hNaXdnTXpBd01Da0tJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnTFMwZ1QyNXNlU0JrYnlCRGIxUklJR2xtSUhkbElHRnlaU0JoWTNSMVlXeHNlU0JwYmlCamIyMWlZWFFLSUNBZ0lDQWdJQ0JwWmlCSmJrTnZiV0poZENncElHRnVaQ0J0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLRGN3TlRBcEtDa2dkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQlhZV2wwVTNScGJHd29NekF3S1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkR0Z5WjJWMElHbGtJQ1ZrSnl3Z2JYRXVWRXhQTGsxbExrbEVLQ2tnYjNJZ01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFWemFXNW5JRU52VkVnZ1FVRWdkRzhnZDJsd1pTQndaWEp6YjI1aGJDQmhaMmR5YnlBb2FXNGdZMjl0WW1GMEtTNG5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5aGJIUWdZV04wSURjd05UQW5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnek5UQXdMQ0JtZFc1amRHbHZiaWdwSUhKbGRIVnliaUJ1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0JsYm1RcENpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJQzB0SUVGMGRHVnRjSFFnZEc4Z2MzVnpjR1Z1WkFvZ0lDQWdJQ0FnSUZkaGFYUlRkR2xzYkNnME1EQXBDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhsU1pXRmtlU2d4TnpZcEtDa2diM0lnYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhsU1pXRmtlU2duVTNWemNHVnVaQ0JOYVc1cGIyNG5LU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkVGRYTndaVzVrYVc1bklFMXBibWx2YnVLQXBpY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTVRjMkp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTlRBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d6TURBd0xDQm1kVzVqZEdsdmJpZ3BJSEpsZEhWeWJpQnViM1FnYlhFdVZFeFBMazFsTGtOaGMzUnBibWN1U1VRb0tTQmxibVFwQ2lBZ0lDQWdJQ0FnWlc1a0Nnb2dJQ0FnSUNBZ0lHbG1JQ2h0Y1M1VVRFOHVUV1V1VUdWMExrbEVLQ2tnYjNJZ01Da2dQVDBnTUNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblVHVjBJSE4xYzNCbGJtUmxaQzRuS1FvZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RISjFaUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNBdExTQlNaV1J2SUhSb1pTQmxiblJwY21VZ2MyVnhkV1Z1WTJVZ2RXNTBhV3dnYzNWalkyVnpjeTRLSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TURBcENpQWdJQ0JsYm1RS0NpQWdJQ0J5WlhSMWNtNGdLQ2h0Y1M1VVRFOHVUV1V1VUdWMExrbEVLQ2tnYjNJZ01Da2dQVDBnTUNrS1pXNWtDZ290TFNCRGIzSmxJRzFoYm1FZ2JHOXZjRG9nYzNWdGJXOXVJRzF2Ym5OMFpYSWdjR1YwSUNoblpXMGdPQ2tnSmlCeVpXTnNZV2x0SUhWdWRHbHNJRGsxSlNCdFlXNWhMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlNaV05zWVdsdFRXRnVZU2dwQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMDFoYm1FZ1RHOXZjQ0JUZEdGeWRHVmtKeWtLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wySmxaWEJ2Ym5SbGJHeHpJRzltWmljcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tnYjNJZ01UQXdLU0E4SURrMUlHUnZDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMa04xY25OdmNpNUpSQ2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVhWMGIybHVkbVZ1ZEc5eWVTY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJd01EQXBDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGMWRHOXBiblpsYm5SdmNua25LUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJqZEUxaGJtRW9LU0J2Y2lBeE1EQXBJRHdnT0NCaGJtUWdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvUjJGMGFHVnlUV0Z1WVZOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDJOaGMzUWdJaVZ6SWljc0lFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NakF3TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHMXhMbFJNVHk1TlpTNURZWE4wYVc1bkxrbEVLQ2tnUFQwZ2JtbHNJR1Z1WkNrS0NpQWdJQ0FnSUNBZ1pXeHpaV2xtSUNodGNTNVVURTh1VFdVdVEzVnljbVZ1ZEUxaGJtRW9LU0J2Y2lBd0tTQThJQ2h0Y1M1VVRFOHVVM0JsYkd3b1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLUzVOWVc1aEtDa2diM0lnTUNrZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVVM1JoYm1ScGJtY29LU0JoYm1RZ2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ2RHaGxiaUJ0Y1M1VVRFOHVUV1V1VTJsMEtDa2daVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2dvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExsTnBkSFJwYm1jb0tTQjBhR1Z1SUcxeExsUk1UeTVOWlM1VGRHRnVaQ2dwSUdWdVpBb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TlRBcENnb2dJQ0FnSUNBZ0lDQWdJQ0F0TFNCRmJuTjFjbVVnYzNCbGJHd2dhVzRnWjJWdElEZ0tJQ0FnSUNBZ0lDQWdJQ0FnYkc5allXd2dZV04wZFdGc1IyVnRJRDBnUlc1emRYSmxVM0JsYkd4SmJrZGxiU2hOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3c0lFMXBjMk5UY0dWc2JFZGxiU2tLSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdibTkwSUdGamRIVmhiRWRsYlNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KME52ZFd4a0lHNXZkQ0JzYjJGa0lFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklHbHVkRzhnWjJWdElDVmtPeUJsZUdsMGFXNW5JRzFoYm1FZ2JHOXZjQzRuTENCTmFYTmpVM0JsYkd4SFpXMHBDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnSUNBZ0lDMHRJRU5oYzNRZ1RXOXVjM1JsY2lCVGRXMXRiMjVwYm1jS0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGxOd1pXeHNVbVZoWkhrb1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OWpZWE4wSUNWa0p5d2dZV04wZFdGc1IyVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTnpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2dvZ0lDQWdJQ0FnSUNBZ0lDQXRMU0JTWldOc1lXbHRJR2x0YldWa2FXRjBaV3g1SUdsbUlHRWdjR1YwSUdseklIVndDaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR0Z1WkNCU1pXTnNZV2x0U1hSbGJTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrWmlnbkwzVnpaV2wwWlcwZ0pYTW5MQ0JTWldOc1lXbHRTWFJsYlNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnWlc1a0NpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ2dvZ0lDQWdUbTkwWlM1SmJtWnZLQ2ROWVc1aElFeHZiM0FnUlc1a1pXUW5LUW9nSUNBZ0xTMGdabWx1WVd3Z1kyeGxZVzUxY0RvZ2FXWWdkR1Z0Y0NCd1pYUWdjM1JwYkd3Z2RYQXNJSEpsWTJ4aGFXMGdkVzUwYVd3Z1oyOXVaUW9nSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVpYUXVTVVFvS1NCdmNpQXdLU0ErSURBZ1pHOEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkWE5sYVhSbGJTQWxjeWNzSUZKbFkyeGhhVzFKZEdWdEtRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRWx1YVhRZ2MzQmxiR3h6TDJsMFpXMXpDbXh2WTJGc0lHWjFibU4wYVc5dUlFbHVhWFFvS1FvZ0lDQWdRMmhsWTJ0UWJIVm5hVzRvSjAxUk1saEJjM05wYzNRbktRb2dJQ0FnUTJobFkydFFiSFZuYVc0b0owMVJNa0ZrZGxCaGRHZ25LUW9nSUNBZ1EyaGxZMnRRYkhWbmFXNG9KMDFSTWsxdmRtVlZkR2xzY3ljcENpQWdJQ0JEYUdWamExQnNkV2RwYmlnblRWRXlRbTk0Y2ljcENnb2dJQ0FnVFc5dWMzUmxjbE4xYlcxdmJtbHVaeUE5SUhzS0lDQWdJQ0FnSUNBaVRXOXVjM1JsY2lCVGRXMXRiMjVwYm1jZ1dGWWlMQW9nSUNBZ0lDQWdJQ0pOYjI1emRHVnlJRk4xYlcxdmJtbHVaeUJZU1ZZaUxBb2dJQ0FnSUNBZ0lDSk5iMjV6ZEdWeUlGTjFiVzF2Ym1sdVp5QllTVWxKSWl3S0lDQWdJSDBLSUNBZ0lFMXZibk4wWlhKVGRXMXRiMjVwYm1kVGNHVnNiQ0E5SUVOb2IyOXpaVUZpYVd4cGRIa29UVzl1YzNSbGNsTjFiVzF2Ym1sdVp5a0tJQ0FnSUdsbUlHNXZkQ0JOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3Z2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUVNCdGIyNXpkR1Z5SUhOMWJXMXZibWx1WnlCemNHVnNiQ0JwY3lCdWIzUWdZWFpoYVd4aFlteGxKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvS0lDQWdJQzB0SUZWd1pHRjBaV1FnUjJGMGFHVnlJR3hwYm1VZ0tHbHVZMngxWkdWeklHeGxkbVZzSURFeU5Ta0tJQ0FnSUVkaGRHaGxjazFoYm1FZ1BTQjdDaUFnSUNBZ0lDQWdJa2RoZEdobGNpQmFaV0ZzSWl3S0lDQWdJQ0FnSUNBaVIyRjBhR1Z5SUZacFoyOXlJaXdLSUNBZ0lDQWdJQ0FpUjJGMGFHVnlJRkJ2ZEdWdVkza2lMQW9nSUNBZ2ZRb2dJQ0FnUjJGMGFHVnlUV0Z1WVZOd1pXeHNJRDBnUTJodmIzTmxRV0pwYkdsMGVTaEhZWFJvWlhKTllXNWhLUW9nSUNBZ2FXWWdibTkwSUVkaGRHaGxjazFoYm1GVGNHVnNiQ0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZEJJR2RoZEdobGNpQnRZVzVoSUhOd1pXeHNJR2x6SUc1dmRDQmhkbUZwYkdGaWJHVW5LUW9nSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFvZ0lDQWdaVzVrQ2dvZ0lDQWdVbVZqYkdGcGJWTmxkQ0E5SUhzS0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFVmhjblJvSWl3S0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFWnBjbVVpTEFvZ0lDQWdJQ0FnSUNKVGRHRm1aaUJ2WmlCRmJHVnRaVzUwWVd3Z1RXRnpkR1Z5ZVRvZ1FXbHlJaXdLSUNBZ0lDQWdJQ0FpVTNSaFptWWdiMllnUld4bGJXVnVkR0ZzSUUxaGMzUmxjbms2SUZkaGRHVnlJaXdLSUNBZ0lDQWdJQ0FpUW5KdmIyMGdiMllnVkhKcGJHOXVJaXdLSUNBZ0lDQWdJQ0FpUVc1amFXVnVkQ0JVYjNKamFDQnZaaUJCYkc1aElpd0tJQ0FnSUNBZ0lDQWlSMlZ0YldWa0lFZHNiM1psY3lCdlppQkhkV2xzWlNJc0NpQWdJQ0FnSUNBZ0lrZHNiM1psY3lCdlppQkVZWEpySUZOMWJXMXZibWx1WnlJc0NpQWdJQ0FnSUNBZ0lsTm9iM1psYkNCdlppQlFiMjU2SWl3S0lDQWdJQ0FnSUNBaVUzUmxhVzRnYjJZZ1ZXeHBjM05oSWl3S0lDQWdJQ0FnSUNBaVZHOXlZMmdnYjJZZ1FXeHVZU0lzQ2lBZ0lDQjlDaUFnSUNCU1pXTnNZV2x0U1hSbGJTQTlJRU5vYjI5elpVbDBaVzBvVW1WamJHRnBiVk5sZENrS0lDQWdJR2xtSUc1dmRDQlNaV05zWVdsdFNYUmxiU0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZE9ieUJ5WldOc1lXbHRJR2wwWlcwZ1ptOTFibVFnYVc0Z2FXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlVLSUNBZ0lHVnVaQW9LSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS0xTMGdUV0ZwYmlCeWIzVjBhVzVsSUNodFpYSm5aV1FnYVc1MGJ5Qk1SVTBnWVdOMGFXOXVLUXBzYjJOaGJDQm1kVzVqZEdsdmJpQlNkVzVOYjI1emRHVnlUV0Z1WVNncENpQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVEyeGhjM011VTJodmNuUk9ZVzFsS0NrZ2ZqMGdKMDFCUnljZ2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVFc5dWMzUmxjazFoYm1FZ2IyNXNlU0IzYjNKcmN5Qm1iM0lnVFdGblpTQmphR0Z5WVdOMFpYSnpKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvZ0lDQWdhV1lnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNVEF3S1NBK0lEazFJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owMWhibUVnYVhNZ2JtVmhjbXg1SUdaMWJHdzdJRzV2ZEdocGJtY2dkRzhnWkc4bktRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ1pXNWtDaUFnSUNCcFppQnViM1FnU1c1cGRDZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owbHVhWFJwWVd4cGVtRjBhVzl1SUhWdWMzVmpZMlZ6YzJaMWJDY3BDaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWmhiSE5sQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZZWFIwWVdOcklHOW1aaWNwQ2dvZ0lDQWdMUzBnWTJ4bFlYSWdZM1Z5YzI5eUNpQWdJQ0IzYUdsc1pTQnRjUzVVVEU4dVEzVnljMjl5TGtsRUtDa2daRzhLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTloZFhSdmFXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNREFwQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JKWmlCM1pTQmhiSEpsWVdSNUlHaGhkbVVnWVNCdFlXbHVJSEJsZEN3Z2MzVnpjR1Z1WkNCcGRDQkdTVkpUVkNBb1lteHZZMnRwYm1jcElHRnVaQ0J5WlcxbGJXSmxjaUIwYUdGMElIZGxJR1JwWkM0S0lDQWdJR2xtSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUGlBd0lIUm9aVzRLSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFCeWFXMWhjbmtnYldGdVlTQnRaWFJvYjJRZ0tIZHBkR2dnY0dWMEtTY3BDaUFnSUNBZ0lDQWdiRzlqWVd3Z2MzVnpjR1Z1WkdWa1Qwc2dQU0JUZFhOd1pXNWtVSEpwYldGeWVWQmxkRjlDYkc5amEybHVaeWdwQ2lBZ0lDQWdJQ0FnYVdZZ2JtOTBJSE4xYzNCbGJtUmxaRTlMSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkVmJtRmliR1VnZEc4Z2MzVnpjR1Z1WkNCd1pYUWdjMkZtWld4NU95QmhZbTl5ZEdsdVp5NG5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5a2IyTnZiVzFoYm1RZ0wySnZlSElnZFc1d1lYVnpaU2NwQ2lBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ0lDQWdJR1Z1WkFvZ0lDQWdJQ0FnSUdScFpGTjFjM0JsYm1STllXbHVVR1YwSUQwZ2RISjFaUW9nSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQzB0SUU1dkxYQmxkQ0JtWVd4c1ltRmphem9nWW5WcGJHUWdkRzhnT0NVZ2QybDBhQ0JIWVhSb1pYSWdiM0lnYzJsMGRHbHVad29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVUhKcGJXRnllU0J0WVc1aElHMWxkR2h2WkNBb2JtOGdjR1YwS1NjcENpQWdJQ0FnSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNQ2tnUENBNElHUnZDaUFnSUNBZ0lDQWdJQ0FnSUd4dlkyRnNJSEpoYm10T1lXMWxJRDBnYlhFdVZFeFBMbE53Wld4c0tFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrdVVtRnVhMDVoYldVb0tRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVUzQmxiR3hTWldGa2VTaHlZVzVyVG1GdFpTa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MMk5oYzNRZ0lpVnpJaWNzSUhKaGJtdE9ZVzFsS1FvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdaV3h6WldsbUlIZHZjbXRwYm1kVGRHRjBaWE5iYlhFdVZFeFBMazFsTGtOdmJXSmhkRk4wWVhSbEtDa2diM0lnSnlkZElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1VGRHRnVaR2x1WnlncElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0IwYUdWdUlHMXhMbFJNVHk1TlpTNVRhWFFvS1NCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNneE5UQXBDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JTZFc0Z2JXRnVZU0JzYjI5d0lDaHpkVzF0YjI0dmNtVmpiR0ZwYlNrS0lDQWdJRkpsWTJ4aGFXMU5ZVzVoS0NrS0NpQWdJQ0F0TFNCU1pYTjBiM0psSUcxaGFXNGdjR1YwSUU5T1RGa2dhV1lnZDJVZ2NISmxkbWx2ZFhOc2VTQnpkWE53Wlc1a1pXUWdhWFFnZEdocGN5QnlkVzRnS0hCeVpYWmxiblJ6SUdsdVptbHVhWFJsSUd4dmIzQWdZV1owWlhJZ1pHVmhkR2dwTGdvZ0lDQWdhV1lnWkdsa1UzVnpjR1Z1WkUxaGFXNVFaWFFnZEdobGJnb2dJQ0FnSUNBZ0lFNXZkR1V1U1c1bWJ5Z25VbVZ6ZEc5eWFXNW5JRzFoYVc0Z2NHVjBJQ2gxYm5OMWMzQmxibVJwYm1jcEp5a0tJQ0FnSUNBZ0lDQjNhR2xzWlNBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQwOUlEQWdaRzhLSUNBZ0lDQWdJQ0FnSUNBZ1YyRnBkRk4wYVd4c0tEUXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrS0NjdllXeDBJR0ZqZENBeE56WW5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnMk5UQXdMQ0JtZFc1amRHbHZiaWdwSUhKbGRIVnliaUJ1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0JsYm1RcENpQWdJQ0FnSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRE13TUNrS0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQXRMU0JKWmlCaElFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklIZGhjbkpwYjNJZ2NHVjBJSEJ2Y0hCbFpDQnBibk4wWldGa0xDQnlaV05zWVdsdElHRnVaQ0IwY25rZ1lXZGhhVzR1Q2lBZ0lDQWdJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWlhRdVEyeGhjM011VG1GdFpTZ3BJRzl5SUNjbktTQTlQU0FuVjJGeWNtbHZjaWNnWkc4S0lDQWdJQ0FnSUNBZ0lDQWdhV1lnVW1WamJHRnBiVWwwWlcwZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MM1Z6WldsMFpXMGdKWE1uTENCU1pXTnNZV2x0U1hSbGJTa0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzS0lDQWdJQ0FnSUNBZ0lDQWdaVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lIZG9hV3hsSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUFQwZ01DQmtid29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTVRjMkp5a0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWTFNREFzSUdaMWJtTjBhVzl1S0NrZ2NtVjBkWEp1SUc1dmRDQnRjUzVVVEU4dVRXVXVRMkZ6ZEdsdVp5NUpSQ2dwSUdWdVpDa0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtETXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ1pXNWtDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxiSE5sQ2lBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkT2J5QnpkWE53Wlc1a1pXUWdiV0ZwYmlCd1pYUWdkRzhnY21WemRHOXlaU0FvYkdsclpXeDVJSE4wWVhKMFpXUWdkMmwwYUNCdWJ5QndaWFFwTGljcENpQWdJQ0JsYm1RS0NpQWdJQ0J0Y1M1a1pXeGhlU2d6TURBcENpQWdJQ0J0Y1M1amJXUW9KeTl3WlhRZ2FHOXNaQ2NwQ2lBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2RXNXdZWFZ6WlNjcENpQWdJQ0J0Y1M1a1pXeGhlU2d6TURBcENpQWdJQ0JPYjNSbExrbHVabThvSjAxaGJtRWdjbTkxZEdsdVpTQmpiMjF3YkdWMFpTNGdUV0ZuWlNCdFlXNWhJRzV2ZHpvZ1hHRm5KWE1uTENCMGIzTjBjbWx1WnlodGNTNVVURTh1VFdVdVVHTjBUV0Z1WVNncEtTa0tJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKbFpYQnZiblJsYkd4eklHOXVKeWtLSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS2JHOWpZV3dnWm5WdVkzUnBiMjRnWVdOMGFXOXVLQ2tLSUNBZ0lDMHRJRkpsWjJsemRHVnlJSE53Wld4c1ltOXZheUJsZG1WdWRITWdLRXhGVFMxellXWmxLUW9nSUNBZ2JYRXVaWFpsYm5Rb0owSmxaMmx1VFdWdGIzSnBlbWx1Wnljc0lDSWpLaU5DWldkcGJtNXBibWNnZEc4Z2JXVnRiM0pwZW1VZ0l6RWpMaTR1SXlvaklpd2dSWFpsYm5SZlFtVm5hVzVOWlcxdmNtbDZhVzVuS1FvZ0lDQWdiWEV1WlhabGJuUW9KMFpwYm1semFFMWxiVzl5YVhwcGJtY25MQ0FpSXlvaldXOTFJR2hoZG1VZ1ptbHVhWE5vWldRZ2JXVnRiM0pwZW1sdVp5QWpNU01qS2lNaUxDQkZkbVZ1ZEY5RmJtUk5aVzF2Y21sNmFXNW5LUW9nSUNBZ2JYRXVaWFpsYm5Rb0owRmliM0owVFdWdGIzSnBlbWx1Wnljc0lDSWpLaU5CWW05eWRHbHVaeUJ0WlcxdmNtbDZZWFJwYjI0Z2IyWWdjM0JsYkd3dUl5b2pJaXdnUlhabGJuUmZSVzVrVFdWdGIzSnBlbWx1WnlrS0NpQWdJQ0JzYjJOaGJDQnZheXdnWlhKeUlEMGdjR05oYkd3b1VuVnVUVzl1YzNSbGNrMWhibUVwQ2lBZ0lDQnBaaUJ1YjNRZ2Iyc2dkR2hsYmlCT2IzUmxMa2x1Wm04b0oxeGhja1Z5Y205eU9seGhlQ0FsY3ljc0lIUnZjM1J5YVc1bktHVnljaWtwSUdWdVpBcGxibVFLQ25KbGRIVnliaUI3WTI5dVpHWjFibU05WTI5dVpHbDBhVzl1TENCaFkzUnBiMjVtZFc1alBXRmpkR2x2Ym4wSyIsCn0=[/CODE]

[CODE lang="Lua" title="LEM Endless Mana"]local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
local my_class = mq.TLO.Me.Class.ShortName()
local my_mana = mq.TLO.Me.PctMana()
local check_paused = mq.TLO.CWTN.Paused()
local mm_status = mq.TLO.Lua.Script('MMbrute').Status()
return my_class == 'MAG' and my_mana < 20 and mm_status ~= 'RUNNING' and check_paused == false
end

-----------------------------------------------------------------------
-- Everything below runs inside LEM's action() when the condition is met
-----------------------------------------------------------------------

-- Lightweight logger (self-contained)
local Note = { prefix = 'MonsterMana', loglevel = 'info' }
function Note.Info(fmt, ...) print(('\ag[%s]\ax '..fmt):format(Note.prefix, ...)) end

-- State / config
local workingStates = { Active=true, Cooldown=true, Resting=true }
local MonsterSummoning, MonsterSummoningSpell
local GatherMana, GatherManaSpell
local ReclaimSet, ReclaimItem
local MiscSpellGem = 8 -- using gem 8
local IsMemorizing = false
local didSuspendMainPet = false -- NEW: track whether we actually suspended a main pet this run

-- -----------------------------
-- Helpers
-- -----------------------------
local function CheckPlugin(plugin)
if not mq.TLO.Plugin(plugin)() then
mq.cmdf('/squelch /plugin %s noauto', plugin)
Note.Info('\aw%s\ax not detected. Loading…', plugin)
end
end

-- Simple movement check: only your avatar’s motion.
local function IsMoving()
return mq.TLO.Me.Moving() or ((mq.TLO.Me.Speed() or 0) > 0)
end

-- Wait until we’ve been NOT moving for a continuous window (ms). No attempt limit.
local function WaitStill(min_ms)
min_ms = min_ms or 400
local stillStart = nil
while true do
if IsMoving() then
stillStart = nil
else
stillStart = stillStart or mq.gettime()
if (mq.gettime() - stillStart) >= min_ms then return true end
end
mq.delay(50)
end
end

-- Robust “am I in combat?” check
local function InCombat()
local cs = tostring(mq.TLO.Me.CombatState() or '')
if cs ~= '' and cs:upper() == 'COMBAT' then return true end
if mq.TLO.Me.Combat and mq.TLO.Me.Combat() then return true end
return false
end

local function ChooseAbility(set)
local chosenSpell, highestLevel = nil, 0
for _, name in ipairs(set) do
local s = mq.TLO.Spell(name)
local lvl, rank = s.Level(), s.RankName()
if rank and mq.TLO.Me.Book(rank)() and lvl > highestLevel then
chosenSpell = (mq.TLO.Me.SpellRankCap() > 1) and s.RankName() or s.BaseName()
highestLevel = lvl
end
end
return chosenSpell
end

local function ChooseItem(set)
for _, name in ipairs(set) do
if mq.TLO.FindItemCount(name)() > 0 then return name end
end
end

-- Spellbook events (registered inside action())
local function Event_BeginMemorizing(_, _) IsMemorizing = true end
local function Event_EndMemorizing(_, _) IsMemorizing = false end

-- Ensure spell is in a specific gem (blocking, no attempt limit). Only starts when stationary.
local function EnsureSpellInGem(spellToMem, gem)
gem = gem or MiscSpellGem
while true do
if mq.TLO.Me.Gem(spellToMem)() == gem then return gem end
local rn = mq.TLO.Spell(spellToMem).RankName()
if not rn or not mq.TLO.Me.Book(rn)() then
Note.Info('Cannot memorize (not in book): %s', tostring(spellToMem))
return
end
if not mq.TLO.Me.Gem(gem)() and gem ~= MiscSpellGem then gem = MiscSpellGem end
WaitStill(600)
Note.Info('\agMemming\ax "%s" into gem %d', rn, gem)
mq.cmdf('/memspell %d "%s"', gem, rn)
mq.delay(2000, function() return IsMemorizing or mq.TLO.Me.Gem(gem).Name() == rn end)
mq.delay(10000, function() return mq.TLO.Me.Gem(gem).Name() == rn or not IsMemorizing end)
if mq.TLO.Me.Gem(gem).Name() == rn then return gem end
end
end

-- Pet proximity helpers (with optional timeout to prevent hangs)
local function PetNear(maxDist) return (mq.TLO.Me.Pet.Distance() or 9999) <= (maxDist or 12) end
local function WaitPetNear(maxDist, timeout_ms)
maxDist = maxDist or 12
local start = mq.gettime()
while true do
if (mq.TLO.Me.Pet.ID() or 0) == 0 then return false end
if PetNear(maxDist) then return true end
if timeout_ms and (mq.gettime() - start) >= timeout_ms then return PetNear(maxDist) end
mq.delay(50)
end
end

-- Suspend pet with full sequence every pass.
-- Only use CoTH AA (7050) if we are IN COMBAT.
-- Returns TRUE only if the pet ends up suspended (ID == 0).
local function SuspendPrimaryPet_Blocking()
local origID = mq.TLO.Me.Pet.ID() or 0
if origID == 0 then return false end -- nothing to suspend

Note.Info('Storing Pet (ID %s)', tostring(origID))

while (mq.TLO.Me.Pet.ID() or 0) > 0 do
-- Full sequence: ghold -> spellhold -> back -> Summon Companion (1215) -> (CoTH if IN COMBAT) -> suspend
WaitStill(400)
mq.cmd('/pet ghold on') ; mq.delay(300)
mq.cmd('/pet spellhold on'); mq.delay(300)
mq.cmd('/pet back') ; mq.delay(300)

-- Summon Companion RIGHT BEFORE suspending, if ready (don’t block for CD)
if mq.TLO.Me.AltAbilityReady(1215)() or mq.TLO.Me.AltAbilityReady('Summon Companion')() then
WaitStill(300)
mq.cmd('/alt act 1215')
mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
WaitPetNear(12, 3000)
end

-- Only do CoTH if we are actually in combat
if InCombat() and mq.TLO.Me.AltAbilityReady(7050)() then
WaitStill(300)
mq.cmdf('/target id %d', mq.TLO.Me.ID() or 0)
mq.delay(200)
Note.Info('Using CoTH AA to wipe personal aggro (in combat).')
mq.cmd('/alt act 7050')
mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
end

-- Attempt to suspend
WaitStill(400)
if mq.TLO.Me.AltAbilityReady(176)() or mq.TLO.Me.AltAbilityReady('Suspend Minion')() then
Note.Info('Suspending Minion…')
mq.cmd('/alt act 176')
mq.delay(500)
mq.delay(3000, function() return not mq.TLO.Me.Casting.ID() end)
end

if (mq.TLO.Me.Pet.ID() or 0) == 0 then
Note.Info('Pet suspended.')
return true
end

-- Redo the entire sequence until success.
mq.delay(200)
end

return ((mq.TLO.Me.Pet.ID() or 0) == 0)
end

-- Core mana loop: summon monster pet (gem 8) & reclaim until 95% mana.
local function ReclaimMana()
Note.Info('Mana Loop Started')
mq.cmd('/squelch /beepontells off')

while (mq.TLO.Me.PctMana() or 100) < 95 do
if mq.TLO.Cursor.ID() then
mq.cmd('/autoinventory')
mq.delay(2000)
mq.cmd('/autoinventory')
end

if (mq.TLO.Me.PctMana() or 100) < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)() then
WaitStill(400)
mq.cmdf('/cast "%s"', GatherManaSpell)
mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)

elseif (mq.TLO.Me.CurrentMana() or 0) < (mq.TLO.Spell(MonsterSummoningSpell).Mana() or 0) then
if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
mq.delay(6050)

else
if mq.TLO.Me.Sitting() then mq.TLO.Me.Stand() end
mq.delay(250)

-- Ensure spell in gem 8
local actualGem = EnsureSpellInGem(MonsterSummoningSpell, MiscSpellGem)
if not actualGem then
Note.Info('Could not load Monster Summoning into gem %d; exiting mana loop.', MiscSpellGem)
break
end

-- Cast Monster Summoning
WaitStill(400)
if mq.TLO.Me.SpellReady(MonsterSummoningSpell)() then
mq.cmdf('/cast %d', actualGem)
end
mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)

-- Reclaim immediately if a pet is up
if (mq.TLO.Me.Pet.ID() or 0) > 0 and ReclaimItem then
WaitStill(200)
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
end
end

mq.delay(50)
end

Note.Info('Mana Loop Ended')
-- final cleanup: if temp pet still up, reclaim until gone
while (mq.TLO.Me.Pet.ID() or 0) > 0 do
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
end
end

-- Init spells/items
local function Init()
CheckPlugin('MQ2XAssist')
CheckPlugin('MQ2AdvPath')
CheckPlugin('MQ2MoveUtils')
CheckPlugin('MQ2Boxr')

MonsterSummoning = {
"Monster Summoning XV",
"Monster Summoning XIV",
"Monster Summoning XIII",
}
MonsterSummoningSpell = ChooseAbility(MonsterSummoning)
if not MonsterSummoningSpell then
Note.Info('A monster summoning spell is not available')
return false
end

-- Updated Gather line (includes level 125)
GatherMana = {
"Gather Zeal",
"Gather Vigor",
"Gather Potency",
}
GatherManaSpell = ChooseAbility(GatherMana)
if not GatherManaSpell then
Note.Info('A gather mana spell is not available')
return false
end

ReclaimSet = {
"Staff of Elemental Mastery: Earth",
"Staff of Elemental Mastery: Fire",
"Staff of Elemental Mastery: Air",
"Staff of Elemental Mastery: Water",
"Broom of Trilon",
"Ancient Torch of Alna",
"Gemmed Gloves of Guile",
"Gloves of Dark Summoning",
"Shovel of Ponz",
"Stein of Ulissa",
"Torch of Alna",
}
ReclaimItem = ChooseItem(ReclaimSet)
if not ReclaimItem then
Note.Info('No reclaim item found in inventory')
return false
end

return true
end

-- Main routine (merged into LEM action)
local function RunMonsterMana()
if mq.TLO.Me.Class.ShortName() ~= 'MAG' then
Note.Info('MonsterMana only works for Mage characters')
return false
end
if (mq.TLO.Me.PctMana() or 100) > 95 then
Note.Info('Mana is nearly full; nothing to do')
return false
end
if not Init() then
Note.Info('Initialization unsuccessful')
return false
end

mq.cmd('/squelch /docommand /boxr pause')
mq.delay(300)
mq.cmd('/squelch /attack off')

-- clear cursor
while mq.TLO.Cursor.ID() do
mq.cmd('/autoinventory')
mq.delay(500)
end

-- If we already have a main pet, suspend it FIRST (blocking) and remember that we did.
if (mq.TLO.Me.Pet.ID() or 0) > 0 then
Note.Info('Primary mana method (with pet)')
local suspendedOK = SuspendPrimaryPet_Blocking()
if not suspendedOK then
Note.Info('Unable to suspend pet safely; aborting.')
mq.cmd('/squelch /docommand /boxr unpause')
return false
end
didSuspendMainPet = true
else
-- No-pet fallback: build to 8% with Gather or sitting
Note.Info('Primary mana method (no pet)')
while (mq.TLO.Me.PctMana() or 0) < 8 do
local rankName = mq.TLO.Spell(GatherManaSpell).RankName()
if mq.TLO.Me.SpellReady(rankName)() then
WaitStill(400)
mq.cmdf('/cast "%s"', rankName)
mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
elseif workingStates[mq.TLO.Me.CombatState() or ''] then
if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
mq.delay(6050)
end
mq.delay(150)
end
end

-- Run mana loop (summon/reclaim)
ReclaimMana()

-- Restore main pet ONLY if we previously suspended it this run (prevents infinite loop after death).
if didSuspendMainPet then
Note.Info('Restoring main pet (unsuspending)')
while (mq.TLO.Me.Pet.ID() or 0) == 0 do
WaitStill(400)
mq.cmd('/alt act 176')
mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)
end
-- If a Monster Summoning warrior pet popped instead, reclaim and try again.
while (mq.TLO.Me.Pet.Class.Name() or '') == 'Warrior' do
if ReclaimItem then
mq.cmdf('/useitem %s', ReclaimItem)
mq.delay(500)
else
break
end
while (mq.TLO.Me.Pet.ID() or 0) == 0 do
WaitStill(400)
mq.cmd('/alt act 176')
mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
mq.delay(300)
end
end
else
Note.Info('No suspended main pet to restore (likely started with no pet).')
end

mq.delay(300)
mq.cmd('/pet hold')
mq.delay(300)
mq.cmd('/squelch /docommand /boxr unpause')
mq.delay(300)
Note.Info('Mana routine complete. Mage mana now: \ag%s', tostring(mq.TLO.Me.PctMana()))
mq.cmd('/squelch /beepontells on')
return true
end

local function action()
-- Register spellbook events (LEM-safe)
mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

local ok, err = pcall(RunMonsterMana)
if not ok then Note.Info('\arError:\ax %s', tostring(err)) end
end

return {condfunc=condition, actionfunc=action}
[/CODE]
 
Release Endless Mana for MQ2Mage

Users who are viewing this thread

Back
Top
Cart