From adfbdcad92cf80f8af1525a264b2464faeb0ae31 Mon Sep 17 00:00:00 2001 From: Taracque Date: Sat, 17 Oct 2015 00:00:03 +0200 Subject: [PATCH] Swing frame removed, added a sound for soul reaper. --- DKCrutch.lua | 126 +++++++++---------------------------------------- DKCrutch.toc | 2 +- DKCrutch_GUI.lua | 81 +------------------------------ locales/enUS.lua | 4 +- media/soul_reaper.ogg | Bin 0 -> 12382 bytes 5 files changed, 27 insertions(+), 186 deletions(-) create mode 100755 media/soul_reaper.ogg diff --git a/DKCrutch.lua b/DKCrutch.lua index 8fa8d8b..133a92c 100755 --- a/DKCrutch.lua +++ b/DKCrutch.lua @@ -1,5 +1,5 @@ ------------------------------------------------------------------------------- --- DKCrutch 1.1.1 +-- DKCrutch 1.1.2 -- -- Death Knight rune tracker and ability advisor ------------------------------------------------------------------------------- @@ -8,7 +8,7 @@ DKCrutch = {Locals = {}} local L = DKCrutch.Locals -DKCrutch.versionNumber = '1.1.1' +DKCrutch.versionNumber = '1.1.2' DKCrutch.talent = "" DKCrutch.talentUnsure = true DKCrutch.DebugMode = false @@ -42,7 +42,7 @@ DKCrutch.SpellList = { ["Death Strike"] = GetSpellInfo(49998), ["Blood Boil"] = GetSpellInfo(50842), ["Soul Reaper"] = GetSpellInfo(130736), --- talent specifig +-- talent specific ["Plague Leech"] = GetSpellInfo(123693), ["Blood Tap"] = GetSpellInfo(45529), ["Blood Charge"] = GetSpellInfo(114851), @@ -168,89 +168,6 @@ function DKCrutch.events.PLAYER_LOGIN() DKCrutch.eventFrame:UnregisterEvent("PLAYER_LOGIN") end -function DKCrutch:SetSwingBarWidth(element, time, speed, maxwidth) - --DKCrutch:Debug("SetSwingBarWidth" .. " t: " .. time .." s:" .. speed , maxwidth) - local width = ( time / speed * maxwidth ); - if ( width < 1 ) then - width = 1; - elseif ( width > maxwidth ) then - width = maxwidth; - end - element:SetValue(width); -end - -function DKCrutch:GetSwingSpeed(element) - local mainhand,offhand = UnitAttackSpeed("player"); - if ( DKCrutch.dualWield ) and ( element.SLOT == GetInventorySlotInfo("SecondaryHandSlot") ) then - return(offhand); - else - return(mainhand); - end -end - -function DKCrutch:SetSwingSpeed(element, speed) - if ( speed == nil ) then - element.speed = DKCrutch:GetSwingSpeed(element); - if ( element.speed == nil ) then - element:Hide(); - return(nil); - end - else - element.speed = speed; - end - _,_,element.latency = GetNetStats(); - element.latency = element.latency / 1000; - DKCrutch:Debug("SwingFrame l: " .. element.latency .." s:" .. element.speed , element.maxwidth) - DKCrutch:SetSwingBarWidth(element, element.latency, element.speed, element.maxwidth); -end - -function DKCrutch:ResetSwingFrame(element) - element:SetScript("OnUpdate", nil); - element.lastupdate = 0; - element.maxwidth = 128; - element.elapsed = 0; - DKCrutch:SetSwingSpeed(element); - element:SetMinMaxValues(0, element.maxwidth); - element:SetValue(0); - element.active = nil; - element:Show(); - element.vanish = 0; -end - -function DKCrutch.VanishFrame(element,elapsed) - --DKCrutch:Debug("VanishFrame", elapsed) - if ( element.vanish > 0 ) then - element.vanish = element.vanish - elapsed; - if ( element.vanish <= 0 ) then - element:SetScript("OnUpdate", nil); - element:Hide(); - end - end -end - -function DKCrutch.UpdateSwingFrame(element,elapsed) - -- performance throttle - element.lastupdate = element.lastupdate + elapsed; - if ( element.lastupdate < 0.03 ) then - return(nil); - end - element.elapsed = element.elapsed + element.lastupdate; - element.lastupdate = 0; - - -- flag the swing timer as inactive early to help account for lag - if ( element.elapsed > (element.speed - element.latency ) ) then - element.active = nil; - end - - if ( element.elapsed > element.speed ) then - DKCrutch:ResetSwingFrame(element); - element.vanish = 2.5; - element:SetScript("OnUpdate", DKCrutch.VanishFrame); - end - - DKCrutch:SetSwingBarWidth(element, element.elapsed, element.speed, element.maxwidth); -end - function DKCrutch.events.COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaster, srcGUID, srcName, srcFlags, srcRaidFlags, dstGUID, dstName, dstFlags, dstRaidFlags, spellId, spellName, spellSchool, damage, ...) if(DKCrutchDB.enabled) and (srcName == DKCrutch.playerName) then DKCrutch:Update() @@ -258,13 +175,6 @@ function DKCrutch.events.COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaste -- enemy count for AoE advise and multiple player in combat (for aggro warning) DKCrutch:CountPerson(timestamp, event, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags) end - if (not DKCrutchDB.swingDisable) then - if ( string.sub(event,1,5) == "SWING" ) and ( srcGUID == UnitGUID("player") ) then - -- reset the swing frame to 0 - DKCrutch:ResetSwingFrame(DKCrutch.swingFrame); - DKCrutch.swingFrame:SetScript("OnUpdate", DKCrutch.UpdateSwingFrame); - end - end end end @@ -597,7 +507,7 @@ function DKCrutch:ProcIcon(name,icon,d,e,value) end -- returns true, if diseases expires on target --- diseaseType : 0 for any, 1 for Frost Fever of Necrotic Plague, 2 for Blood Plague or Necrotic Plague +-- diseaseType : 0 for any, 1 for Frost Fever or Necrotic Plague, 2 for Blood Plague or Necrotic Plague, 3 for Necrotic Plage or Blood Plage and Frost Fever -- expirationTime : 0 for expired, otherwise check expiration time between 1 and expirationTime function DKCrutch:DiseaseExpires(diseaseType,expirationTime) diseaseType = diseaseType or 0; @@ -620,13 +530,20 @@ function DKCrutch:DiseaseExpires(diseaseType,expirationTime) expired = expired or (ffExpiration < 2); end end - if (diseaseType == 2) or (diseaseType == 0) then -- Check blood plague + if (diseaseType == 2) or (diseaseType == 0) then -- Check blood plagued if (expirationTime>0) then expired = expired or ((bpExpiration > 1) and (bpExpiration < expirationTime)); else expired = expired or (bpExpiration < 2); end end + if (diseaseType == 3) then -- Check both diseases + if (expirationTime>0) then + expired = expired or (((bpExpiration > 1) and (bpExpiration < expirationTime)) and ((ffExpiration > 1) and (ffExpiration < expirationTime))); + else + expired = expired or ((bpExpiration < 2) and (ffExpiration < 2)); + end + end return expired; end @@ -886,7 +803,7 @@ function DKCrutch:AdviseFrostAbilityDW() -- Frost DK DualWield priority end end if (DKCrutch.tier1talent == 19166) and (DKCrutch.SpellList["Plague Leech"]) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech"; end end @@ -976,10 +893,10 @@ function DKCrutch:AdviseFrostAbilityDW() -- Frost DK DualWield priority return "Howling Blast" end - -- Plague Leech if Outbreak available, and have on fully depleted rune + -- Plague Leech if Outbreak available, and have on fully depleted rune, and have disease on target if (DKCrutch.SpellList["Plague Leech"]) then if (obcd) and (obcd<=0) and (IsSpellInRange(DKCrutch.SpellList["Outbreak"], "target") == 1) and (DKCrutch.depletedCount>0) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1 ) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1 ) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech" end end @@ -1052,7 +969,7 @@ function DKCrutch:AdviseFrostAbility() end end if (DKCrutch.tier1talent == 19166) and (DKCrutch.SpellList["Plague Leech"]) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech"; end end @@ -1181,13 +1098,13 @@ function DKCrutch:AdviseUnholyAbility() if (DKCrutch.tier1talent == 19166) and (DKCrutch.SpellList["Plague Leech"]) then -- if outbreak available if (obcd) and (obcd<=1) and (IsSpellInRange(DKCrutch.SpellList["Outbreak"], "target") == 1) and (DKCrutch.depletedCount>0) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech"; end end -- or if diseases will expire in 2 sec on target if (DKCrutch:DiseaseExpires()) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,2)) then return "Plague Leech"; end end @@ -1291,7 +1208,7 @@ function DKCrutch:AdviseUnholyAbility() end end if (DKCrutch.tier1talent == 19166) and (DKCrutch.SpellList["Plague Leech"]) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech"; end end @@ -1402,7 +1319,7 @@ function DKCrutch:AdviseUnholyAbility() -- Plague Leech if (DKCrutch.tier1talent == 19166) and (DKCrutch.SpellList["Plague Leech"]) then - if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) then + if (DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Plague Leech"]) <= 1) and (DKCrutch:DiseaseExpires(3,99)) then return "Plague Leech"; end end @@ -1470,6 +1387,9 @@ function DKCrutch:Update() if (not DKCrutchDB.advisorDisabled) then local spell = DKCrutch:AdviseAbility( not ((UnitHealth("target") == 0) or (guid == nil)) ) + if (spell == "Soul Reaper") and (DKCrutchDB.srSoundEnable) and (DKCrutch.lastSpell ~= "Soul Reaper") then + PlaySoundFile("Interface\\AddOns\\DKCrutch\\media\\soul_reaper.ogg"); + end DKCrutch:Debug("Advised: " .. spell, DKCrutch.SpellList[spell]) if (spell) and (spell ~= "") then local inRange = IsSpellInRange(DKCrutch.SpellList[spell],"target") diff --git a/DKCrutch.toc b/DKCrutch.toc index a3a1bbd..be36549 100755 --- a/DKCrutch.toc +++ b/DKCrutch.toc @@ -2,7 +2,7 @@ ## Title: DKCrutch ## Notes: Death Knight rune tracker and rotation helper ## Author: Taracque, Dšgrov‡s of Arathor -## Version: 1.1.1 +## Version: 1.1.2 ## SavedVariables: DKCrutchDB ## OptionalDeps: ## Dependencies: diff --git a/DKCrutch_GUI.lua b/DKCrutch_GUI.lua index 2a8fb11..070e226 100755 --- a/DKCrutch_GUI.lua +++ b/DKCrutch_GUI.lua @@ -139,8 +139,6 @@ function DKCrutch:ApplySettings() DKCrutch.runicFrame:SetMovable(false) DKCrutch.debuffFrame:EnableMouse(false) DKCrutch.debuffFrame:SetMovable(false) - DKCrutch.swingFrame:EnableMouse(false) - DKCrutch.swingFrame:SetMovable(false) end end if ( DKCrutchDB.enabled ) then @@ -175,11 +173,6 @@ function DKCrutch:ApplySettings() else DKCrutch.displayFrame:Hide() end - if (not DKCrutchDB.swingDisabled) then - DKCrutch.swingFrame:Show() - else - DKCrutch.swingFrame:Hide() - end end else DKCrutch.eventFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED") @@ -193,7 +186,6 @@ function DKCrutch:ApplySettings() DKCrutch.weaponFrame:Hide() DKCrutch.runicFrame:Hide() DKCrutch.debuffFrame:Hide() - DKCrutch.swingFrame:Hide() end end if (DKCrutch.displayFrame) then @@ -209,8 +201,6 @@ function DKCrutch:ApplySettings() DKCrutch.runicFrame:SetScale(DKCrutchDB.runic.scale) DKCrutch.debuffFrame:SetAlpha(DKCrutchDB.debuff.alpha) DKCrutch.debuffFrame:SetScale(DKCrutchDB.debuff.scale) - DKCrutch.swingFrame:SetAlpha(DKCrutchDB.swing.alpha or 1) - DKCrutch.swingFrame:SetScale(DKCrutchDB.swing.scale or 1) end end @@ -452,40 +442,8 @@ function DKCrutch:CreateConfig() local weaponDisableBtn = DKCrutch:CreateCheckButton(L.CONFIG_DISABLE_WEAPON, DKCrutch.configPanel, DKCrutchDB, "weaponDisabled", false) weaponDisableBtn:SetPoint('TOPLEFT', 10, -418) - local swingScale = DKCrutch:CreateSlider(L.CONFIG_SWING_SCALE, DKCrutch.configPanel, .25, 3, .1) - swingScale:SetScript('OnShow', function(self) - self.onShow = true - self:SetValue(DKCrutchDB.swing.scale) - self.onShow = nil - end) - swingScale:SetScript('OnValueChanged', function(self, value) - self.valText:SetText(format('%.1f', value)) - if not self.onShow then - DKCrutchDB.swing.scale=value - DKCrutch.swingFrame:SetScale(value) - end - end) - swingScale:SetPoint("TOPLEFT",10,-458) - swingScale:Show() - - local swingAlpha = DKCrutch:CreateSlider(L.CONFIG_SWING_ALPHA, DKCrutch.configPanel, .0, 1, .1) - swingAlpha:SetScript('OnShow', function(self) - self.onShow = true - self:SetValue(DKCrutchDB.swing.alpha) - self.onShow = nil - end) - swingAlpha:SetScript('OnValueChanged', function(self, value) - self.valText:SetText(format('%.1f', value)) - if not self.onShow then - DKCrutchDB.swing.alpha=value - DKCrutch.swingFrame:SetAlpha(value) - end - end) - swingAlpha:SetPoint("TOPLEFT",200,-458) - swingAlpha:Show() - - local swingDisableBtn = DKCrutch:CreateCheckButton(L.CONFIG_DISABLE_SWING, DKCrutch.configPanel, DKCrutchDB, "swingDisabled", false) - swingDisableBtn:SetPoint('TOPLEFT', 10, -478) + local srSoundEnableBtn = DKCrutch:CreateCheckButton(L.CONFIG_ENABLE_SRSOUND, DKCrutch.configPanel, DKCrutchDB, "srSoundEnable", false) + srSoundEnableBtn:SetPoint('TOPLEFT', 10, -438) local ResetBtn = DKCrutch:CreateButton(L.CONFIG_RESET_POSITIONS, DKCrutch.configPanel) ResetBtn:SetWidth(160) @@ -621,15 +579,6 @@ function DKCrutch:ResetDB() ["relativePoint"] = "CENTER", } end - if (not DKCrutchDB.swing) or (force) then - DKCrutchDB.swing = { - ["x"] = -20, - ["y"] = 180, - ["scale"] = 1, - ["alpha"] = 1, - ["relativePoint"] = "CENTER", - } - end if (force) then DKCrutchDB.locked = false DKCrutchDB.enabled = true @@ -638,7 +587,6 @@ function DKCrutch:ResetDB() DKCrutchDB.weaponDisabled = false DKCrutchDB.runicDisabled = false DKCrutchDB.debuffDisabled = false - DKCrutchDB.swingDisabled = false end end @@ -691,9 +639,6 @@ function DKCrutch:ResetPosition() DKCrutchDB.debuff.x = 0 DKCrutchDB.debuff.y = 180 DKCrutchDB.debuff.relativePoint = "CENTER" - DKCrutchDB.swing.x = -20 - DKCrutchDB.swing.y = 180 - DKCrutchDB.swing.relativePoint = "CENTER" DKCrutch.displayFrame:ClearAllPoints() DKCrutch.displayFrame:SetPoint(DKCrutchDB.runes.relativePoint,DKCrutchDB.runes.x,DKCrutchDB.runes.y) @@ -705,8 +650,6 @@ function DKCrutch:ResetPosition() DKCrutch.weaponFrame:SetPoint(DKCrutchDB.weapon.relativePoint,DKCrutchDB.weapon.x,DKCrutchDB.weapon.y) DKCrutch.debuffFrame:ClearAllPoints() DKCrutch.debuffFrame:SetPoint(DKCrutchDB.debuff.relativePoint,DKCrutchDB.debuff.x,DKCrutchDB.debuff.y) - DKCrutch.swingFrame:ClearAllPoints() - DKCrutch.swingFrame:SetPoint(DKCrutchDB.swing.relativePoint,DKCrutchDB.swing.x,DKCrutchDB.swing.y) end function DKCrutch:MakeDraggable(frame,store) @@ -756,7 +699,6 @@ function DKCrutch:ShowHideFrames( visible ) DKCrutch.weaponFrame:Show(); DKCrutch.runicFrame:Show(); DKCrutch.debuffFrame:Show(); - DKCrutch.swingFrame:Show(); else DKCrutch.displayFrame:Hide(); DKCrutch.advisorFrame:Hide(); @@ -764,7 +706,6 @@ function DKCrutch:ShowHideFrames( visible ) DKCrutch.weaponFrame:Hide(); DKCrutch.runicFrame:Hide(); DKCrutch.debuffFrame:Hide(); - DKCrutch.swingFrame:Hide(); end end @@ -775,7 +716,6 @@ function DKCrutch:UnLockFrames() DKCrutch:MakeDraggable(DKCrutch.weaponFrame,"weapon") DKCrutch:MakeDraggable(DKCrutch.runicFrame,"runic") DKCrutch:MakeDraggable(DKCrutch.debuffFrame,"debuff") - DKCrutch:MakeDraggable(DKCrutch.swingFrame,"swing") end function DKCrutch:CreateGUI() @@ -975,23 +915,6 @@ function DKCrutch:CreateGUI() DKCrutch.debuffFrame = debuffFrame - local swingFrame = CreateFrame("StatusBar", "DKCrutchSwingFrame", UIParent) - swingFrame:SetFrameStrata("BACKGROUND") - swingFrame:SetWidth(128) - swingFrame:SetHeight(8) - swingFrame:SetBackdrop({ - bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 32, - }) - swingFrame:SetOrientation("HORIZONTAL") - swingFrame:SetMinMaxValues(0, 128) - swingFrame:SetValue(0) - swingFrame:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar") - swingFrame:SetStatusBarColor(0,0,0,1) - swingFrame:SetAlpha(DKCrutchDB.swing.alpha or 1) - swingFrame:SetPoint(DKCrutchDB.swing.relativePoint or "CENTER",DKCrutchDB.swing.x or -20,DKCrutchDB.swing.y or 180) - - DKCrutch.swingFrame = swingFrame - if (not DKCrutchDB.locked) then DKCrutch:UnLockFrames() end diff --git a/locales/enUS.lua b/locales/enUS.lua index a346e6d..40a4f10 100755 --- a/locales/enUS.lua +++ b/locales/enUS.lua @@ -25,7 +25,5 @@ if GetLocale() then L.CONFIG_WEAPON_SCALE = "Weapon proc tracker scale" L.CONFIG_WEAPON_ALPHA = "Weapon proc tracker alpha" L.CONFIG_DISABLE_WEAPON = "Disable weapon proc tracker" - L.CONFIG_SWING_SCALE = "Swing frame scale" - L.CONFIG_SWING_ALPHA = "Swing frame alpha" - L.CONFIG_DISABLE_SWING = "Disable swing frame" + L.CONFIG_ENABLE_SRSOUND = "Play sound when Soul Repaer should be user" end \ No newline at end of file diff --git a/media/soul_reaper.ogg b/media/soul_reaper.ogg new file mode 100755 index 0000000000000000000000000000000000000000..fa7c5982ea51eb2ccbf6cdcf9a8a84f90b11071d GIT binary patch literal 12382 zcmch7cT`hd({HfQlqy|75CTLg(mP6rPz}99=v}&iG)1M?(3=RMgHl2jcn}D^_bN)0 zE;RxI_XOYP`_^~=xa+QU*Scq&oXp;{_ss11&CK2@8n(7tpc|n7TzJ*N>{v3pMc5IC z5y#ur9d7S|?ZA1ci+uxuG~55a7vpGPXa3iPorwdq)Mo4TNV%^5$94DSUqK82U*G

W|%pTRW?ivE!ah4sn}o@A=48w9H#@qPROU%({xwnTF>;zqtWYk`^f}Q zt4y~2ZUkU}iVFw zmm}f_2QevK6(Oh_1R{OrMxhu_p;AfTH^NGUPh@Z#a0Un;7^n0uUnv5qA7f*m&F1%! zBmLu}(klDjD$c&Dtw!$a=}G`F&nY@zP~ct9vjTze%{e0SL}FI-6Oabkc%kpgZh(S8 zpj*JWyNZ<*YWu812NFYv|NH${EfWX?dd*=)bMs#a@R{joWwT)9#)MQd^klLOGJ~?k z$Tv%nw_wXrtukqR=2v@?m_`4+zYvguKo%4tVIf_t_{^bj3U)cS0w#c3W!3NX{mF{I z@P<^TKGVOi0hn>^3Sf=@FolxJ0Aqj$Bp(4&f)u2}BOqP$9{s#sOmFV;{rr%qF4mKu zpf1+Snim6egrF$2R4Z4hEXz@onI4~{A(m0RXqx|iuw1(VSTHFrtyLUgU?|14Pu)F4a}(Ak z$<_-fXOl@2lPRzNd0#I*_!cNQW(Dv%a4W^+D-m9U6NdvL1qJ7cL@X--c*KAW64>mM zZGDpqebbA=8Lx)`zyMwYuHcW?u(28>7uaVPV!U{bH*%RvK_CJU zh@s1kUeS%d%MH7#YY#Ks1Tld?vd`(|-8s7w1XO@Ej>!!j89x{D($aJO7X)Ak_UiJG z0PY^Z6#$Vap*$v__J4U}9eV==1Rp(0*JH2weUzwD8YFd1bs4`LZSfD0wawIY>)Fed?!-k=9woS}d%w?J+;K=?9) z%xEULC~16fK81`D1b$a$Efdi%3PB7e#ph*3j;F>V;mRcpusm@%l_lbHyE*_R{64FOTaGEjz41PscRj4akr3gfrJ^ z02I)t@8|%;5*(;chK_0gWf;Xfsqa`06nAzE= zGX`IW>~p|VykWc@G_PZnyIJLk`8a41xH3w`d5Gtaz{zy{P;ddcw_zKI9C?&J=~C4rtXfmO@G?s&+g*2A^z+R*UI0V>` zt{F1;v;YI}8L&TLi!iWL0Yx|$>v`tT;cF+!09Y0Mg9BpvM|p)E?nZEQ61%8RuBNb}1K-ln`VMl@Z`|z)R&Qpow)=6axSZw78Q-9RJ#{DDP`b zXdH=<`BX+_s7X3ta3_spIST7_6d)Tw3}_0j-vIq{j~*0E=%ml^J>QP=^Yt2WfoM%~Pz11ZfI%ShYdb^vH0`>fASOx>=*c@QXn0O3)UZ!}@hasWjRB$CRqj2DfKs7^Y|XfTq> zvAki@Pz7iLMmA7^f`^wtAaC>bO?-BF%aFJ4%5H%UfE@@3Z2)`#4PJDrhY|#d#Q=E3 z06<_Fz=;IQ7!(B#G5`jdmH=x10S9Pe89)<@8bAT(q1(j3sX!>gN&N}A_VpTpYWEBX zbs7(K8E7M_kBRX(ccc28$@KC6;l3 zB#pux%WZ&UL*^&L%eVmW0jwq+%Cka&bV8x@9q%$D5WtXHI!6c+ne0$jIjJuTDMn7i z%TQ=Tpsu0l9LvgqQlL^kVF+x;R3P&Mzzs>}%Xc3u+rG_fyY_?oO%Q%44K}F22y6<; zLI0*C2jF~II5y+)ase2Cnw$VIJb{eIGL*r9tMHf+KuTgkx=vUu1NsP@bRDyQXTX4> z31ItoMv}G|5V+S280--;lw1Y^PQo^UV+G+~QTYi_C?ts-t3w+|>?Ca%1oBt8HWUg5 z#NcB^L5cw`Fz;HqHed_TsSLcZr2zX(LSTggwm^{DhR|Z53*aIQfldUVHy`lcwb1|< zh_j@Bo7kz!#rfJWU|IqUz!MLPr-HU&SeA{k@2waPtJL7@{0hAZ0{urscobIOwbK7j z54wL%Csc-j0pH>?%iMU@$cNon%arwaU?%9F=AIk9+;*NX-2% zorbi0Q_1_}?JKMS5#Jr|e!BtUwTL3Xp58lv!&E2@Iu$sU0%?7n$1&1BnXr`>o6NT5 z*cuAdHNdIndN%eG3T|5Lz9V=c8b8AZy5m%eQ+vWcC^{5%LO;tsu5Y{Z&%dWDQsD3r zA#Z>WS^EH9WwxYvlZtpBCEaVFNhgD5vgv#o1qnq^u*m$RfN4fW@Ono{^YGE+$l$mA zgh$0xQn3J5NrQrefe#=zZ{6kx{j&tJSb6q=CHS9QBG403X8sUqW&x4zTful?_{AV5 zUg_tJ!?&5`;<#UPGS+lP;lt2urM2&imyLzu*h1z$!lM}$tq{X`gZ{E#K*_Krf*%-e?L_Q3;ktd zKUHE?rNK&48GT>*zeD4ej!1YH85@NNPfm!9PKZfZ5$L4q@S$NM_<3fj z#Uyd5SycKYQ$k9s!bN`KdqZi;OJCIBeGUEa(fqfkukTH9iS3xMsac-s`h7dycD`xc z@A-Y?pl2^ffW@`B%ZlrUWA)Ek-c^!i(IC^c1C_sN|8*JBqIj>f`FypQ*T(s?~PSs`WW%)7S)3PiGpB;4>xlXO<5TtC@sq~fg zezPYEq>4`P8?5*z!8P14*$wY5DlI3=u_g3tWk1O>uOyu)JSMEfwy<3| zI^FyCI>!9VG-HKeY@IG9R>VQ6C(h%@+%Re$Jzs6pLvVi6;<*fWtWQg_AKz@$zM*#J zb1ij4K?UxomEYNzco({IoU6&Fq?W03$auF{1LD$qUn?l=oDQn$85xaDq*DK>AqyF&u zNA+FRHdGWZq&pStw7gspv8)_&*63#%YPXSYA3(i`Tb`@V!_6tn_Lj$CQM4IRWqCKCow6>4%ViXaArl;u*n3f4%UjGg0Id4z?tNC@Gr&mpK<1Qj`=;xAyFdw zWA)k0$|o!I+jE{hD8oPle~p1eJ7f4j34H;Sq65+plFEThdhOZTn!vyJ=XPLSX8eRuEy->l-IhGu! z8ye<~FKX0yTKVbjxg$+XAoEO5;p)m`DGcUOmp+EMRgJ9=Lu9+JdU!6HszZpIoPQaD zxh&*9Q7soOjO&ng-|UF5yuoq~H{%;JbGpG;-#5qDG0yWGGH6)!1ef1N!Ol1Emt^bX zJ8UXb=RqVU3nVE`^U$%xp58C}aE}dBb-yWzPhv9E4GKPW>&YiP8$8s-h$DSXrL32t z4-76ycKB?#y9;?ZemDLqDEUN304YnTD-*!v$Bh{{ebF`3+I^R-JPe#J)3|;={Fo`<166b*6UT36CiMHkG{BB z@@K$RiE?SJ1CNE5)y)2!d{W@A4run;i=KG9UDFlHV9~4Q(=W_0#Li$W{FKefq4m&u zR5%jp>0E90AwO3^|4QnBatP_4yBwn)5J9o$;3Rf_^k-}(Dalmbw^*1cm%F~4$*APR z>m~5XbZP0mDE-(65)6Ci!){v=pv$gA61ft(H%|$@a+@TYl6kjH`ES~wqh9KCQG%wL<>w_ET^q0ir;n^a*x)-h>2Es+UeBewTa}L3R`<-N3N|uq@ z8swb2IDz$jIUIAO-8PyAr{bUZd2Raf^IU>{XP9N#8z1xuJETY~M%dX-CQ`T}6CRG$ z!Xxu2SBvngOSjWIqhC6(=!TzU=2fl;EpI!3AuXF@1;US@ks^`$PqX+06% zRBe6@9{tgb`~?)uB3}MkQ;bLa{uy7)(him^I-J-{09+G3=RvNsB3+0M#j z;RE{!hkqiU_mAd{RpFBPJ<}oW}V?;7A*+e!j;P*R~V&h|OO8C!udfy_t zROW*p-t?6}U|briFI=k&vYo-Xtl#?fqF2}UM_=kAbuDcr;_KcI6A1Bq(5z8Z7gUbts z+ly+{WSt%0Azh4a#0MfT#fpvB>}eKxnAcexIrEi%8u#xvT;zDC%S>nE{i;;evpob< z>}d9e!_GNdB5O1*%l*dSuPukYS-8jcYX@4*@iuRr1vZr^+>2$tR$M_jZVEvY4KZ-9t+*mL{#ijlI4Wuf~*Mh)?ah?)P zisaqswTglVX^~Ty5pCCMr}brb|5=x~SM?_^W6H)3HNG#W1bGo({;BS0$?iNCNmF0U zsy-qwpp0G9^;<#jL#v-NMmA|NAuZaC!-G71w@T80f zDlYXS-Z2~8y{s>Foy@O)__!;b!@q|yz4YhTRI*WKF3f4|+Pa`l7iL+7{L~!3XN^c&#H|R3V*~GgQ{>=KO6HW|zcB9OjM#)kDPsj-TD#^m+AZtzJid5w%w)kEr9+ z7n}ZmeBTw%9#!k6z$Zk36Tgg49UdD=SQ&kbR-SuL*;ByCLiz490o^@xHj8dXML}@) ztG!1SYNPA} zzA_(eOGf#)Sc=5tUsmn3=5ru+oC53v^b>IcyTxC%HBp{*yE%%n1g-Z&Ib$m=BI4qY zE4TR1rwm$Nb7LqsxWBR&(DoGf8!r~pokUWrp9U1@y;Y< zQG7t289W=MH%^dij?PVax0?5R)g!s-ZA++W{g)+gHyi3 z#Bh`%17T*;KR-7QRUm{OnoA;$H(l=p%;Oq$A|9s2I?^mWOmSQrKTtbAztsZl3|9G6 zw)7VAYPBnrLr-UD>_Y=adfM7%cJ|i$`7UtduNH=+j3rl;1XuLdk>NP*$mi;NCCj_JczD%r2`7DM=|N6M%wA#qanTgwN_?%?zj0Sv5+k1_xHxjRNVN7sJj{AUb z?B_l^|7LlYN%HGID^OR|kIYm-Nkx0cnE7taYEA~0R&on%=?|V{Oxvk7Q9gN~mT4nV z&Sp_IAIkC(E0x*3T@qVM1?}aEx*=z-ob(H^Jq)3jg*ET)PST{)6(5o6#MvY2EiOrX zyKpx82@8KIC^Yyq7DpZKCsrKc=v|ef^kwsI(8580wV**vua-6 zqS0lyi4f_tvUsym(U}>Z@?@0rMf8gnxO}7AzIw`7?%2!Nk$->ZcKz>fB!I8xK;b>& zj1S^s5eW&=vGJ)IzJZ?U5fPD*k#RB6@v)KbW5N?Oe6s7szpUnqHnv7_jP6?(zP3!| zMLVtbneQcERm{%>&@h(R;r3~0RguKI)YR0*xCQ;TGI!a0?Zl8LeMA>vUTwS}I;Wo# z@QuVx_`@jUurASYys~e{y$L(ALhoG?uRzY@KT9*+DYkG`-t(bEjZaA{p5GLQz=9pp zrtt;Nou=k--8zCjkZ7bl@cWn2CJs>CD;?%epuV1)Bn)dRi)zjMHoZ}0>2psHMCbVD z7H0NFb}-JLepxoHj|fx@G!the@m&q%3WQTc?-sL>@fdeRtkCej^(^$e8FT)=ePcG@ zRpRLC@wg@)Yj{;`t>h4mSev0A%H`K>mO1R zyDrXd!)H3(RPT@ihc|h~lv#RQQE zXye}^_48ZsgxzZT<4WW66ZyCT6H@}T`DUf~7awx2Q)nr6v3i8Asiu+naq=JdHO1_#-3#Ii%=tR3zRpVP72jgWrb5E2Bj(K4 z89t!3w&_F7Mp7`GdFu}CgLd-MC2)Yfu0cPoq_@?pIPt^{RP~{r#KBzvaHorP< zd8a(v)iqJjCW0*81g6ej*~uF~W3lD9XC)!R!N;9%gEGbmJwd@X;w|2B2Wo2^H-HcQFNsG`EnsUPEcl}T{Yv`m9;GI+OzIv ze64hwV_e6KyD*=~K{k> zo69`1T#`k)mR)1f_uGWyCtIS7idE9f zBt%BmRQUMJoy)GKVd2-h$CAp_-HjX=`fx{jxg7osdvuuJ#iX(<%h~!j=h`WUjg;EV z7yK7Kv-flAXf~Sl8d5BtOf(&w()m=|vU7CBku%wEcY24ip??}8NAf@Fr0-47e-__O z|8=`B<9W%Kcjo=YauBBIIa;55?#xp1RrkGj-&(wFx|ZqCZF%uwbyNuU&fLM-m@AOb zbg3SVG(LvdDpNv~H0S0YeL+JC{!WS^t0}RZ9+z)HGrClr#Ws7U%LTU?H}njf3Nd-r zLR-r}i-dI>H}cRlGf$I`VVKwb^-fBiC<@8SX%CSADl~dFiu}w08G9}#%JA?G^-Llk zr8)Z{O9@=4RTp1al(%@I2_nzrk53&AQjk-Jg$&K{^u8Y%1ZMzMwjF>@(kZ#;hBv04+vq$W|+1E<9 z8gGYIG;+q?KhJU1Xw~Zt{InNc{TL5)SCsQ-q?NLs=EEDRU&NJbTuCm<5kVwUJm;Bd z7mdRkCr@#^1mXvYP1H`cWm+;#FD%j|B-o0jawfMrqZM4YE$J{zzd!Ay>d~QJX~(Nm zIX`Mnp7<(VZpNzKC`H?BJ#AD_{>qOiMa5lx>&c=^nxt(wZcFO&x7&YeqB~@tuJZG) z<7j|6KJt>+9h}!c*fVL#me@aQHn{8%@ow0m<*#~b;r(#{ow?BbMaf>O?kQc;QS<6V zP<8gaq2;33(*z;3P=d{fU(l@2#gZ;*c+)EfL3NWypB|u1ccv}rG_oJ4Kbf>Ee#a^=#r`u%vwUp;UZo5GZAI$VyCKz^>E+>%2mdPH&&mAv9 zc8VwVC%j7PbQ8B$E7)h4X@zahf2ZZBEHXO3TNs?5{&-|tm)`YitlnmJ)xzcR`TVjK zfpt$LHJ(>_g9VMcCr_H{v_SO8Xmo6GUE6{uxOyr?YrO)SY0-1E62&B4oxhhwRH^1o-z z+1ln2>c�yje0DGj)+Dqzp}Z$G!ulWoxl;jhvcrRt<+XMy9?%D~QaX2WKvksb+z( zda01m6Zk4e|GuTE!gZ z(o<7-MDeiq&f>aJG0|r8Gqbb?4vgI!Mzg|xC)p_4Jd~eWgSOXJ&!k!P#)ELO{?3Nh zi$xg5y!m!Hp&WHM9BCu)8A|KQ*$j8yV|Jt3+8fzk8^=6CanB-~9uX)$` zy_ z!;{1FY1~3RXAtsdHIA5u;kOItEXeWi5+eKLzKEE9(j-Bb+(lkKc@emwUrt=L;DCEMWwhV%QNK<@t)9b+>ZX@s$8b0qzl_KQ z#&s+@`NSmXOk>Rb@fL+;Nnu|rM?=5dZNX-YUfaye9MoYyYh&s5Txg})H$vvlLlauH zCh|{XiD@50FzYD1j^4D@t=YSil>zH;Z_N6i>ETUlHpbRL-IHex%xdg0o7weIMFF(m zTXo079)e%jZ{b|7XZQ`ctu`08cXHHKiq*>=>g> zc2pdch+=KjGEHb2sR$If*dC=it%H*=!kCv+=LAH9cvVx?g?R+Cusb*N#L7RM)dcw! zyQRBV9~^OJ&nu1Ec)a)3;GPUPGpafttf|&6)h|1_Z#Ie1GqNA0VA_o{pkS=8p3xks z+hbJSP0b>*V9>Hb7YX{?s*DZc?nVjnw2YrDYMTk94Z3jq^2Pr^f5_-MJDkSrqE4Wl z(D0AIi+z#Z>LMclXgQ~9?>HW#as=ZD&HKBhL_(I;V@v&Qv(}NH({)N#HPcSC9O1Sc_Wz%-ZAWR&Uez^dEmN}KZa_+;LBZ*n7}xO^#syh&TP~gAMHc?-SqkNyN2c;M z9+;d_F}wgZKXlKXhi`c5Vu+5uuSp)l)-7z^N(&VkLVC4be+1r&jN7^phXqlJoF+`I zgzdaKclrwaFr~~aK2&CSwoCz@ywfrjxu|?rtEClNPa_GLvVD+^$w27V zv8U)t&V+5*j>QzFC6`3{D(m3f`A#j~#x(DweW0dcV43mHFA}4MaT6N^^UJd^pBLmsdrYm*p%5^E!;;zEk zj6l!!?}xqQ?;o{=9*i0YEputE!IzP1#$GQHm>b`k^a@2JXM#VdWr^>QE=aZCS}9M? z8p(7H0Jn>sjojJ#f_QV$-B;wJp5{{Q)LGZ;tu2@nO}>c{gl-^(?kDb^o_x;4XZ)Eb zwAI!h!+5KKV<2X?cwNLRM9`+6VrRGis-o%ZdZU*`T`sNjz;_8jsgFhjggNP?)`?-3 z`FEO+(rKUHE=e&Hcx5{Mw(@=3J==*LuRzufqw2O{vzMLiJtm6Z{ax?f3lXzV>sCML zD5hoG|BzkrZ5m=CAN_I&U*>IGUv&TFX>_xQg=9Kjl98o%I!J2zP$YS$H=?jDLF$*H zWk1CTvI#|!HFf^RvGKi%u@w3W+{#|MPoKQ$pGZeJ=6FA{RkQ6!<~nAz+IFU=<>(tv zZc0GCR%P#sOW~&tt+@ckwpBfNvBUck3RW)L%;BTry9HV~QxVIGuLWmz_j0zo0-Yyk zYUTELP4`}w4GMIYDL`>Zc5-&sZd}&oP21M%DWT;WIEL)`BiI*YgVV^qzI=RzI1b>- z`0>Vz}zTUg;UIv3VK}wVdRW9LGnT3OY9?E5US=n1N+Zf3XCCA4X zy0TH4akyo>&>W_uR*e?rB}Qj#3)3-Yp z{<+Za<;fmuS17RXuzUJrB^**sbY*qvFJ&>cHy!weskQRnOWFVxjZnnq6Bf9hwD$62V`>RMhc?%@BdG>DeS zQm4vlU4*9vX{@=>>oVbHy-)i-yxL$YqVQSI+8*cB?^MSsM><759`2Q$PMJ#EQd1St5OG z|KMWjhrgwaw*X&xhHB0m4i+BNacS(Z=CgI<*pbLwfx?Wh)c3#Bq^oeb5nCgMN@a8N zs<%RLosM33jg2Zna8{m)(DLMw`{6txW&KcX>h#;~O8UnqJr0nMX>ehdp$8!4XSl5z`DVKzTL!M^&;cg36t?;Ag<4hPN z$;$cI-qjvsGG?{SVtI8L&Xxt%FVHf=@ma|ar1nc==f5bCJ1z?QD-^c8G&jk)THEw? zgvA!0IxPM|>t4juRvw>w_;JdN%`2Ju%^vQwSafNdQOV>4ffp#l1=-J=nj8g_=rTVl zb2+?oy#DjVEh^xzDcB49=LzheD(uRgc5Zm!tUQ^#V-)+gENJp8#?Y_1@RMdN!=Z+h zM^mzll+gC^8o`5w)_@;lokx9w;EF&~pL45@)YW=nBK%*0U`_b| literal 0 HcmV?d00001 -- 1.7.9.5