Quantcast

Merged all current changes from @joev codebase

Failcoder [10-19-16 - 15:09]
Merged all current changes from @joev codebase
Filename
LICENSE
README.md
SVUITheme_Simple/LICENSE.txt
SVUITheme_Simple/SVUITheme_Simple.lua
SVUI_!Core/License.txt
SVUI_!Core/SVUI_!Core.toc
SVUI_!Core/SVUI_!Core.xml
SVUI_!Core/assets/textures/Dock/LABEL-ART.blp
SVUI_!Core/filtering/_load.xml
SVUI_!Core/filtering/class_filters/demonhunter.lua
SVUI_!Core/filtering/defaults.lua
SVUI_!Core/language/chinese_ui.lua
SVUI_!Core/language/english_ui.lua
SVUI_!Core/language/french_ui.lua
SVUI_!Core/language/german_ui.lua
SVUI_!Core/language/italian_ui.lua
SVUI_!Core/language/korean_ui.lua
SVUI_!Core/language/portuguese_ui.lua
SVUI_!Core/language/russian_ui.lua
SVUI_!Core/language/spanish_ui.lua
SVUI_!Core/language/taiwanese_ui.lua
SVUI_!Core/libs/LibArtifactData-1.0/LibArtifactData-1.0.lua
SVUI_!Core/libs/LibItemUpgradeInfo-1.0/Core.lua
SVUI_!Core/libs/LibReputationData-1.0/LibReputationData-1.0.lua
SVUI_!Core/libs/_SVUI_Lib/Librarian.lua
SVUI_!Core/libs/_load.xml
SVUI_!Core/system/_docklets/garrison.lua
SVUI_!Core/system/_docklets/misc.lua
SVUI_!Core/system/_reports/artifact.lua
SVUI_!Core/system/_reports/experience.lua
SVUI_!Core/system/_reports/reputation.lua
SVUI_!Core/system/_reports/reputation_new.lua
SVUI_!Core/system/_reports/tokens.lua
SVUI_!Core/system/alerts.lua
SVUI_!Core/system/core.lua
SVUI_!Core/system/credits.lua
SVUI_!Core/system/dock.lua
SVUI_!Core/system/gear.lua
SVUI_!Core/system/layout.lua
SVUI_!Core/system/media.lua
SVUI_!Core/system/overrides.lua
SVUI_!Options/License.txt
SVUI_!Options/SVUI_!Options.lua
SVUI_!Options/UnitFrames.lua
SVUI_ActionBars/LICENSE.txt
SVUI_ActionBars/Loader.lua
SVUI_ActionBars/components/micro.lua
SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.lua
SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.xml
SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.27.txt
SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.28.2.txt
SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.toc
SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.xml
SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.lua
SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.lua
SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.toc
SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.lua
SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.toc
SVUI_ActionBars/libs/_load.xml
SVUI_Auras/LICENSE.txt
SVUI_Auras/SVUI_Auras.lua
SVUI_Auras/components/procs.lua
SVUI_Chat/LICENSE.txt
SVUI_CraftOMatic/License.txt
SVUI_FightOMatic/License.txt
SVUI_FightOMatic/SVUI_FightOMatic.lua
SVUI_Inventory/LICENSE.txt
SVUI_Inventory/SVUI_Inventory.lua
SVUI_Maps/LICENSE.txt
SVUI_Maps/SVUI_Maps.lua
SVUI_NamePlates/LICENSE.txt
SVUI_NamePlates/Loader.lua
SVUI_NamePlates/SVUI_NamePlates.lua
SVUI_NamePlates/SVUI_NamePlates.xml
SVUI_NamePlates/assets/Border/Highlight.blp
SVUI_NamePlates/assets/Border/Mark.blp
SVUI_NamePlates/assets/Border/Plate.blp
SVUI_NamePlates/assets/Border/PlateGlow.blp
SVUI_NamePlates/assets/Border/textureBackground.tga
SVUI_NamePlates/assets/Border/textureChecked.tga
SVUI_NamePlates/assets/Border/textureDebuff.tga
SVUI_NamePlates/assets/Border/textureHighlight.tga
SVUI_NamePlates/assets/Border/textureNormal.tga
SVUI_NamePlates/assets/Border/texturePushed.tga
SVUI_NamePlates/assets/Border/textureShadow.tga
SVUI_NamePlates/assets/Border/textureWhite.tga
SVUI_NamePlates/assets/QUEST-BG-ICON.blp
SVUI_QuestTracker/LICENSE.txt
SVUI_QuestTracker/SVUI_QuestTracker.lua
SVUI_Skins/License.txt
SVUI_Skins/components/blizzard/achievement.lua
SVUI_Skins/components/blizzard/auctionhouse.lua
SVUI_Skins/components/blizzard/lfd.lua
SVUI_Skins/components/blizzard/misc.lua
SVUI_Skins/components/blizzard/petjournal.lua
SVUI_Skins/components/blizzard/worldmap.lua
SVUI_Tooltip/LICENSE.txt
SVUI_Tooltip/SVUI_Tooltip.lua
SVUI_TrackOMatic/License.txt
SVUI_TrackOMatic/components/triangulate.lua
SVUI_UnitFrames/LICENSE.txt
SVUI_UnitFrames/Loader.lua
SVUI_UnitFrames/SVUI_UnitFrames.lua
SVUI_UnitFrames/class_resources/druid.lua
SVUI_UnitFrames/class_resources/rogue.lua
SVUI_UnitFrames/elements/essentials.lua
SVUI_UnitFrames/elements/misc.lua
SVUI_UnitFrames/frames.lua
SVUI_UnitFrames/groups.lua
SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
diff --git a/LICENSE b/LICENSE
index 4175642..dedfb1a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 7e34985..1814d8c 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,20 @@ Custom World of Warcraft User Interface

 SuperVillain UI is designed to work with the latest live expansion of World of Warcraft.

+## How to use
+* Make sure WoW isn't running
+* Go to your WoW "Interface\Addons" folder (Normally this would be "C:\Program Files\World of Warcraft\Interface\Addons")
+* Delete all the SVUI_ folders
+* Go to the [SVUI-Temp project on GitHub](https://github.com/failcoder/supervillain-ui)
+* Click the green "Clone or Download" button
+* Click "Download a ZIP" and save the ZIP wherever you like :)
+* Open the ZIP and copy all the SVUI_ folders into your WoW Interface\Addons folder
+* Start WoW
+* Post bugs (yes, there are still plenty :>) here: https://github.com/failcoder/supervillain-ui/Issues
+
+## Communications
+If you're looking for the most up to date information about what's happening with this fan update of SVUI, Mentalo commands you to (please) join the authors (and other SuperVillains) on Discord: https://discord.gg/4VJdSsc
+
 ### Notes

 * This repo will be used exclusively for development versions
@@ -19,4 +33,4 @@ If you are looking for the most current release version (non-development) you ca
 ## License

 SuperVillain UI is licensed under the The MIT License.
-Copyright (c) 2010, Munglunch (Steve Jackson).
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.
diff --git a/SVUITheme_Simple/LICENSE.txt b/SVUITheme_Simple/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUITheme_Simple/LICENSE.txt
+++ b/SVUITheme_Simple/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUITheme_Simple/SVUITheme_Simple.lua b/SVUITheme_Simple/SVUITheme_Simple.lua
index 4ba33ef..5161575 100644
--- a/SVUITheme_Simple/SVUITheme_Simple.lua
+++ b/SVUITheme_Simple/SVUITheme_Simple.lua
@@ -64,9 +64,10 @@ local _RefreshZoneText = function(self)
 	if(self.InfoTop:IsShown()) then
 		self.InfoTop:Hide();
 	end
-	if(not SV.db.Maps.locationText or SV.db.Maps.locationText == "HIDE") then
+	  -- JV - 20160918 Fix error around expectation that SV.db.Maps exists which might not be so if SVUI_Maps is not loaded.
+ 	if ((SV.Maps and SV.db.Maps) and (not SV.db.Maps.locationText or SV.db.Maps.locationText == "HIDE")) then
 		self.InfoBottom:Hide();
-	else
+ 	else
 		self.InfoBottom:Show();
 		local zone = GetRealZoneText() or UNKNOWN
 		self.InfoBottom.Text:SetText(zone)
diff --git a/SVUI_!Core/License.txt b/SVUI_!Core/License.txt
index 69d4d04..18ddca3 100644
--- a/SVUI_!Core/License.txt
+++ b/SVUI_!Core/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_!Core/SVUI_!Core.toc b/SVUI_!Core/SVUI_!Core.toc
index 1f37a6a..84906cf 100644
--- a/SVUI_!Core/SVUI_!Core.toc
+++ b/SVUI_!Core/SVUI_!Core.toc
@@ -5,7 +5,7 @@
 ## Notes: SVUI [|cff9911FFCore Framework|r].
 ## SavedVariables: SVUI_Global, SVUI_Errors, SVUI_Filters, SVUI_Media, SVUI_Shared
 ## SavedVariablesPerCharacter: SVUI_Private
-## OptionalDeps: LibSharedMedia-3.0
+## OptionalDeps: LibSharedMedia-3.0, AdiDebug
 ## X-SVUIName: SVUI
 ## X-SVUISchema: Core
 ## X-Email: munglunch@gmail.com
diff --git a/SVUI_!Core/SVUI_!Core.xml b/SVUI_!Core/SVUI_!Core.xml
index 4646e09..b051a9e 100644
--- a/SVUI_!Core/SVUI_!Core.xml
+++ b/SVUI_!Core/SVUI_!Core.xml
@@ -30,10 +30,11 @@
     <Script file="system\_reports\durability.lua"/>
     <Script file="system\_reports\experience.lua"/>
     <Script file="system\_reports\friends.lua"/>
+    <Script file="system\_reports\artifact.lua"/>
     <Script file="system\_reports\gold.lua"/>
     <Script file="system\_reports\tokens.lua"/>
     <Script file="system\_reports\guild.lua"/>
-    <Script file="system\_reports\reputation.lua"/>
+    <Script file="system\_reports\reputation_new.lua"/>
     <Script file="system\_reports\system.lua"/>
     <Script file="system\_reports\time.lua"/>
     <Script file="system\_reports\dps.lua"/>
diff --git a/SVUI_!Core/assets/textures/Dock/LABEL-ART.blp b/SVUI_!Core/assets/textures/Dock/LABEL-ART.blp
new file mode 100644
index 0000000..221a9d7
Binary files /dev/null and b/SVUI_!Core/assets/textures/Dock/LABEL-ART.blp differ
diff --git a/SVUI_!Core/filtering/_load.xml b/SVUI_!Core/filtering/_load.xml
index c55eb24..9998389 100644
--- a/SVUI_!Core/filtering/_load.xml
+++ b/SVUI_!Core/filtering/_load.xml
@@ -2,6 +2,7 @@
     <Script file="defaults.lua"/>
     <Script file="class_filters\pets.lua"/>
     <Script file="class_filters\deathknight.lua"/>
+    <Script file="class_filters\demonhunter.lua"/>
     <Script file="class_filters\druid.lua"/>
     <Script file="class_filters\hunter.lua"/>
     <Script file="class_filters\mage.lua"/>
@@ -12,4 +13,4 @@
     <Script file="class_filters\shaman.lua"/>
     <Script file="class_filters\warlock.lua"/>
     <Script file="class_filters\warrior.lua"/>
-</Ui>
\ No newline at end of file
+</Ui>
diff --git a/SVUI_!Core/filtering/class_filters/demonhunter.lua b/SVUI_!Core/filtering/class_filters/demonhunter.lua
new file mode 100644
index 0000000..446c40c
--- /dev/null
+++ b/SVUI_!Core/filtering/class_filters/demonhunter.lua
@@ -0,0 +1,73 @@
+--[[
+##########################################################
+S V U I   By: Failcoder
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+if(select(2, UnitClass("player")) ~= 'DEMONHUNTER') then return end;
+
+local SV = select(2, ...)
+
+--[[ DEMONHUNTER FILTERS ]]--
+
+SV.defaults.Filters["BuffWatch"] = {
+    ["178740"] = {-- Immolation Aura
+        ["enable"] = true,
+        ["id"] = 178740,
+        ["point"] = "TOPRIGHT",
+        ["color"] = {["r"] = 0.4, ["g"] = 0.8, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["218256"] = {-- Empower Wards
+        ["enable"] = true,
+        ["id"] = 218256,
+        ["point"] = "TOPLEFT",
+        ["color"] = {["r"] = 0.2, ["g"] = 1, ["b"] = 0.2},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["162264"] = {-- Metamorphosis (Havoc)
+        ["enable"] = true,
+        ["id"] = 162264,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.8, ["g"] = 0.1, ["b"] = 0.8},
+        ["anyUnit"] = true,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+    ["187827"] = {-- Metamorphosis (Vengence)
+        ["enable"] = true,
+        ["id"] = 187827,
+        ["point"] = "BOTTOMLEFT",
+        ["color"] = {["r"] = 0.8, ["g"] = 0.1, ["b"] = 0.8},
+        ["anyUnit"] = false,
+        ["onlyShowMissing"] = false,
+        ['style'] = 'coloredIcon',
+        ['displayText'] = false,
+        ['textColor'] = {["r"] = 1, ["g"] = 1, ["b"] = 1},
+        ['textThreshold'] = -1,
+        ['xOffset'] = 0,
+        ['yOffset'] = 0
+    },
+};
diff --git a/SVUI_!Core/filtering/defaults.lua b/SVUI_!Core/filtering/defaults.lua
index 49ae94b..4e15939 100644
--- a/SVUI_!Core/filtering/defaults.lua
+++ b/SVUI_!Core/filtering/defaults.lua
@@ -35,18 +35,18 @@ end
 local FilterIDs = {
     ["BlackList"] = [[36900,36901,36893,114216,97821,36032,8733,57724,25771,57723,36032,58539,26013,6788,71041,41425,55711,8326,23445,24755,25163,80354,95223,124275,124274,124273,117870,123981,15007,113942,89140]],

-    ["WhiteList"] = [[31821,2825,32182,80353,90355,47788,33206,116849,22812,123059,136431,137332,137375,144351,142863,142864,142865,143198]],
+    ["WhiteList"] = [[31821,2825,32182,80353,90355,47788,33206,116849,22812,123059,136431,137332,137375,144351,142863,142864,142865,143198,162264]],

     ["CC"] = [[47476,91800,91807,91797,108194,115001,33786,339,78675,22570,5211,102359,99,127797,45334,114238,3355,24394,64803,19386,117405,128405,31661,118,122,82691,44572,33395,102051,20066,10326,853,105593,31935,105421,605,64044,8122,9484,15487,114404,88625,87194,2094,1776,6770,1833,1330,408,88611,51514,64695,63685,118905,118345,710,6789,118699,5484,6358,30283,115268,89766,137143,7922,105771,107566,132168,107570,118895,18498,116706,115078,119392,119381,120086,140023,25046,20549,107079]],

-    ["Defense"] = [[17,45438,115610,48797,48792,49039,87256,55233,50461,33206,47788,62618,47585,104773,110913,108359,22812,102342,61336,19263,53480,1966,31224,74001,5277,45182,98007,30823,108271,1022,6940,114039,31821,498,642,86659,31850,118038,55694,97463,12975,114029,871,114030,120954,122783,122278,116849,20594]],
+    ["Defense"] = [[17,45438,115610,48797,48792,49039,87256,55233,50461,33206,47788,62618,47585,104773,110913,108359,22812,102342,61336,19263,53480,1966,31224,74001,5277,45182,98007,30823,108271,1022,6940,114039,31821,498,642,86659,31850,118038,55694,97463,12975,114029,871,114030,120954,122783,122278,116849,20594,218256]],

-    ["Player"] = [[45438,115610,110909,12051,12472,80353,12042,32612,110960,108839,111264,108843,48797,48792,49039,87256,49222,55233,50461,51271,96268,33206,47788,62618,47585,6346,10060,114239,119032,27827,104773,110913,108359,113860,113861,113858,88448,22812,102342,61336,117679,102543,102558,102560,132158,106898,1850,106951,52610,69369,112071,124974,19263,53480,51755,54216,3045,3584,131894,90355,90361,31224,74001,5277,45182,51713,114018,2983,11327,108212,57933,79140,13750,98007,30823,108271,16188,2825,79206,8178,58875,108281,108271,16166,114896,1044,1022,1038,6940,114039,31821,498,642,86659,20925,31850,31884,53563,31842,105809,85499,118038,55694,97463,12975,114029,871,114030,18499,1719,23920,114028,46924,3411,107574,120954,122783,122278,116849,125174,116841,20594,59545,20572,26297,68992]],
+    ["Player"] = [[45438,115610,110909,12051,12472,80353,12042,32612,110960,108839,111264,108843,48797,48792,49039,87256,49222,55233,50461,51271,96268,33206,47788,62618,47585,6346,10060,114239,119032,27827,104773,110913,108359,113860,113861,113858,88448,22812,102342,61336,117679,102543,102558,102560,132158,106898,1850,106951,52610,69369,112071,124974,19263,53480,51755,54216,3045,3584,131894,90355,90361,31224,74001,5277,45182,51713,114018,2983,11327,108212,57933,79140,13750,98007,30823,108271,16188,2825,79206,8178,58875,108281,108271,16166,114896,1044,1022,1038,6940,114039,31821,498,642,86659,20925,31850,31884,53563,31842,105809,85499,118038,55694,97463,12975,114029,871,114030,18499,1719,23920,114028,46924,3411,107574,120954,122783,122278,116849,125174,116841,20594,59545,20572,26297,68992,191428,191427,187827,162264,218256,178740]],

     ["Raid"] = [[175601,175599,172069,172066,166779,56037,175654,166185,166175,174404,173763,174500,174939,172115,166200,174473,158986,159113,159178,159213,159410,160521,159386,159188,162497,159202,156152,156151,156143,163046,159220,163242,163590,163241,160179,159972,162346,162892,162475,155569,158241,158026,167200,159709,167179,163374,158200,163472,172895,162185,162184,161242,161358,156803,164004,164005,164006,158619,164176,164178,164191,157349,164232,164235,164240,158553,165102,157801,156096,156743,156047,156401,156404,158054,156888,157000,156999,155365,155061,155030,155236,159044,162276,155657,155222,155399,154989,155499,155318,155277,154952,155074,163284,162293,155493,163633,155921,165195,155701,156310,164380,155240,155242,176133,156934,175104,176121,158702,155225,157139,161570,157853,155080,143962,155078,36240,155326,165300,157060,156766,161839,156844,156309,156203,173471,164271,158315,156601,170395,170405,158692,158702,158686,158683,159585,156112,184369,180079,179897,185978,182373,182280,182074,182001,187819,181345,184360,184449,185065,184450,185066,184676,184652,181488,188929,180389,179867,181295,179977,179864,179909,179908,181957,182200,182178,182325,185239,185510,182600,179219,181753,182038,188666,189627,180415,185237,185238,185241,180526,181508,181653,179428,182008,179407,188208,186073,186407,186500,186063,186333,181275,181099,181597,182006,181841,182088,184964,186123,185014,186952,186961,189891,183634,189895,190049]]
 };

-local InitAuraBars = [[2825,32182,80353,90355,86659]]
+local InitAuraBars = [[2825,32182,80353,90355,86659,162264]]

 SV.defaults.Filters["BlackList"] = {};
 SV.defaults.Filters["WhiteList"] = {};
diff --git a/SVUI_!Core/language/chinese_ui.lua b/SVUI_!Core/language/chinese_ui.lua
index 00ef491..df47eca 100644
--- a/SVUI_!Core/language/chinese_ui.lua
+++ b/SVUI_!Core/language/chinese_ui.lua
@@ -470,4 +470,9 @@ L["You can set your keybinds quickly by typing /kb."]="你可以通过输入 /kb
 L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."]="你可以通过鼠标中键点击小地图或在快捷列设置内选择打开微型系统栏."
 L["You can use the /resetui command to reset all of your moveables. You can also use the command to reset a specific mover, /resetui <mover name>.\nExample: /resetui Player Frame"]="使用 /resetui 命令可以重置你的所有框架位置. 你也可以通过命令 /resetui <框架名称> 单独重置某个框架.\n例如: /resetui Player Frame"
 L["Ghost"]="鬼魂"
-L["Offline"]="离线"
\ No newline at end of file
+L["Offline"]="离线"
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
diff --git a/SVUI_!Core/language/english_ui.lua b/SVUI_!Core/language/english_ui.lua
index e778afc..05539db 100644
--- a/SVUI_!Core/language/english_ui.lua
+++ b/SVUI_!Core/language/english_ui.lua
@@ -493,4 +493,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true;
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/french_ui.lua b/SVUI_!Core/language/french_ui.lua
index a3b74f8..baa417b 100644
--- a/SVUI_!Core/language/french_ui.lua
+++ b/SVUI_!Core/language/french_ui.lua
@@ -589,4 +589,9 @@ L["Arena"]="Arêne"
 L["Party"]="Groupe"
 L["Raid"]="Raid"
 L["Progression Info"]="Information de progression"
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]="Affiche la progression (Raid) du joueur dans une infos-bulle (ne peut être mis à jour immédiatement lorsque la souris survole une unité)."
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]="Affiche la progression (Raid) du joueur dans une infos-bulle (ne peut être mis à jour immédiatement lorsque la souris survole une unité)."
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/german_ui.lua b/SVUI_!Core/language/german_ui.lua
index 2a531c1..82b8fb3 100644
--- a/SVUI_!Core/language/german_ui.lua
+++ b/SVUI_!Core/language/german_ui.lua
@@ -587,4 +587,9 @@ L["Arena"]='Arena'
 L["Party"]='Gruppe'
 L["Raid"]='Schlachtzug'
 L["Progression Info"]='Schlachtzugfortschritt'
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]='Zeigt den Schlachtzugfortschritt eines Charakters im Tooltip an. Es kann einen kurzen Moement dauern, bis diese Information agezeigt / aktualisiert wird.'
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]='Zeigt den Schlachtzugfortschritt eines Charakters im Tooltip an. Es kann einen kurzen Moement dauern, bis diese Information agezeigt / aktualisiert wird.'
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/italian_ui.lua b/SVUI_!Core/language/italian_ui.lua
index dd0035f..1e4de54 100644
--- a/SVUI_!Core/language/italian_ui.lua
+++ b/SVUI_!Core/language/italian_ui.lua
@@ -590,4 +590,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/korean_ui.lua b/SVUI_!Core/language/korean_ui.lua
index e752517..3c62e6b 100644
--- a/SVUI_!Core/language/korean_ui.lua
+++ b/SVUI_!Core/language/korean_ui.lua
@@ -590,4 +590,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/portuguese_ui.lua b/SVUI_!Core/language/portuguese_ui.lua
index fc26346..59ecb7c 100644
--- a/SVUI_!Core/language/portuguese_ui.lua
+++ b/SVUI_!Core/language/portuguese_ui.lua
@@ -570,4 +570,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/russian_ui.lua b/SVUI_!Core/language/russian_ui.lua
index 3c0237d..b56f5ba 100644
--- a/SVUI_!Core/language/russian_ui.lua
+++ b/SVUI_!Core/language/russian_ui.lua
@@ -590,4 +590,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/spanish_ui.lua b/SVUI_!Core/language/spanish_ui.lua
index 8430e93..4250cdb 100644
--- a/SVUI_!Core/language/spanish_ui.lua
+++ b/SVUI_!Core/language/spanish_ui.lua
@@ -594,4 +594,9 @@ L["Arena"]=true;
 L["Party"]=true;
 L["Raid"]=true;
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/language/taiwanese_ui.lua b/SVUI_!Core/language/taiwanese_ui.lua
index 52e7873..ff908f3 100644
--- a/SVUI_!Core/language/taiwanese_ui.lua
+++ b/SVUI_!Core/language/taiwanese_ui.lua
@@ -590,4 +590,9 @@ L["Arena"]="競技場"
 L["Party"]="隊伍"
 L["Raid"]="團隊"
 L["Progression Info"]=true;
-L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
\ No newline at end of file
+L["Display the players raid progression in the tooltip, this may not immediately update when mousing over a unit."]=true
+L["Artifact Power"]=true;
+L["Current Artifact Power:"]=true;
+L["Remaining:"]=true;
+L["Points to Spend:"]=true;
+L["No Artifact"]=true;
\ No newline at end of file
diff --git a/SVUI_!Core/libs/LibArtifactData-1.0/LibArtifactData-1.0.lua b/SVUI_!Core/libs/LibArtifactData-1.0/LibArtifactData-1.0.lua
new file mode 100644
index 0000000..eae1ba2
--- /dev/null
+++ b/SVUI_!Core/libs/LibArtifactData-1.0/LibArtifactData-1.0.lua
@@ -0,0 +1,519 @@
+local MAJOR, MINOR = "LibArtifactData-1.0", 11
+
+assert(_G.LibStub, MAJOR .. " requires LibStub")
+local lib = _G.LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+
+lib.callbacks = lib.callbacks or _G.LibStub("CallbackHandler-1.0"):New(lib)
+
+local Debug = function() end
+if _G.AdiDebug then
+	Debug = _G.AdiDebug:Embed({}, MAJOR)
+end
+
+-- local store
+local artifacts = {}
+local equippedID, viewedID, activeID
+artifacts.knowledgeLevel = 0
+artifacts.knowledgeMultiplier = 1
+
+-- constants
+local _G                       = _G
+local BACKPACK_CONTAINER       = _G.BACKPACK_CONTAINER
+local BANK_CONTAINER           = _G.BANK_CONTAINER
+local INVSLOT_MAINHAND         = _G.INVSLOT_MAINHAND
+local LE_ITEM_CLASS_ARMOR      = _G.LE_ITEM_CLASS_ARMOR
+local LE_ITEM_CLASS_WEAPON     = _G.LE_ITEM_CLASS_WEAPON
+local LE_ITEM_QUALITY_ARTIFACT = _G.LE_ITEM_QUALITY_ARTIFACT
+local NUM_BAG_SLOTS            = _G.NUM_BAG_SLOTS
+local NUM_BANKBAGSLOTS         = _G.NUM_BANKBAGSLOTS
+
+-- blizzard api
+local aUI                              = _G.C_ArtifactUI
+local Clear                            = aUI.Clear
+local GetArtifactInfo                  = aUI.GetArtifactInfo
+local GetArtifactKnowledgeLevel        = aUI.GetArtifactKnowledgeLevel
+local GetArtifactKnowledgeMultiplier   = aUI.GetArtifactKnowledgeMultiplier
+local GetContainerItemInfo             = _G.GetContainerItemInfo
+local GetContainerNumSlots             = _G.GetContainerNumSlots
+local GetCostForPointAtRank            = aUI.GetCostForPointAtRank
+local GetCurrencyInfo                  = _G.GetCurrencyInfo
+local GetEquippedArtifactInfo          = aUI.GetEquippedArtifactInfo
+local GetInventoryItemEquippedUnusable = _G.GetInventoryItemEquippedUnusable
+local GetItemInfo                      = _G.GetItemInfo
+local GetNumObtainedArtifacts          = aUI.GetNumObtainedArtifacts
+local GetNumPurchasableTraits          = _G.MainMenuBar_GetNumArtifactTraitsPurchasableFromXP
+local GetNumRelicSlots                 = aUI.GetNumRelicSlots
+local GetPowerInfo                     = aUI.GetPowerInfo
+local GetPowers                        = aUI.GetPowers
+local GetRelicInfo                     = aUI.GetRelicInfo
+local GetRelicSlotType                 = aUI.GetRelicSlotType
+local GetSpellInfo                     = _G.GetSpellInfo
+local HasArtifactEquipped              = _G.HasArtifactEquipped
+local IsAtForge                        = aUI.IsAtForge
+local IsViewedArtifactEquipped         = aUI.IsViewedArtifactEquipped
+local SocketContainerItem              = _G.SocketContainerItem
+local SocketInventoryItem              = _G.SocketInventoryItem
+
+-- lua api
+local select   = _G.select
+local strmatch = _G.string.match
+local tonumber = _G.tonumber
+
+local private = {} -- private space for the event handlers
+
+lib.frame = lib.frame or _G.CreateFrame("Frame")
+local frame = lib.frame
+frame:UnregisterAllEvents() -- deactivate old versions
+frame:SetScript("OnEvent", function(_, event, ...) private[event](event, ...) end)
+frame:RegisterEvent("PLAYER_ENTERING_WORLD")
+
+local function CopyTable(tbl)
+	if not tbl then return {} end
+	local copy = {};
+	for k, v in pairs(tbl) do
+		if ( type(v) == "table" ) then
+			copy[k] = CopyTable(v);
+		else
+			copy[k] = v;
+		end
+	end
+	return copy;
+end
+
+local function PrepareForScan()
+	frame:UnregisterEvent("ARTIFACT_UPDATE")
+	_G.UIParent:UnregisterEvent("ARTIFACT_UPDATE")
+
+	local ArtifactFrame = _G.ArtifactFrame
+	if ArtifactFrame and not ArtifactFrame:IsShown() then
+		ArtifactFrame:UnregisterEvent("ARTIFACT_UPDATE")
+	end
+end
+
+local function RestoreStateAfterScan()
+	frame:RegisterEvent("ARTIFACT_UPDATE")
+	_G.UIParent:RegisterEvent("ARTIFACT_UPDATE")
+
+	local ArtifactFrame = _G.ArtifactFrame
+	if ArtifactFrame and not ArtifactFrame:IsShown() then
+		Clear()
+		ArtifactFrame:RegisterEvent("ARTIFACT_UPDATE")
+	end
+end
+
+local function InformEquippedArtifactChanged(artifactID)
+	if artifactID ~= equippedID then
+		Debug("ARTIFACT_EQUIPPED_CHANGED", artifactID, equippedID)
+		lib.callbacks:Fire("ARTIFACT_EQUIPPED_CHANGED", artifactID, equippedID)
+		equippedID = artifactID
+	end
+end
+
+local function InformActiveArtifactChanged(artifactID)
+	local oldActiveID = activeID
+	if artifactID and not GetInventoryItemEquippedUnusable("player", INVSLOT_MAINHAND) then
+		activeID = artifactID
+	else
+		activeID = nil
+	end
+	if oldActiveID ~= activeID then
+		Debug("ARTIFACT_ACTIVE_CHANGED", activeID, oldActiveID)
+		lib.callbacks:Fire("ARTIFACT_ACTIVE_CHANGED", activeID, oldActiveID)
+	end
+end
+
+local function InformTraitsChanged(artifactID)
+	Debug("ARTIFACT_TRAITS_CHANGED", artifactID, artifacts[artifactID].traits)
+	lib.callbacks:Fire("ARTIFACT_TRAITS_CHANGED", artifactID, CopyTable(artifacts[artifactID].traits))
+end
+
+local function StoreArtifact(artifactID, name, icon, unspentPower, numRanksPurchased, numRanksPurchasable, power, maxPower, traits, relics)
+	if not artifacts[artifactID] then
+		artifacts[artifactID] = {
+			name = name,
+			icon = icon,
+			unspentPower = unspentPower,
+			numRanksPurchased = numRanksPurchased,
+			numRanksPurchasable = numRanksPurchasable,
+			power = power,
+			maxPower = maxPower,
+			powerForNextRank = maxPower - power,
+			traits = traits,
+			relics = relics,
+		}
+		Debug("ARTIFACT_ADDED", artifactID, name)
+		lib.callbacks:Fire("ARTIFACT_ADDED", artifactID)
+	else
+		local current = artifacts[artifactID]
+		current.unspentPower = unspentPower
+		current.numRanksPurchased = numRanksPurchased -- numRanksPurchased does not include bonus traits from relics
+		current.numRanksPurchasable = numRanksPurchasable
+		current.power = power
+		current.maxPower = maxPower
+		current.powerForNextRank = maxPower - power
+		current.traits = traits
+		current.relics = relics
+	end
+end
+
+local function ScanTraits(artifactID)
+	local traits = {}
+	local powers = GetPowers()
+
+	for i = 1, #powers do
+		local traitID = powers[i]
+		local spellID, _, currentRank, maxRank, bonusRanks, _, _, _, isStart, isGold, isFinal = GetPowerInfo(traitID)
+		if currentRank > 0 then
+			local name, _, icon = GetSpellInfo(spellID)
+			traits[#traits + 1] = {
+				traitID = traitID,
+				spellID = spellID,
+				name = name,
+				icon = icon,
+				currentRank = currentRank,
+				maxRank = maxRank,
+				bonusRanks = bonusRanks,
+				isGold = isGold,
+				isStart = isStart,
+				isFinal = isFinal,
+			}
+		end
+	end
+
+	if artifactID then
+		artifacts[artifactID].traits = traits
+	end
+
+	return traits
+end
+
+local function ScanRelics(artifactID)
+	local relics = {}
+	for i = 1, GetNumRelicSlots() do
+		local slotType = GetRelicSlotType(i)
+		local lockedReason, name, icon, link = GetRelicInfo(i)
+		local isLocked = lockedReason and true or false
+		local itemID
+		if name then
+			itemID = strmatch(link, "item:(%d+):")
+		end
+
+		relics[i] = { type = slotType, isLocked = isLocked, name = name, icon = icon, itemID = itemID, link = link }
+	end
+
+	if artifactID then
+		artifacts[artifactID].relics = relics
+	end
+
+	return relics
+end
+
+local function GetArtifactKnowledge()
+	local lvl = GetArtifactKnowledgeLevel()
+	local mult = GetArtifactKnowledgeMultiplier()
+	if artifacts.knowledgeMultiplier ~= mult or artifacts.knowledgeLevel ~= lvl then
+		artifacts.knowledgeLevel = lvl
+		artifacts.knowledgeMultiplier = mult
+		Debug("ARTIFACT_KNOWLEDGE_CHANGED", lvl, mult)
+		lib.callbacks:Fire("ARTIFACT_KNOWLEDGE_CHANGED", lvl, mult)
+	end
+end
+
+local function GetViewedArtifactData()
+	GetArtifactKnowledge()
+	local itemID, _, name, icon, unspentPower, numRanksPurchased = GetArtifactInfo() -- TODO: appearance stuff needed? altItemID ?
+	if not itemID then
+		Debug("|cffff0000ERROR:|r", "GetArtifactInfo() returned nil.")
+		return
+	end
+	viewedID = itemID
+	Debug("GetViewedArtifactData", name, itemID)
+	local numRanksPurchasable, power, maxPower = GetNumPurchasableTraits(numRanksPurchased, unspentPower)
+	local traits = ScanTraits()
+	local relics = ScanRelics()
+	StoreArtifact(itemID, name, icon, unspentPower, numRanksPurchased, numRanksPurchasable, power, maxPower, traits, relics)
+
+	if IsViewedArtifactEquipped() then
+		InformEquippedArtifactChanged(itemID)
+		InformActiveArtifactChanged(itemID)
+	end
+end
+
+local function ScanEquipped()
+	if HasArtifactEquipped() then
+		PrepareForScan()
+		SocketInventoryItem(INVSLOT_MAINHAND)
+		GetViewedArtifactData()
+		Clear()
+		RestoreStateAfterScan()
+		frame:UnregisterEvent("UNIT_INVENTORY_CHANGED")
+	end
+end
+
+local function ScanContainer(container, numObtained)
+	for slot = 1, GetContainerNumSlots(container) do
+		local _, _, _, quality, _, _, _, _, _, itemID = GetContainerItemInfo(container, slot)
+		if quality == LE_ITEM_QUALITY_ARTIFACT then
+			local classID = select(12, GetItemInfo(itemID))
+			if classID == LE_ITEM_CLASS_WEAPON or classID == LE_ITEM_CLASS_ARMOR then
+				Debug("ARTIFACT_FOUND", "in", container, slot)
+				SocketContainerItem(container, slot)
+				GetViewedArtifactData()
+				Clear()
+				if numObtained <= lib:GetNumObtainedArtifacts() then break end
+			end
+		end
+	end
+end
+
+local function IterateContainers(from, to, numObtained)
+	PrepareForScan()
+	for container = from, to do
+		ScanContainer(container, numObtained)
+		if numObtained <= lib:GetNumObtainedArtifacts() then break end
+	end
+	RestoreStateAfterScan()
+end
+
+local function ScanBank(numObtained)
+	if numObtained > lib:GetNumObtainedArtifacts() then
+		PrepareForScan()
+		ScanContainer(BANK_CONTAINER, numObtained)
+		RestoreStateAfterScan()
+	end
+	if numObtained > lib:GetNumObtainedArtifacts() then
+		IterateContainers(NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS, numObtained)
+	end
+end
+
+function private.PLAYER_ENTERING_WORLD(event)
+	frame:UnregisterEvent(event)
+	frame:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player")
+	frame:RegisterEvent("BAG_UPDATE_DELAYED")
+	frame:RegisterEvent("BANKFRAME_OPENED")
+	frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
+	frame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
+	frame:RegisterEvent("ARTIFACT_CLOSE")
+	frame:RegisterEvent("ARTIFACT_XP_UPDATE")
+	frame:RegisterUnitEvent("PLAYER_SPECIALIZATION_CHANGED", "player")
+end
+
+-- bagged artifact data becomes obtainable
+function private.BAG_UPDATE_DELAYED(event)
+	local numObtained = GetNumObtainedArtifacts()
+	if numObtained <= 0 then return end
+
+	-- prevent double-scanning if UNIT_INVENTORY_CHANGED fired first
+	-- UNIT_INVENTORY_CHANGED does not fire after /reload
+	if not equippedID and HasArtifactEquipped() then
+		ScanEquipped()
+	end
+
+	if numObtained > lib:GetNumObtainedArtifacts() then
+		IterateContainers(BACKPACK_CONTAINER, NUM_BAG_SLOTS, numObtained)
+	end
+
+	frame:UnregisterEvent(event)
+end
+
+-- equipped artifact data becomes obtainable
+function private.UNIT_INVENTORY_CHANGED(event)
+	ScanEquipped(event)
+end
+
+function private.ARTIFACT_CLOSE()
+	viewedID = nil
+end
+
+function private.ARTIFACT_UPDATE(event, newItem)
+	Debug(event, newItem)
+	if newItem then
+		GetViewedArtifactData()
+	else
+		if not GetNumRelicSlots() then
+			Debug("|cffff0000ERROR:|r", "artifact data unobtainable.")
+			return
+		end
+		local newRelics = ScanRelics()
+		local oldRelics = artifacts[viewedID].relics
+
+		for i = 1, #newRelics do
+			local newRelic = newRelics[i]
+			-- TODO: test third slot unlock
+			if newRelic.isLocked ~= oldRelics[i].isLocked or newRelic.itemID ~= oldRelics[i].itemID then
+				oldRelics[i] = newRelic
+				Debug("ARTIFACT_RELIC_CHANGED", viewedID, i, newRelic)
+				lib.callbacks:Fire("ARTIFACT_RELIC_CHANGED", viewedID, i, CopyTable(newRelic))
+				-- if a relic changed, so did the traits
+				ScanTraits(viewedID)
+				InformTraitsChanged(viewedID)
+				break
+			end
+		end
+	end
+end
+
+function private.ARTIFACT_XP_UPDATE(event)
+	-- at the forge the player can purchase traits even for unequipped artifacts
+	local GetInfo = IsAtForge() and GetArtifactInfo or GetEquippedArtifactInfo
+	local itemID, _, _, _, unspentPower, numRanksPurchased = GetInfo()
+	local numRanksPurchasable, power, maxPower = GetNumPurchasableTraits(numRanksPurchased, unspentPower)
+
+	local artifact = artifacts[itemID]
+	if not artifact then
+		return lib.ForceUpdate()
+	end
+
+	local diff = unspentPower - artifact.unspentPower
+
+	if numRanksPurchased ~= artifact.numRanksPurchased then
+		-- both learning traits and artifact respec trigger ARTIFACT_XP_UPDATE
+		-- however respec has a positive diff and learning traits has a negative one
+		ScanTraits(itemID)
+		InformTraitsChanged(itemID)
+	end
+
+	if diff ~= 0 then
+		artifact.unspentPower = unspentPower
+		artifact.power = power
+		artifact.maxPower = maxPower
+		artifact.numRanksPurchased = numRanksPurchased
+		artifact.numRanksPurchasable = numRanksPurchasable
+		artifact.powerForNextRank = maxPower - power
+		Debug(event, itemID, diff, unspentPower, power, maxPower, maxPower - power, numRanksPurchasable)
+		lib.callbacks:Fire("ARTIFACT_POWER_CHANGED", itemID, diff, unspentPower, power, maxPower, maxPower - power, numRanksPurchasable)
+	end
+end
+
+function private.BANKFRAME_OPENED()
+	local numObtained = GetNumObtainedArtifacts()
+	if numObtained > lib:GetNumObtainedArtifacts() then
+		ScanBank(numObtained)
+	end
+end
+
+function private.CURRENCY_DISPLAY_UPDATE(event)
+	local _, lvl = GetCurrencyInfo(1171)
+	if lvl ~= artifacts.knowledgeLevel then
+		artifacts.knowledgeLevel = lvl
+		Debug("ARTIFACT_DATA_MISSING", event, lvl)
+		lib.callbacks:Fire("ARTIFACT_DATA_MISSING", "knowledge", lvl)
+	end
+end
+
+function private.PLAYER_EQUIPMENT_CHANGED(event, slot)
+	if slot == INVSLOT_MAINHAND then
+		local itemID = GetEquippedArtifactInfo()
+
+		if itemID and not artifacts[itemID] then
+			ScanEquipped(event)
+		end
+
+		InformEquippedArtifactChanged(itemID)
+		InformActiveArtifactChanged(itemID)
+	end
+end
+
+-- needed in case the game fails to switch artifacts
+function private.PLAYER_SPECIALIZATION_CHANGED(event)
+	local itemID = GetEquippedArtifactInfo()
+	Debug(event, itemID)
+	InformActiveArtifactChanged(itemID)
+end
+
+function lib.GetActiveArtifactID()
+	return activeID
+end
+
+function lib.GetArtifactInfo(_, artifactID)
+	artifactID = artifactID or equippedID
+	return artifactID, CopyTable(artifacts[artifactID])
+end
+
+function lib.GetAllArtifactsInfo()
+	return CopyTable(artifacts)
+end
+
+function lib.GetNumObtainedArtifacts()
+	local numArtifacts = 0
+	for artifact in pairs(artifacts) do
+		if tonumber(artifact) then
+			numArtifacts = numArtifacts + 1
+		end
+	end
+
+	return numArtifacts
+end
+
+function lib.GetArtifactTraits(_, artifactID)
+	artifactID = artifactID or equippedID
+	for itemID, data in pairs(artifacts) do
+		if itemID == artifactID then
+			return artifactID, CopyTable(data.traits)
+		end
+	end
+end
+
+function lib.GetArtifactRelics(_, artifactID)
+	artifactID = artifactID or equippedID
+	for itemID, data in pairs(artifacts) do
+		if itemID == artifactID then
+			return artifactID, CopyTable(data.relics)
+		end
+	end
+end
+
+function lib.GetArtifactPower(_, artifactID)
+	artifactID = artifactID or equippedID
+	for itemID, data in pairs(artifacts) do
+		if itemID == artifactID then
+			return artifactID, data.unspentPower, data.power, data.maxPower, data.powerForNextRank, data.numRanksPurchased, data.numRanksPurchasable
+		end
+	end
+end
+
+function lib.GetArtifactKnowledge()
+	return artifacts.knowledgeLevel, artifacts.knowledgeMultiplier
+end
+
+function lib.GetAcquiredArtifactPower(_, artifactID)
+	local total = 0
+
+	if artifactID then
+		local data = artifacts[artifactID]
+		total = total + data.unspentPower
+		local rank = 1
+		while rank < data.numRanksPurchased do
+			total = total + GetCostForPointAtRank(rank)
+			rank = rank + 1
+		end
+
+		return total
+	end
+
+	for itemID, data in pairs(artifacts) do
+		if tonumber(itemID) then
+			total = total + data.unspentPower
+			local rank = 1
+			while rank < data.numRanksPurchased do
+				total = total + GetCostForPointAtRank(rank)
+				rank = rank + 1
+			end
+		end
+	end
+
+	return total
+end
+
+function lib.ForceUpdate()
+	if _G.ArtifactFrame and _G.ArtifactFrame:IsShown() then
+		Debug("ForceUpdate", "aborted because ArtifactFrame is open.")
+		return
+	end
+	local numObtained = GetNumObtainedArtifacts()
+	if numObtained > 0 then
+		ScanEquipped("FORCE_UPDATE")
+		IterateContainers(BACKPACK_CONTAINER, NUM_BAG_SLOTS, numObtained)
+	end
+end
diff --git a/SVUI_!Core/libs/LibItemUpgradeInfo-1.0/Core.lua b/SVUI_!Core/libs/LibItemUpgradeInfo-1.0/Core.lua
new file mode 100644
index 0000000..9edc75c
--- /dev/null
+++ b/SVUI_!Core/libs/LibItemUpgradeInfo-1.0/Core.lua
@@ -0,0 +1,546 @@
+local MAJOR, MINOR = "LibItemUpgradeInfo-1.0", 25
+local type,tonumber,select,strsplit,GetItemInfoFromHyperlink=type,tonumber,select,strsplit,GetItemInfoFromHyperlink
+local library,previous = _G.LibStub:NewLibrary(MAJOR, MINOR)
+local lib=library --#lib Needed to keep Eclipse LDT happy
+if not lib then return end
+local pp=print
+--[===[@debug@
+LoadAddOn("Blizzard_DebugTools")
+LoadAddOn("LibDebug")
+if LibDebug then LibDebug() end
+--@end-debug@]===]
+--@non-debug@
+local print=function() end
+--@end-non-debug@
+local upgradeTable = {
+	[  1] = { upgrade = 1, max = 1, ilevel = 8 },
+	[373] = { upgrade = 1, max = 3, ilevel = 4 },
+	[374] = { upgrade = 2, max = 3, ilevel = 8 },
+	[375] = { upgrade = 1, max = 3, ilevel = 4 },
+	[376] = { upgrade = 2, max = 3, ilevel = 4 },
+	[377] = { upgrade = 3, max = 3, ilevel = 4 },
+	[378] = {                       ilevel = 7 },
+	[379] = { upgrade = 1, max = 2, ilevel = 4 },
+	[380] = { upgrade = 2, max = 2, ilevel = 4 },
+	[445] = { upgrade = 0, max = 2, ilevel = 0 },
+	[446] = { upgrade = 1, max = 2, ilevel = 4 },
+	[447] = { upgrade = 2, max = 2, ilevel = 8 },
+	[451] = { upgrade = 0, max = 1, ilevel = 0 },
+	[452] = { upgrade = 1, max = 1, ilevel = 8 },
+	[453] = { upgrade = 0, max = 2, ilevel = 0 },
+	[454] = { upgrade = 1, max = 2, ilevel = 4 },
+	[455] = { upgrade = 2, max = 2, ilevel = 8 },
+	[456] = { upgrade = 0, max = 1, ilevel = 0 },
+	[457] = { upgrade = 1, max = 1, ilevel = 8 },
+	[458] = { upgrade = 0, max = 4, ilevel = 0 },
+	[459] = { upgrade = 1, max = 4, ilevel = 4 },
+	[460] = { upgrade = 2, max = 4, ilevel = 8 },
+	[461] = { upgrade = 3, max = 4, ilevel = 12 },
+	[462] = { upgrade = 4, max = 4, ilevel = 16 },
+	[465] = { upgrade = 0, max = 2, ilevel = 0 },
+	[466] = { upgrade = 1, max = 2, ilevel = 4 },
+	[467] = { upgrade = 2, max = 2, ilevel = 8 },
+	[468] = { upgrade = 0, max = 4, ilevel = 0 },
+	[469] = { upgrade = 1, max = 4, ilevel = 4 },
+	[470] = { upgrade = 2, max = 4, ilevel = 8 },
+	[471] = { upgrade = 3, max = 4, ilevel = 12 },
+	[472] = { upgrade = 4, max = 4, ilevel = 16 },
+	[491] = { upgrade = 0, max = 4, ilevel = 0 },
+	[492] = { upgrade = 1, max = 4, ilevel = 4 },
+	[493] = { upgrade = 2, max = 4, ilevel = 8 },
+	[494] = { upgrade = 0, max = 6, ilevel = 0 },
+	[495] = { upgrade = 1, max = 6, ilevel = 4 },
+	[496] = { upgrade = 2, max = 6, ilevel = 8 },
+	[497] = { upgrade = 3, max = 6, ilevel = 12 },
+	[498] = { upgrade = 4, max = 6, ilevel = 16 },
+	[503] = { upgrade = 3, max = 3, ilevel = 1 },
+	[504] = { upgrade = 3, max = 4, ilevel = 12 },
+	[505] = { upgrade = 4, max = 4, ilevel = 16 },
+	[506] = { upgrade = 5, max = 6, ilevel = 20 },
+	[507] = { upgrade = 6, max = 6, ilevel = 24 },
+	[529] = { upgrade = 0, max = 2, ilevel = 0 },
+	[530] = { upgrade = 1, max = 2, ilevel = 5 },
+	[531] = { upgrade = 2, max = 2, ilevel = 10 },
+	[535] = { upgrade = 1, max = 3, ilevel = 15 },
+	[536] = { upgrade = 2, max = 3, ilevel = 30 },
+	[537] = { upgrade = 3, max = 3, ilevel = 45 },
+	[538] = { upgrade = 0, max = 3, ilevel = 0 },
+
+}
+do
+	local stub = { ilevel = 0 }
+	setmetatable(upgradeTable, { __index = function(t, key)
+		return stub
+	end})
+end
+-- Tooltip Scanning stuff
+local itemLevelPattern = _G.ITEM_LEVEL:gsub("%%d", "(%%d+)")
+local soulboundPattern = _G.ITEM_SOULBOUND
+local boePattern=_G.ITEM_BIND_ON_EQUIP
+local bopPattern=_G.ITEM_BIND_ON_PICKUP
+local boaPattern1=_G.ITEM_BIND_TO_BNETACCOUNT
+local boaPattern2=_G.ITEM_BNETACCOUNTBOUND
+
+local scanningTooltip
+local itemCache = setmetatable({},{__index=function(table,key) return {} end})
+local heirloomcolor
+local emptytable={}
+function _G.ScanTip(itemLink,itemLevel,show)
+	if type(itemLink)=="number" then
+		itemLink=select(2,GetItemInfo(itemLink))
+		if not itemLink then return emptytable end
+	end
+	if true or type(itemCache[itemLink].ilevel)=="nil" then
+		if not scanningTooltip then
+			scanningTooltip = _G.CreateFrame("GameTooltip", "LibItemUpgradeInfoTooltip", nil, "GameTooltipTemplate")
+			scanningTooltip:SetOwner(_G.WorldFrame, "ANCHOR_NONE")
+		end
+		scanningTooltip:ClearLines()
+		local rc,message=pcall(scanningTooltip.SetHyperlink,scanningTooltip,itemLink)
+		if (not rc) then
+			return emptytable
+		end
+		local quality=select(3,GetItemInfo(itemLink))
+				-- line 1 is the item name
+		-- line 2 may be the item level, or it may be a modifier like "Heroic"
+		-- check up to line 6 just in case
+		local ilevel,soulbound,bop,boe,boa,heirloom
+		for i = 2, 6 do
+			local label, text = _G["LibItemUpgradeInfoTooltipTextLeft"..i], nil
+			if label then text=label:GetText() end
+			if text then
+				if ilevel==nil then ilevel = tonumber(text:match(itemLevelPattern)) end
+				if soulbound==nil then soulbound = text:find(soulboundPattern) end
+				if bop==nil then bop = text:find(bopPattern) end
+				if boe==nil then boe = text:find(boePattern) end
+				if boa==nil then boa = text:find(boaPattern1) end
+				if boa==nil then boa = text:find(boaPattern2) end
+			end
+		end
+		itemCache[itemLink]={ilevel=ilevel or itemLevel,soulbound=soulbound,bop=bop,boe=boe,quality=quality}
+	end
+	return itemCache[itemLink]
+end
+
+
+-- GetUpgradeID(itemString)
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Number - The upgrade ID (possibly 0), or nil if the input is invalid or
+--            does not contain upgrade info
+function lib:GetUpgradeID(itemString)
+	if type(itemString)~="string" then return end
+	local itemString = itemString:match("item[%-?%d:]+") or ""-- Standardize itemlink to itemstring
+	local instaid, _, numBonuses, affixes = select(12, strsplit(":", itemString, 15))
+	instaid=tonumber(instaid) or 7
+	numBonuses=tonumber(numBonuses) or 0
+	if instaid >0 and (instaid-4)%8==0 then
+		return tonumber((select(numBonuses + 1, strsplit(":", affixes))))
+	end
+end
+
+-- GetCurrentUpgrade(id)
+--
+-- Returns the current upgrade level of the item, e.g. 1 for a 1/2 item.
+--
+-- Arguments:
+--   id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
+--
+-- Returns:
+--   Number - The current upgrade level of the item. Returns nil if the item
+--            cannot be upgraded
+function lib:GetCurrentUpgrade(id)
+	return upgradeTable[id].upgrade
+end
+
+-- GetMaximumUpgrade(id)
+--
+-- Returns the maximum upgrade level of the item, e.g. 2 for a 1/2 item.
+--
+-- Arguments:
+--   id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
+--
+-- Returns:
+--   Number - The maximum upgrade level of the item. Returns nil if the item
+--            cannot be upgraded
+function lib:GetMaximumUpgrade(id)
+	return upgradeTable[id].max
+end
+
+-- GetItemLevelUpgrade(id)
+--
+-- Returns the item level increase that this upgrade is worth, e.g. 4 for a
+-- 1/2 item or 8 for a 2/2 item.
+--
+-- Arguments:
+--   id - Number - The upgrade ID of the item (obtained via GetUpgradeID())
+--
+-- Returns:
+--   Number - The item level increase of the item. Returns 0 if the item
+--            cannot be or has not been upgraded
+function lib:GetItemLevelUpgrade(id)
+	return upgradeTable[id].ilevel
+end
+
+-- GetItemUpgradeInfo(itemString)
+--
+-- Returns the current upgrade level, maximum upgrade level, and item level
+-- increase for an item.
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns if the item can be upgraded:
+--   Number - The current upgrade level of the item
+--   Number - The maximum upgrade level of the item
+--   Number - The item level increase of the item
+-- or if the item cannot be upgraded:
+--   nil
+--   nil
+--   0
+-- or if the item is invalid or does not contain upgrade info:
+--   nil
+function lib:GetItemUpgradeInfo(itemString)
+	local id = self:GetUpgradeID(itemString)
+	if id then
+		local cur = self:GetCurrentUpgrade(id)
+		local max = self:GetMaximumUpgrade(id)
+		local delta = self:GetItemLevelUpgrade(id)
+		return cur, max, delta
+	end
+	return nil
+end
+
+-- GetHeirloomTrueLevel(itemString)
+--
+-- Returns the true item level for an heirloom (actually, returns the true level for any adapting item)
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Number, Boolean - The true item level of the item. If the item is not
+--                     an heirloom, or an error occurs when trying to scan the
+--                     item tooltip, the second return value is false. Otherwise
+--                     the second return value is true. If the input is invalid,
+--                     (nil, false) is returned.
+-- Convert the ITEM_LEVEL constant into a pattern for our use
+function lib:GetHeirloomTrueLevel(itemString)
+	if type(itemString) ~= "string" then return nil,false end
+	local _, itemLink, rarity, itemLevel = GetItemInfo(itemString)
+	if (not itemLink) then
+		return nil,false
+	end
+	local rc=ScanTip(itemLink,itemLevel)
+	if rc.ilevel then
+		return rc.ilevel,true
+	end
+	return itemLevel, false
+end
+
+-- GetUpgradedItemLevel(itemString)
+--
+-- Returns the true item level of the item, including upgrades and heirlooms.
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Number - The true item level of the item, or nil if the input is invalid
+function lib:GetUpgradedItemLevel(itemString)
+	-- check for heirlooms first
+	local ilvl, isTrue = self:GetHeirloomTrueLevel(itemString)
+	if isTrue then
+		return ilvl
+	end
+	-- not an heirloom? fall back to the regular item logic
+	local id = self:GetUpgradeID(itemString)
+	if ilvl and id then
+		ilvl = ilvl + self:GetItemLevelUpgrade(id)
+	end
+	return ilvl
+end
+
+-- IsBop(itemString)
+--
+-- Check an item for  Bind On Pickup.
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Boolean - True if Bind On Pickup
+
+function lib:IsBop(itemString)
+	local rc=ScanTip(itemString)
+	return rc.bop
+end
+-- IsBoe(itemString)
+--
+-- Check an item for  Bind On Equip.
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Boolean - True if Bind On Equip
+
+function lib:IsBoe(itemString)
+	local rc=ScanTip(itemString)
+	return rc.boe
+end
+-- IsBoa(itemString)
+--
+-- Check an item for  Bind On Aaccount
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Boolean - True if Bind On Equip
+
+function lib:IsBoa(itemString)
+	local rc=ScanTip(itemString)
+	return rc.boa
+end
+
+-- IsArtifact(itemString)
+--
+-- Check an item for  Heirloom
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Boolean - True if Artifact
+
+function lib:IsArtifact(itemString)
+	local rc=ScanTip(itemString)
+	return rc.quality==LE_ITEM_QUALITY_ARTIFACT
+end
+
+
+
+-- IsHeirloom(itemString)
+--
+-- Check an item for  Heirloom
+--
+-- Arguments:
+--   itemString - String - An itemLink or itemString denoting the item
+--
+-- Returns:
+--   Boolean - True if Heirloom
+
+function lib:IsHeirloom(itemString)
+	local rc=ScanTip(itemString)
+	return rc.quality==LE_ITEM_QUALITY_HEIRLOOM
+end
+
+
+
+local GetItemInfo=GetItemInfo
+lib.itemcache=lib.itemcache or
+	setmetatable({miss=0,tot=0},{
+		__index=function(table,key)
+			if (not key) then return "" end
+			if (key=="miss") then return 0 end
+			if (key=="tot") then return 0 end
+			local cached={GetItemInfo(key)}
+			if #cached==0 then return nil end
+			local itemLink=cached[2]
+			if not itemLink then return nil end
+			local itemID=lib:GetItemID(itemLink)
+			local name=cached[1]
+			rawset(table,itemLink,cached)
+			rawset(table,itemID,cached)
+			rawset(table,name,cached)
+			table.miss=table.miss+1
+			return cached
+		end
+
+	})
+local CachedGetItemInfo	--#function
+do
+	local cache,select,unpack=lib.itemcache,select,unpack
+	function CachedGetItemInfo(key,index)
+		if not key then return nil end
+		index=index or 1
+		cache.tot=cache.tot+1
+		local cached=cache[key]
+		if cached and type(cached)=='table' then
+			return select(index,unpack(cached))
+		else
+			rawset(cache,key,nil) -- voiding broken cache entry
+		end
+	end
+end
+---
+-- Parses an itemlink and returns itemId without calling API again
+-- @param #Lib self
+-- @param #string itemlink
+-- @return #number itemId or 0
+function lib:GetItemID(itemlink)
+	if (type(itemlink)=="string") then
+			local itemid,context=GetItemInfoFromHyperlink(itemlink)
+			return tonumber(itemid) or 0
+			--return tonumber(itemlink:match("Hitem:(%d+):")) or 0
+	else
+			return 0
+	end
+end
+
+---
+--
+-- Returns a caching version of GetItemInfo. Can be used to override the original one.
+-- Adds a second parameter to directly retrieving a specific value
+-- (Note: internally uses select so it's actually like calling select(n,GetItemInfo(itemID))
+--
+-- Arguments:
+--   self #lib self
+--
+-- Returns:
+--   #function The new function
+function lib:GetCachingGetItemInfo()
+	return CachedGetItemInfo
+end
+function lib:GetCacheStats()
+	local c=lib.itemcache
+	local h=c.tot-c.miss
+	local perc=( h>0) and h/c.tot*100 or 0
+	return c.miss,h,perc
+end
+
+--[===========[ ]===========]
+--[===[ Debug utilities ]===]
+--[===========[ ]===========]
+
+local function compareTables(t1, t2)
+	local seen = {}
+	for k, v1 in pairs(t1) do
+		seen[k] = true
+		local v2 = rawget(t2, k)
+		if not v2 then return false end
+		if type(v1) ~= type(v2) then return false end
+		if type(v1) == "table" then
+			if not compareTables(v1, v2) then return false end
+		elseif v1 ~= v2 then return false end
+	end
+	for k in pairs(t2) do
+		if not seen[k] then return false end
+	end
+	return true
+end
+
+-- prints the table rows in red and green
+-- omits the lead { and the trailing }
+local function printDiffTable(t1, t2)
+	local keys, seen = {}, {}
+	for k in pairs(t1) do
+		keys[#keys+1] = k
+		seen[k] = true
+	end
+	for k in pairs(t2) do
+		if not seen[k] then
+			keys[#keys+1] = k
+		end
+	end
+	table.sort(keys)
+	local function formatTable(t)
+		local comps = {}
+		for k, v in pairs(t) do
+			comps[#comps+1] = ("%s = %d"):format(k, v)
+		end
+		return "{ " .. table.concat(comps, ", ") .. " }"
+	end
+	for _, k in ipairs(keys) do
+		local v1, v2 = rawget(t1, k), rawget(t2, k)
+		local equal
+		if type(v1) == "table" and type(v2) == "table" then equal = compareTables(v1, v2)
+		else equal = v1 == v2 end
+		if not equal then
+			if v1 then
+				pp(("|cffff0000    [%d] = %s,|r"):format(k, formatTable(v1)))
+			end
+			if v2 then
+				pp(("|cff00ff00    [%d] = %s,|r"):format(k, formatTable(v2)))
+			end
+		end
+	end
+end
+
+-- Scans the first 10000 upgrade IDs
+-- Run this with /run LibStub:GetLibrary("LibItemUpgradeInfo-1.0"):_CheckUpgradeTable()
+-- If you don't have Aspirant's Staff of Harmony cached it may error out, just try again.
+do
+	local debugFrame
+	local worker
+	local newTable
+	local debugTooltip
+	function lib:_CheckUpgradeTable(itemLink)
+		if worker then
+			pp("|cffff0000LibItemUpgradeInfo-1.0: upgrade check already in progress")
+			return
+		end
+		if not debugFrame then
+			debugFrame = _G.CreateFrame("frame")
+			debugFrame:Hide()
+			debugFrame:SetScript("OnUpdate", function()
+				local ok, result, count, max = pcall(worker)
+				if not ok or result then
+					debugFrame:Hide()
+					worker = nil
+				end
+				if not ok then
+					pp("|cffff0000LibItemUpgradeInfo-1.0 error: " .. result .. "|r")
+				elseif result then
+					pp("LibItemUpgradeInfo-1.0: scan complete")
+					if compareTables(upgradeTable, newTable) then
+						pp("LibItemUpgradeInfo-1.0: |cff00ff00No changes|r")
+					else
+						pp("LibItemUpgradeInfo-1.0: |cffff0000New table:|r {")
+						printDiffTable(upgradeTable, newTable)
+						pp("}")
+					end
+				else
+					pp("LibItemUpgradeInfo-1.0: scanning " .. count .. "/" .. max)
+				end
+			end)
+		end
+		if not debugTooltip then
+			debugTooltip = _G.CreateFrame("GameTooltip", "LibItemUpgradeInfoDebugTooltip", nil, "GameTooltipTemplate")
+			debugTooltip:SetOwner(_G.WorldFrame, "ANCHOR_NONE")
+		end
+		newTable = {}
+		--local itemLink = "|cff0070dd|Hitem:89551:0:0:0:0:0:0:0:90:253:0:0:1:0|h[Aspirant's Staff of Harmony]|h|r"
+		local itemLink = itemLink or "|cff0070dd|Hitem:89551:0:0:0:0:0:0:0:100:253:4:0:0:0|h[Aspirant's Staff of Harmony]|h|r"
+-- Livello è il 9,upgradeid il 14. Al decimo posto, un valore che deve essere 4 o 4+n *8) per far scattare l'uso dell'upgradeid
+		local itemLevel = select(4, _G.GetItemInfo(itemLink))
+		assert(itemLevel, "Can't find item level for itemLink")
+		local count, max, batchsize = 0, 10000, 200
+		worker = function()
+			for i = count, math.min(max, count+batchsize) do
+				local link = itemLink:gsub("%d+|h", i.."|h")
+				debugTooltip:ClearLines()
+				debugTooltip:SetHyperlink(link)
+				local upgrade, max
+				local curLevel, maxLevel = _G.LibItemUpgradeInfoDebugTooltipTextLeft3:GetText():match("^Upgrade Level: (%d+)/(%d+)")
+				local ilvl = tonumber(_G.LibItemUpgradeInfoDebugTooltipTextLeft2:GetText():match("Item Level (%d+)"))
+				if not ilvl then
+					ilvl = tonumber(_G.LibItemUpgradeInfoDebugTooltipTextLeft3:GetText():match("Item Level (%d+)"))
+				end
+				assert(ilvl ~= nil, "Can't find ItemLevel in tooltip: " .. _G.LibItemUpgradeInfoDebugTooltipTextLeft2:GetText())
+				if curLevel or maxLevel or ilvl ~= itemLevel then
+					newTable[i] = { upgrade = tonumber(curLevel), max = tonumber(maxLevel), ilevel = ilvl - itemLevel }
+				end
+			end
+			count = count + batchsize
+			return (count > max), count, max
+		end
+		debugFrame:Show()
+	end
+end
+
+-- vim: set noet sw=4 ts=4:
diff --git a/SVUI_!Core/libs/LibReputationData-1.0/LibReputationData-1.0.lua b/SVUI_!Core/libs/LibReputationData-1.0/LibReputationData-1.0.lua
new file mode 100644
index 0000000..974d279
--- /dev/null
+++ b/SVUI_!Core/libs/LibReputationData-1.0/LibReputationData-1.0.lua
@@ -0,0 +1,265 @@
+local MAJOR, MINOR = "LibReputationData-1.0", 1
+
+assert(_G.LibStub, MAJOR .. " requires LibStub")
+local lib = _G.LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+
+lib.callbacks = lib.callbacks or _G.LibStub("CallbackHandler-1.0"):New(lib)
+
+-- local store
+local reputationChanges = {}
+local allFactions = {}
+local watchedFaction = 0
+
+-- blizzard api
+local GetFactionInfo                = _G.GetFactionInfo
+local GetFriendshipReputation		= _G.GetFriendshipReputation
+local IsFactionInactive 			= _G.IsFactionInactive
+local SetWatchedFactionIndex        = _G.SetWatchedFactionIndex
+local TimerAfter					= _G.C_Timer.After
+
+-- lua api
+local select   = _G.select
+local strmatch = _G.string.match
+local tonumber = _G.tonumber
+
+local private = {} -- private space for the event handlers
+
+lib.frame = lib.frame or _G.CreateFrame("Frame")
+local frame = lib.frame
+frame:UnregisterAllEvents() -- deactivate old versions
+frame:SetScript("OnEvent", function(_, event, ...) private[event](event, ...) end)
+frame:RegisterEvent("PLAYER_ENTERING_WORLD")
+
+local function CopyTable(tbl)
+	if not tbl then return {} end
+	local copy = {};
+	for k, v in pairs(tbl) do
+		if ( type(v) == "table" ) then
+			copy[k] = CopyTable(v);
+		else
+			copy[k] = v;
+		end
+	end
+	return copy;
+end
+
+local function GetFLocalFactionInfo(factionIndex)
+	return allFactions[factionIndex]
+end
+
+local function GetFactionIndex(factionName)
+	for i = 1, #allFactions do
+		local name, _, _, _, _, _, _, _, _, _, _, _, _ = GetFLocalFactionInfo(i);
+		if name == factionName then return i end
+	end
+end
+
+local function GetFactionData(factionIndex)
+
+	local name, _, standingID, bottomValue, topValue, earnedValue, _,
+		_, isHeader, isCollapsed, hasRep, isWatched, isChild, factionID = GetFactionInfo(factionIndex)
+	if not name then return nil end
+
+	if isWatched then watchedFaction = factionIndex end
+	local standingText = _G['FACTION_STANDING_LABEL'..standingID]
+
+	local friendID, friendRep, friendMaxRep, _, _, _, friendTextLevel, friendThresh = GetFriendshipReputation(factionID)
+	if friendID ~= nil then
+		bottomValue = friendThresh
+		if nextThresh then
+			topValue = friendThresh + min( friendMaxRep - friendThresh, 8400 ) -- Magic number! Yay!
+		end
+		earnedValue = friendRep
+		standingText = friendTextLevel
+	end
+
+	local faction = {
+		factionIndex = factionIndex,
+		name = name,
+		standingID = standingID,
+		standing = standingText,
+		min = bottomValue,
+		max = topValue,
+		value = earnedValue,
+		isHeader = isHeader,
+		isChild = isChild,
+		hasRep = hasRep,
+		isActive = not IsFactionInactive(factionIndex),
+		factionID = factionID,
+		friendID = friendID
+	}
+	return faction
+end
+
+-- Refresh the list of known factions
+local function RefreshAllFactions()
+	local i = 1
+	local lastName
+	local factions = {}
+
+	repeat
+		local name, description, standingId, bottomValue, topValue, earnedValue, atWarWith,
+			canToggleAtWar, isHeader, isCollapsed, hasRep, isWatched, isChild, factionID = GetFactionInfo(i)
+		if not name or name == lastName and name ~= GUILD then break end
+
+		lastName = name
+		local faction = GetFactionData(i)
+
+		if faction then
+			tinsert(factions, faction)
+		end
+
+		if isCollapsed then ExpandFactionHeader(i) end
+		i = i + 1
+	until i > 200
+	allFactions = factions
+	lib.callbacks:Fire("FACTIONS_LOADED")
+end
+
+local function UpdateFaction(factionIndex)
+	allFactions[factionIndex] = GetFactionData(factionIndex)
+end
+
+
+------------------------------------------------------------------------------
+-- Ensure factions and guild info are loaded
+------------------------------------------------------------------------------
+local function EnsureFactionsLoaded()
+	-- Sometimes it takes a while for faction and guild info
+	-- to load when the game boots up so we need to periodically
+	-- check whether its loaded before we can display it
+	if GetFactionInfo(1) == nil or (IsInGuild() and GetGuildInfo("player") == nil) then
+			TimerAfter(0.5, EnsureFactionsLoaded)
+	else
+		-- Refresh all factions and notify subscribers
+		RefreshAllFactions()
+	end
+end
+
+------------------------------------------------------------------------------
+-- Update reputation
+------------------------------------------------------------------------------
+local function UpdateReputationChanges()
+
+	RefreshAllFactions()
+
+	-- Build sorted change table
+	local changes = {}
+	for name, amount in pairs(reputationChanges) do
+
+		local factionIndex= GetFactionIndex(name)
+		if factionIndex then
+			UpdateFaction(factionIndex)
+			tinsert(changes, {
+				name = name,
+				amount = amount,
+				factionIndex = factionIndex
+			})
+		end
+	end
+
+	if #changes > 1 then
+		table.sort(changes, function(a, b) return a.amount > b.amount end)
+	end
+
+	if #changes > 0 then
+		-- Notify subscribers
+		InformReputationsChanged(changes)
+	end
+
+	reputationChanges = {}
+end
+
+
+local function InformReputationsChanged(changes)
+	for _,_,factionIndex in changes do
+		lib.callbacks:Fire("REPUTATION_CHANGED", factionIndex)
+	end
+end
+
+------------------------------------------------------------------------------
+-- Events
+------------------------------------------------------------------------------
+function private.PLAYER_ENTERING_WORLD(event)
+	TimerAfter(3, function()
+		frame:RegisterEvent("COMBAT_TEXT_UPDATE")
+		frame:RegisterEvent("UPDATE_FACTION")
+		EnsureFactionsLoaded()
+	end)
+end
+
+function private.COMBAT_TEXT_UPDATE(event, type, name, amount)
+	if (type == "FACTION") then
+		if IsInGuild() then
+			-- Check name for guild reputation
+			if name == GUILD then
+				name = (GetGuildInfo("player"))
+				if not name or name == "" then return end
+			end
+		end
+
+		if not reputationChanges[name] then
+			reputationChanges[name] = amount
+		else
+			reputationChanges[name] = reputationChanges[name] + amount
+		end
+
+		TimerAfter(0.5,UpdateReputationChanges)
+
+	end
+end
+
+function private.UPDATE_FACTION(event)
+	RefreshAllFactions()
+end
+
+------------------------------------------------------------------------------
+-- API
+------------------------------------------------------------------------------
+function lib:SetWatchedFaction(factionIndex)
+
+	SetWatchedFactionIndex(factionIndex)
+	watchedFaction = factionIndex
+	lib.callbacks:Fire("REPUTATION_CHANGED", factionIndex)
+end
+
+function lib:GetWatchedFactionIndex()
+	return watchedFaction
+end
+
+function lib:GetReputationInfo(_, factionIndex)
+	factionIndex = factionIndex or watchedFaction
+	if allFactions[factionIndex] then
+		return factionIndex, CopyTable(allFactions[factionIndex])
+	else
+		return nil,nil
+	end
+end
+
+function lib:GetAllFactionsInfo()
+	return CopyTable(allFactions)
+end
+
+function lib:GetAllActiveFactionsInfo()
+	local activeFactions = {}
+	for i=1,#allFactions do
+		if allFactions[i].isActive then
+			tinsert(activeFactions,allFactions[i])
+		end
+	end
+
+	if #activeFactions > 0 then
+		return CopyTable(activeFactions)
+	else
+		return nil
+	end
+end
+
+function lib:GetNumObtainedReputations()
+	return #allFactions
+end
+
+function lib:ForceUpdate()
+	EnsureFactionsLoaded()
+end
diff --git a/SVUI_!Core/libs/_SVUI_Lib/Librarian.lua b/SVUI_!Core/libs/_SVUI_Lib/Librarian.lua
new file mode 100644
index 0000000..1a788d7
--- /dev/null
+++ b/SVUI_!Core/libs/_SVUI_Lib/Librarian.lua
@@ -0,0 +1,68 @@
+--[[
+Librarian is a library used to manage localization, packages, scripts, animations and data embedded
+into the SVUI core addon.
+
+It's main purpose is to keep all methods and logic needed to properly keep
+core add-ins functioning outside of the core object and away from other libraries like LibStub.
+--]]
+local _G            = getfenv(0)
+local assert        = _G.assert;
+local type          = _G.type;
+local error         = _G.error;
+local pairs         = _G.pairs;
+local tostring      = _G.tostring;
+
+local Librarian = _G["Librarian"]
+
+if not Librarian then
+    Librarian = Librarian or {libs = {}, arrested = {}, warrants = {}}
+    _G["Librarian"] = Librarian
+
+    function Librarian:NewLibrary(libName)
+        assert(type(libName) == "string", "Missing Library Name")
+        self.libs[libName] = self.libs[libName] or {}
+        return self.libs[libName]
+    end
+
+    function Librarian:Fetch(libName, silent)
+        if not self.libs[libName] and not silent then
+            error(("Cannot find a library instance of %q."):format(tostring(libName)), 2)
+        end
+        return self.libs[libName]
+    end
+
+    local dead = function() return end
+
+    function Librarian:LockLibrary(lib)
+        local LibStub = _G.LibStub;
+        if((self.warrants[lib]) or (not LibStub) or (not LibStub.libs)) then return end
+        for libName,libObj in pairs(LibStub.libs) do
+            if(libName:find(lib) and (not self.arrested[libName])) then
+                self.warrants[lib] = true
+                self.arrested[libName] = {}
+                for k,v in pairs(libObj) do
+                    if(type(v) == 'function') then
+                        self.arrested[libName][k] = v
+                        v = dead
+                    end
+                end
+            end
+        end
+    end
+
+    function Librarian:UnlockLibrary(lib)
+        local LibStub = _G.LibStub;
+        if((not LibStub) or (not LibStub.libs)) then return end
+        for libName,libObj in pairs(LibStub.libs) do
+            if(libName:find(lib) and (self.arrested[libName])) then
+                for k,v in pairs(self.arrested[libName]) do
+                    libObj[k] = v
+                end
+                self.warrants[lib] = nil
+                self.arrested[libName] = nil
+            end
+        end
+    end
+
+    setmetatable(Librarian, { __call = Librarian.Fetch })
+end
diff --git a/SVUI_!Core/libs/_load.xml b/SVUI_!Core/libs/_load.xml
index 8032db0..a8d5492 100644
--- a/SVUI_!Core/libs/_load.xml
+++ b/SVUI_!Core/libs/_load.xml
@@ -6,4 +6,7 @@
 	<Include file="AceGUI-3.0\AceGUI-3.0.xml"/>
 	<Include file="AceConfig-3.0\AceConfig-3.0.xml"/>
 	<Include file="AceVillain-1.0\AceVillain-1.0.xml"/>
+	<Script file="LibArtifactData-1.0\LibArtifactData-1.0.lua"/>
+	<Script file="LibReputationData-1.0\LibReputationData-1.0.lua"/>
+	<Script file="LibItemUpgradeInfo-1.0\Core.lua"/>
 </Ui>
diff --git a/SVUI_!Core/system/_docklets/garrison.lua b/SVUI_!Core/system/_docklets/garrison.lua
index f13bcf3..2c0fbe8 100644
--- a/SVUI_!Core/system/_docklets/garrison.lua
+++ b/SVUI_!Core/system/_docklets/garrison.lua
@@ -80,6 +80,47 @@ local GarrisonData = {};
 LOCALS
 ##########################################################
 ]]--
+
+local function GetInProgressMissions()
+    local garrisonMission = {}
+
+    local types = {
+        LE_FOLLOWER_TYPE_GARRISON_7_0,
+        LE_FOLLOWER_TYPE_GARRISON_6_0,
+        LE_FOLLOWER_TYPE_SHIPYARD_6_2
+    }
+
+    for key, type in pairs(types) do
+        local localMission = {}
+        C_Garrison.GetInProgressMissions(localMission, type)
+        for i = 1, #localMission do
+            garrisonMission[#garrisonMission + 1] = localMission[i]
+        end
+    end
+
+    return garrisonMission
+end
+
+local function GetCompleteMissions()
+    local garrisonMission = {}
+
+    local types = {
+        LE_FOLLOWER_TYPE_GARRISON_7_0,
+        LE_FOLLOWER_TYPE_GARRISON_6_0,
+        LE_FOLLOWER_TYPE_SHIPYARD_6_2
+    }
+
+    for key, type in pairs(types) do
+        local localMission = {}
+        C_Garrison.GetCompleteMissions(garrisonMission, type)
+        for i = 1, #localMission do
+            garrisonMission[#garrisonMission + 1] = localMission[i]
+        end
+    end
+
+    return garrisonMission
+end
+
 local function GetDockCooldown(itemID)
 	local start,duration = GetItemCooldown(itemID)
 	local expires = duration - (GetTime() - start)
@@ -125,6 +166,8 @@ local GarrisonButton_OnEvent = function(self, event, ...)
 		self:StartAlert();
 	elseif ( event == "GARRISON_MISSION_NPC_OPENED" ) then
 		self:StopAlert();
+	elseif ( event == "GARRISON_SHIPYARD_NPC_OPENED" ) then
+		self:StopAlert();
 	elseif (event == "GARRISON_INVASION_AVAILABLE") then
 		self:StartAlert();
 	elseif (event == "GARRISON_INVASION_UNAVAILABLE") then
@@ -153,6 +196,8 @@ end
 local function GetActiveMissions()
 	wipe(GarrisonData)
 	local hasMission = false
+	local inProgressMissions = {}
+	local completedMissions = {}

 	GameTooltip:AddLine(" ", 1, 1, 1)
 	GameTooltip:AddLine("Active Missions", 1, 0.7, 0)
@@ -239,12 +284,19 @@ end

 local SetGarrisonTooltip = function(self)
 	if(not InCombatLockdown()) then C_Garrison.RequestLandingPageShipmentInfo() end
-	local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(824)
+	local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(1220)
 	local texStr = ("\124T%s:12\124t %d"):format(tex, amount)
 	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
+	name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(1155)
+	texStr = ("\124T%s:12\124t %d"):format(tex, amount)
+	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
+	name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(824)
+	texStr = ("\124T%s:12\124t %d"):format(tex, amount)
+	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
 	name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(1101)
 	texStr = ("\124T%s:12\124t %d"):format(tex, amount)
 	GameTooltip:AddDoubleLine(name, texStr, 1, 1, 0, 1, 1, 1)
+
 	GetActiveMissions()
 	GetBuildingData()
 	if(self.StopAlert) then
@@ -274,7 +326,7 @@ local function LoadToolBarGarrison()
 		return
 	end

-	local garrison = SV.Dock:SetDockButton("BottomLeft", L["Garrison Landing Page"], "SVUI_Garrison", SV.media.dock.garrisonToolIcon, SetGarrisonTooltip, "SecureActionButtonTemplate")
+	local garrison = SV.Dock:SetDockButton("BottomLeft", L["Landing Page"], "SVUI_Garrison", SV.media.dock.garrisonToolIcon, SetGarrisonTooltip, "SecureActionButtonTemplate")
 	garrison:SetAttribute("type1", "click")
 	garrison:SetAttribute("clickbutton", mmButton)

@@ -300,6 +352,7 @@ local function LoadToolBarGarrison()
 	garrison:RegisterEvent("GARRISON_ARCHITECT_OPENED");
 	garrison:RegisterEvent("GARRISON_MISSION_FINISHED");
 	garrison:RegisterEvent("GARRISON_MISSION_NPC_OPENED");
+	garrison:RegisterEvent("GARRISON_SHIPYARD_NPC_OPENED");
 	garrison:RegisterEvent("GARRISON_INVASION_AVAILABLE");
 	garrison:RegisterEvent("GARRISON_INVASION_UNAVAILABLE");
 	garrison:RegisterEvent("SHIPMENT_UPDATE");
diff --git a/SVUI_!Core/system/_docklets/misc.lua b/SVUI_!Core/system/_docklets/misc.lua
index 7ef72f1..a7c36a7 100644
--- a/SVUI_!Core/system/_docklets/misc.lua
+++ b/SVUI_!Core/system/_docklets/misc.lua
@@ -60,6 +60,7 @@ local GetNumSpecGroups    	= _G.GetNumSpecGroups;
 local GetActiveSpecGroup    = _G.GetActiveSpecGroup;
 local SetActiveSpecGroup    = _G.SetActiveSpecGroup;
 local GetSpecializationInfo = _G.GetSpecializationInfo;
+local GetToyInfo            = _G.C_ToyBox.GetToyInfo;
 --[[
 ##########################################################
 ADDON
@@ -69,13 +70,22 @@ local SV = select(2, ...)
 local L = SV.L

 local MOD = SV.Dock;
+
+--Debug
+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("MiscTools")
+else
+	Debug = function() end
+end
+
 --[[
 ##########################################################
 LOCALS
 ##########################################################
 ]]--
-local HEARTH_SPELLS = {556,50977,18960,126892};
-local HEARTH_ITEMS = {6948,110560,64488,54452,93672,28585,128353};
+local HEARTH_SPELLS = {556,50977,18960,126892,193753};
+local HEARTH_ITEMS = {6948,110560,64488,54452,93672,28585,128353,140192};
 local HEARTH_LEFT_CLICK, HEARTH_RIGHT_CLICK = 6948, 110560;
 local HEARTH_HEADER = "HearthStone";

@@ -132,6 +142,12 @@ local function GetHearthOption(selected)
 						if(owned and owned > 0) then
 							option = test;
 						end
+					else
+						--JV: 20161002 - Fix for #66 Toys no longer return data from GetItemInfo
+						local _,test,_,collected = GetToyInfo(optionID)
+						if (test and type(test) == 'string') and collected then
+							option = test;
+						end
 					end
 				end
 			end
@@ -235,34 +251,55 @@ local Hearth_OnShiftRightClick = function(self)
 	end
 end

-local SpecSwap_OnClick = function(self)
-	if InCombatLockdown() then return end
-	local current = GetActiveSpecGroup()
-	if(current == 2) then
-		SetActiveSpecGroup(1)
+local SpecSwap_OnLeftClick = function(self)
+	if(IsShiftKeyDown()) then
+		local spec = GetSpecializationInfo(3)
+		if spec then SetSpecialization(3) end
 	else
-		SetActiveSpecGroup(2)
+		SetSpecialization(1)
 	end
 end

-local SpecSwap_OnEnter = function(self)
-	local currentGroup = GetActiveSpecGroup()
-	local currentSpec = GetSpecialization(false, false, currentGroup);
-	local text1 = currentSpec and select(2, GetSpecializationInfo(currentSpec)) or "None"
-	local otherGroup = 1;
-	local activeText = SPECIALIZATION_SECONDARY_ACTIVE;
-	local otherText = SPECIALIZATION_PRIMARY;
-	if(currentGroup == 1) then
-		otherGroup = 2
-		activeText = SPECIALIZATION_PRIMARY_ACTIVE;
-		otherText = SPECIALIZATION_SECONDARY;
+local SpecSwap_OnRightClick = function(self)
+	if(IsShiftKeyDown()) then
+		local spec = GetSpecializationInfo(4)
+		if spec then SetSpecialization(4) end
+	else
+		local spec = GetSpecializationInfo(2)
+		if spec then SetSpecialization(2) end
 	end
-	local otherSpec = GetSpecialization(false, false, otherGroup);
-	local text2 = otherSpec and select(2, GetSpecializationInfo(otherSpec)) or "None"
+end
+
+local SpecSwap_OnEnter = function(self)
 	GameTooltip:AddLine(GARRISON_SWITCH_SPECIALIZATIONS, 1, 1, 0)
 	GameTooltip:AddLine(" ", 1, 1, 1)
-	GameTooltip:AddDoubleLine(activeText, text1, 1, 0.5, 0, 1, 1, 1)
-	GameTooltip:AddDoubleLine(otherText, text2, 1, 0.5, 0, 1, 1, 1)
+
+	local specs = {}
+	local numSpecs = GetNumSpecializations()
+	local active = GetSpecialization()
+
+	if numSpecs then
+		for i=1,numSpecs do
+			local _, sname = GetSpecializationInfo(i)
+			tinsert(specs,i,{name=sname,r=1,g=1,b=1})
+			if i==tonumber(active) then
+				specs[i].r = 0.3
+				specs[i].g = 0.3
+				specs[i].b = 1
+			end
+		end
+
+		GameTooltip:AddDoubleLine("[Left-Click]", specs[1].name, 0, 1, 0, specs[1].r,specs[1].g,specs[1].b)
+		if(specs[3]) then
+			GameTooltip:AddDoubleLine("[SHIFT + Left-Click]", specs[3].name, 0, 1, 0,specs[3].r,specs[3].g,specs[3].b)
+		end
+		if(specs[2]) then
+			GameTooltip:AddDoubleLine("[Right-Click]", specs[2].name, 0, 1, 0, specs[2].r,specs[2].g,specs[2].b)
+		end
+		if(specs[4]) then
+			GameTooltip:AddDoubleLine("[SHIFT + Right-Click]", specs[4].name, 0, 1, 0,specs[4].r,specs[4].g,specs[4].b)
+		end
+	end
 end

 local PowerButton_OnLeftClick = function(self)
@@ -312,10 +349,12 @@ local function LoadMiscTools()

 	-- SPEC BUTTON
 	if(SV.db.Dock.dockTools.specswap and (not SVUI_SpecSwap)) then
-		local numSpecGroups = GetNumSpecGroups()
-		if(numSpecGroups and numSpecGroups == 2) then
+		Debug("Setting up spec swap dock")
+		local numSpecs = GetNumSpecializations()
+		if(numSpecs and numSpecs > 1) then
+			Debug("numSpecs = ", numSpecs)
 			local specSwap = SV.Dock:SetDockButton("BottomLeft", L["Spec Swap"], "SVUI_SpecSwap", SV.media.dock.specSwapIcon, SpecSwap_OnEnter)
-			specSwap:SetClickCallbacks(SpecSwap_OnClick);
+			specSwap:SetClickCallbacks(SpecSwap_OnLeftClick, SpecSwap_OnRightClick);
 		end
 	end

diff --git a/SVUI_!Core/system/_reports/artifact.lua b/SVUI_!Core/system/_reports/artifact.lua
new file mode 100644
index 0000000..6fac8dd
--- /dev/null
+++ b/SVUI_!Core/system/_reports/artifact.lua
@@ -0,0 +1,215 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local pairs 	= _G.pairs;
+local ipairs 	= _G.ipairs;
+local type 		= _G.type;
+local error 	= _G.error;
+local pcall 	= _G.pcall;
+local assert 	= _G.assert;
+local tostring 	= _G.tostring;
+local tonumber 	= _G.tonumber;
+local string 	= _G.string;
+local math 		= _G.math;
+local table 	= _G.table;
+--[[ STRING METHODS ]]--
+local lower, upper = string.lower, string.upper;
+local find, format, len, split = string.find, string.format, string.len, string.split;
+local match, sub, join = string.match, string.sub, string.join;
+local gmatch, gsub = string.gmatch, string.gsub;
+--[[ MATH METHODS ]]--
+local abs, ceil, floor, round = math.abs, math.ceil, math.floor, math.round;  -- Basic
+--[[ TABLE METHODS ]]--
+local twipe, tsort = table.wipe, table.sort;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L
+local Reports = SV.Reports;
+local LAD = LibStub("LibArtifactData-1.0");
+
+--Debug
+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("Reports")
+else
+	Debug = function() end
+end
+
+--[[
+##########################################################
+UTILITIES
+##########################################################
+]]--
+local function GetArtifactData()
+	local artID = LAD:GetActiveArtifactID()
+	Debug("GetArtifactData - GetActiveArtifactID returned artID: ",artID)
+	if not artID then return false end
+
+	local data = nil
+	artID, data = LAD:GetArtifactInfo(artID)
+	if not artID then return false end
+	Debug()
+
+	return true, data.numRanksPurchased, data.power, data.maxPower , data.numRanksPurchasable
+end
+
+local function SetTooltipText(report)
+	Reports:SetDataTip(report)
+	local isEquipped, rank, currentPower,powerToNextLevel,pointsToSpend = GetArtifactData()
+	Reports.ToolTip:AddLine(L["Artifact Power"])
+	Reports.ToolTip:AddLine(" ")
+
+	if isEquipped then
+		local calc1 = (currentPower / powerToNextLevel) * 100;
+		Reports.ToolTip:AddDoubleLine(L["Rank:"], (" %d "):format(rank), 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(L["Current Artifact Power:"], (" %d  /  %d (%d%%)"):format(currentPower, powerToNextLevel, calc1), 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(L["Remaining:"], (" %d "):format(powerToNextLevel - currentPower), 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(L["Points to Spend:"], format(" %d ", pointsToSpend), 1, 1, 1)
+	else
+		Reports.ToolTip:AddDoubleLine(L["No Artifact"])
+	end
+end
+
+local function FormatPower(rank, currentPower, powerForNextPoint, pointsToSpend)
+	local currentText = ("%d(+%d) %d/%d"):format(rank, pointsToSpend, currentPower, powerForNextPoint);
+	return currentText
+end
+
+
+--[[
+##########################################################
+REPORT TEMPLATE
+##########################################################
+]]--
+local REPORT_NAME = "Artifact";
+local HEX_COLOR = "22FFFF";
+--SV.media.color.green
+--SV.media.color.normal
+--r, g, b = 0.8, 0.8, 0.8
+--local c = SV.media.color.green
+--r, g, b = c[1], c[2], c[3]
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+Report.events = {"PLAYER_ENTERING_WORLD"};
+
+Report.OnEvent = function(self, event, ...)
+	Report.Populate(self)
+end
+
+Report.Populate = function(self)
+	if self.barframe:IsShown() then
+		self.text:SetAllPoints(self)
+		self.text:SetJustifyH("CENTER")
+		self.barframe:Hide()
+	end
+
+	local isEquipped,rank,currentPower,powerToNextLevel,pointsToSpend = GetArtifactData()
+
+	if isEquipped then
+		local text = FormatPower(rank, currentPower,powerToNextLevel,pointsToSpend);
+		self.text:SetText(text)
+	else
+		self.text:SetText(L["No Artifact"])
+	end
+end
+
+Report.OnEnter = function(self)
+	SetTooltipText(self)
+	Reports:ShowDataTip()
+end
+
+Report.OnInit = function(self)
+	LAD.RegisterCallback(self,"ARTIFACT_ADDED", function ()
+		Debug("Report: Caught Artifact Added")
+		Report.Populate(self)
+	end)
+	LAD.RegisterCallback(self,"ARTIFACT_ACTIVE_CHANGED", function ()
+		Debug("Report: Caught Artifact active changed")
+		Report.Populate(self)
+	end)
+	LAD.RegisterCallback(self,"ARTIFACT_POWER_CHANGED", function ()
+		Debug("Report: Caught Artifact power changed")
+		Report.Populate(self)
+	end)
+end
+
+--[[
+##########################################################
+BAR TYPE
+##########################################################
+]]--
+local BAR_NAME = "Artifact Bar";
+local ReportBar = Reports:NewReport(BAR_NAME, {
+	type = "data source",
+	text = BAR_NAME,
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+ReportBar.events = {"PLAYER_ENTERING_WORLD"};
+
+ReportBar.OnEvent = function(self, event, ...)
+	ReportBar.Populate(self)
+end
+
+ReportBar.Populate = function(self)
+	if (not self.barframe:IsShown())then
+		self.barframe:Show()
+		self.barframe.icon.texture:SetTexture(SV.media.dock.artifactLabel)
+	end
+	local bar = self.barframe.bar;
+
+	local isEquipped, rank, currentPower, powerToNextLevel, pointsToSpend = GetArtifactData()
+
+	if isEquipped then
+		bar:SetMinMaxValues(0, powerToNextLevel)
+		bar:SetValue(currentPower)
+		bar:SetStatusBarColor(0.9, 0.64, 0.37)
+		local toSpend = ""
+		if pointsToSpend>0 then
+			toSpend = " (+"..pointsToSpend..")"
+		end
+		self.text:SetText(rank..toSpend)
+	else
+		bar:SetMinMaxValues(0, 1)
+		bar:SetValue(0)
+		self.text:SetText(L["No Artifact"])
+	end
+end
+
+ReportBar.OnEnter = function(self)
+	SetTooltipText(self)
+	Reports:ShowDataTip()
+end
+
+ReportBar.OnInit = function(self)
+	LAD.RegisterCallback(self,"ARTIFACT_ADDED", function ()
+		Debug("Report: Caught Artifact Added")
+		ReportBar.Populate(self)
+	end)
+	LAD.RegisterCallback(self,"ARTIFACT_ACTIVE_CHANGED", function ()
+		Debug("Report: Caught Artifact active changed")
+		ReportBar.Populate(self)
+	end)
+	LAD.RegisterCallback(self,"ARTIFACT_POWER_CHANGED", function ()
+		Debug("Report: Caught Artifact power changed")
+		ReportBar.Populate(self)
+	end)
+end
diff --git a/SVUI_!Core/system/_reports/experience.lua b/SVUI_!Core/system/_reports/experience.lua
index ca85b65..98d0d75 100644
--- a/SVUI_!Core/system/_reports/experience.lua
+++ b/SVUI_!Core/system/_reports/experience.lua
@@ -141,11 +141,11 @@ local function FetchExperience()
 	return xp,mxp,exp,rxp
 end

-local function CacheRepData(data)
-	local nextIndex = #data+1;
-	data[nextIndex] = {text = factionName, func = fn};
-	tsort(data, function(a,b) return a.text < b.text end)
-end
+-- local function CacheRepData(data)
+-- 	local nextIndex = #data+1;
+-- 	data[nextIndex] = {text = factionName, func = fn};
+-- 	tsort(data, function(a,b) return a.text < b.text end)
+-- end
 --[[
 ##########################################################
 STANDARD TYPE
diff --git a/SVUI_!Core/system/_reports/reputation.lua b/SVUI_!Core/system/_reports/reputation.lua
index 4cfac70..ee00c6f 100644
--- a/SVUI_!Core/system/_reports/reputation.lua
+++ b/SVUI_!Core/system/_reports/reputation.lua
@@ -54,33 +54,47 @@ local function TruncateString(value)
     end
 end

-local sort_menu_fn = function(a,b) return a.text < b.text end;
+local sort_menu_fn = function(a,b)
+	if (a ~= nil and b ~= nil) then
+		if (a.text ~= nil and b.text ~= nil) then
+			return a.text < b.text
+		end
+	end
+	return false
+end;

 local function CacheRepData(data)
 	local count = 1;
 	local savedCount = #data;
+	ExpandAllFactionHeaders();
 	local totalFactions = GetNumFactions();
 	local maxCount = totalFactions;
 	if(savedCount > totalFactions) then maxCount = savedCount; end
+
 	for i=1, maxCount do
 		if(i <= totalFactions) then
-			local factionName, description, standingID, barMin, barMax, barValue, _, _, _, _, hasRep, isWatched, isChild = GetFactionInfo(i)
-			if(standingID) then
-				local fn = function()
-					local active = GetWatchedFactionInfo()
-					if factionName ~= active then
-						SetWatchedFactionIndex(i)
+			local factionName, description, standingID, barMin, barMax, barValue, _, _, isHeader, _, hasRep, isWatched, isChild = GetFactionInfo(i)
+
+			if((not isHeader) and standingID > 0) then
+				if not IsFactionInactive(i) then
+					local fn = function()
+						local active = GetWatchedFactionInfo()
+						if factionName ~= active then
+							SetWatchedFactionIndex(i)
+						end
 					end
+					data[count] = {text = factionName, func = fn};
+					--DEFAULT_CHAT_FRAME:AddMessage("Faction: " .. data[count].text .. " - " .. count)
+					count=count+1;
 				end
-				data[count] = {text = factionName, func = fn};
-				count=count+1;
 			end
 		else
-			data[count] = nil;
-			count=count+1;
+			tremove(data, count);
 		end
 	end
-	tsort(data, sort_menu_fn)
+	if #data > 0 then
+		tsort(data, sort_menu_fn);
+	end
 end
 --[[
 ##########################################################
diff --git a/SVUI_!Core/system/_reports/reputation_new.lua b/SVUI_!Core/system/_reports/reputation_new.lua
new file mode 100644
index 0000000..b8ef63d
--- /dev/null
+++ b/SVUI_!Core/system/_reports/reputation_new.lua
@@ -0,0 +1,197 @@
+--[[
+##############################################################################
+S V U I   By: Failcoder
+##############################################################################
+
+##########################################################
+LOCALIZED LUA FUNCTIONS
+##########################################################
+]]--
+--[[ GLOBALS ]]--
+local _G = _G;
+
+local select 	= _G.select;
+local table     = _G.table;
+local twipe     = table.wipe;
+local tsort     = table.sort;
+--[[ STRING METHODS ]]--
+local format, gsub = string.format, string.gsub;
+--[[
+##########################################################
+GET ADDON DATA
+##########################################################
+]]--
+local SV = select(2, ...)
+local L = SV.L;
+local Reports = SV.Reports;
+local LRD = LibStub("LibReputationData-1.0");
+--[[
+##########################################################
+REPUTATION STATS
+##########################################################
+]]--
+local HEX_COLOR = "22FFFF";
+local TEXT_PATTERN = "|cff22EF5F%s|r|cff888888 - [|r%d%%|cff888888]|r";
+local FACTION_BAR_COLORS = _G.FACTION_BAR_COLORS;
+
+local sort_menu_fn = function(a,b)
+	if (a ~= nil and b ~= nil) then
+		if (a.text ~= nil and b.text ~= nil) then
+			return a.text < b.text
+		end
+	end
+	return false
+end;
+
+local function CacheRepData(data)
+	local count = 1
+	local factions = LRD:GetAllActiveFactionsInfo();
+	if not factions then return end
+
+	twipe(data)
+
+	for i=1, #factions do
+		if(factions[i].isActive and (not factions[i].isHeader)) then
+			local factionIndex = tonumber(factions[i].factionIndex)
+			local fn = function()
+				local active = LRD:GetWatchedFactionIndex()
+				if factionIndex ~= active then
+					LRD:SetWatchedFaction(factionIndex)
+				end
+			end
+			tinsert(data,{text = factions[i].name, func = fn});
+			count=count+1;
+		end
+	end
+	if #data > 0 then
+		tsort(data, sort_menu_fn);
+	end
+end
+
+local function DoTooltip(self)
+	Reports:SetDataTip(self)
+	local factionIndex, faction = LRD:GetReputationInfo()
+
+	if not factionIndex then
+		Reports.ToolTip:AddLine("No Watched Factions")
+	else
+		Reports.ToolTip:AddLine(faction.name)
+		Reports.ToolTip:AddLine(' ')
+		Reports.ToolTip:AddDoubleLine(STANDING..':', faction.standing, 1, 1, 1)
+		Reports.ToolTip:AddDoubleLine(REPUTATION..':', format('%d / %d (%d%%)', faction.value - faction.min, faction.max - faction.min, (faction.value - faction.min) / (faction.max - faction.min) * 100), 1, 1, 1)
+	end
+	Reports.ToolTip:AddLine(" ", 1, 1, 1)
+	Reports.ToolTip:AddDoubleLine("[Click]", "Change Watched Faction", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
+end
+--[[
+##########################################################
+STANDARD TYPE
+##########################################################
+]]--
+
+local REPORT_NAME = "Reputation";
+local Report = Reports:NewReport(REPORT_NAME, {
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+
+Report.Populate = function(self)
+	if self.barframe:IsShown()then
+		self.text:SetAllPoints(self)
+		self.text:SetJustifyH("CENTER")
+		self.barframe:Hide()
+		self.text:SetAlpha(1)
+		self.text:SetShadowOffset(2, -4)
+	end
+	local factionIndex, faction = LRD:GetReputationInfo()
+
+	if not factionIndex then
+		self.text:SetText("No watched factions")
+	else
+		self.text:SetFormattedText(TEXT_PATTERN , faction.standing, ((faction.value - faction.min) / (faction.max - faction.min) * 100))
+	end
+end
+
+Report.OnClick = function(self, button)
+	SV.Dropdown:Open(self, self.InnerData, "Select Faction")
+end
+
+Report.OnEnter = function(self)
+	DoTooltip(self)
+end
+
+Report.OnInit = function(self)
+	LRD.RegisterCallback(self,"FACTIONS_LOADED", function ()
+		if(not self.InnerData) then
+			self.InnerData = {}
+		end
+		CacheRepData(self.InnerData)
+		Report.Populate(self)
+	end)
+	LRD.RegisterCallback(self, "REPUTATION_CHANGED", function()
+		Report.Populate(self)
+	end)
+	LRD:ForceUpdate()
+end
+--[[
+##########################################################
+BAR TYPE
+##########################################################
+]]--
+local BAR_NAME = "Reputation Bar";
+local ReportBar = Reports:NewReport(BAR_NAME, {
+	type = "data source",
+	text = BAR_NAME,
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+});
+
+
+ReportBar.Populate = function(self)
+	if not self.barframe:IsShown()then
+		self.barframe:Show()
+		self.barframe.icon.texture:SetTexture(SV.media.dock.reputationLabel)
+		self.text:SetAlpha(1)
+		self.text:SetShadowOffset(1, -2)
+	end
+	local bar = self.barframe.bar;
+
+	local factionIndex, faction = LRD:GetReputationInfo()
+
+	if not factionIndex then
+		bar:SetStatusBarColor(0,0,0)
+		bar:SetMinMaxValues(0,1)
+		bar:SetValue(0)
+		self.text:SetText("No Faction")
+	else
+		local color = FACTION_BAR_COLORS[faction.standingID]
+		bar:SetStatusBarColor(color.r, color.g, color.b)
+		bar:SetMinMaxValues(faction.min, faction.max)
+		bar:SetValue(faction.value)
+		self.text:SetText(faction.standing)
+	end
+end
+
+ReportBar.OnClick = function(self, button)
+	SV.Dropdown:Open(self, self.InnerData, "Select Faction")
+end
+
+ReportBar.OnEnter = function(self)
+	DoTooltip(self)
+end
+
+ReportBar.OnInit = function(self)
+	LRD.RegisterCallback(self,"FACTIONS_LOADED", function ()
+		if(not self.InnerData) then
+			self.InnerData = {}
+		end
+		CacheRepData(self.InnerData)
+		ReportBar.Populate(self)
+	end)
+	LRD.RegisterCallback(self, "REPUTATION_CHANGED", function()
+		ReportBar.Populate(self)
+	end)
+	LRD:ForceUpdate()
+end
\ No newline at end of file
diff --git a/SVUI_!Core/system/_reports/tokens.lua b/SVUI_!Core/system/_reports/tokens.lua
index 1621934..0d28688 100644
--- a/SVUI_!Core/system/_reports/tokens.lua
+++ b/SVUI_!Core/system/_reports/tokens.lua
@@ -38,228 +38,246 @@ local TEXT_PATTERN = "\124T%s:12\124t %s";
 local playerName = UnitName("player");
 local playerRealm = GetRealmName();

+--[[
+##########################################################
+Tables of tokens (we're interested in)
+Format: ID, Cap
+##########################################################
+]]--
+local ARCHAEOLOGY_TOKENS={
+	{ 829, 250},
+	{ 1174, 200},
+	{ 398, 200},
+	{ 821, 250},
+	{ 384, 200},
+	{ 393, 200},
+	{ 1172, 200},
+	{ 1173, 200},
+	{ 754, 200},
+	{ 677, 200},
+	{ 400, 200},
+	{ 394, 200},
+	{ 828, 250},
+	{ 397, 200},
+	{ 676, 200},
+	{ 401, 200},
+	{ 385, 200},
+	{ 399, 200}
+}
+
+local JEWELCRAFTING_TOKENS={
+	{ 61, 0},
+	{ 361, 0},
+	{ 1008, 0}
+}
+
+local COOKING_TOKENS={
+	{ 81, 0},
+	{ 402, 0}
+}
+
+local DUNGEON_TOKENS={
+	{ 1166, 0},
+	{ 1191, 5000},
+	{ 1273, 10},
+	{ 776, 20},
+	{ 1129, 20},
+	{ 994, 20},
+}
+
+local GARRISON_TOKENS={
+	{ 823, 0},
+	{ 824, 10000},
+	{ 1101, 100000}
+}
+
+local LEGION_TOKENS={
+	{ 1220, 0},
+	{ 1155, 300},
+	{ 1275, 0},
+	{ 1226, 2000},
+	{ 1154, 500},
+	{ 1149, 5000},
+	{ 1268, 1000}
+}
+
+local PVP_TOKENS={
+	{ 391, 300}
+}
+
+local MISC_TOKENS={
+	{ 777, 0 },
+	{ 416, 0 }
+}
+
 local sort_menu_fn = function(a,b) return a.text < b.text end;

 local Tokens_OnEvent = function(self, event, ...)
-if(not IsLoggedIn() or (not self)) then return end
-local id = self.TokenKey or 738;
-local _, current, tex = GetCurrencyInfo(id)
-local currentText = TEXT_PATTERN:format(tex, current);
-self.text:SetText(currentText)
+	if(not IsLoggedIn() or (not self)) then return end
+	local id = self.TokenKey or 738;
+	local _, current, tex = GetCurrencyInfo(id)
+	local currentText = TEXT_PATTERN:format(tex, current);
+	self.text:SetText(currentText)
 end

 local function AddToTokenMenu(self, id, key)
-local itemName, _, tex, _, _, _, _ = GetCurrencyInfo(id)
-local fn = function()
-Reports.Accountant["tokens"][playerName][key] = id;
-self.TokenKey = id
-Tokens_OnEvent(self)
+	local itemName, _, tex, _, _, _, _ = GetCurrencyInfo(id)
+	local fn = function()
+		Reports.Accountant["tokens"][playerName][key] = id;
+		self.TokenKey = id
+		Tokens_OnEvent(self)
+	end
+	local nextIndex = #self.InnerData+1;
+	self.InnerData[nextIndex] = {text = itemName, icon = "\124T"..tex..":12\124t ", func = fn};
 end
-local nextIndex = #self.InnerData+1;
-self.InnerData[nextIndex] = {text = itemName, icon = "\124T"..tex..":12\124t ", func = fn};
+
+local function AddTokenTableToMenu(self,ttable,key)
+	for k,v in pairs(ttable) do
+		AddToTokenMenu(self, v[1], key)
+	end
 end

 local function CacheTokenData(self)
-twipe(self.InnerData);
-local prof1, prof2, archaeology, _, cooking = GetProfessions();
-local key = self:GetName();
-if archaeology then
-AddToTokenMenu(self, 398, key)
-AddToTokenMenu(self, 384, key)
-AddToTokenMenu(self, 393, key)
-AddToTokenMenu(self, 677, key)
-AddToTokenMenu(self, 400, key)
-AddToTokenMenu(self, 394, key)
-AddToTokenMenu(self, 397, key)
-AddToTokenMenu(self, 676, key)
-AddToTokenMenu(self, 401, key)
-AddToTokenMenu(self, 385, key)
-AddToTokenMenu(self, 399, key)
-AddToTokenMenu(self, 821, key)
-AddToTokenMenu(self, 829, key)
-AddToTokenMenu(self, 944, key)
-end
-if cooking then
-AddToTokenMenu(self, 81, key)
-AddToTokenMenu(self, 402, key)
-end
-if(prof1 == 9 or prof2 == 9) then
-AddToTokenMenu(self, 61, key)
-AddToTokenMenu(self, 361, key)
-AddToTokenMenu(self, 698, key)
-
-AddToTokenMenu(self, 910, key)
-AddToTokenMenu(self, 999, key)
-AddToTokenMenu(self, 1020, key)
-AddToTokenMenu(self, 1008, key)
-AddToTokenMenu(self, 1017, key)
-end
-AddToTokenMenu(self, 1166, key)
-AddToTokenMenu(self, 1129, key)
-AddToTokenMenu(self, 994, key)
-AddToTokenMenu(self, 697, key)
-AddToTokenMenu(self, 738, key)
-AddToTokenMenu(self, 615, key)
-AddToTokenMenu(self, 614, key)
-AddToTokenMenu(self, 395, key)
-AddToTokenMenu(self, 396, key)
-AddToTokenMenu(self, 390, key)
-AddToTokenMenu(self, 392, key)
-AddToTokenMenu(self, 391, key)
-AddToTokenMenu(self, 241, key)
-AddToTokenMenu(self, 416, key)
-AddToTokenMenu(self, 515, key)
-AddToTokenMenu(self, 776, key)
-AddToTokenMenu(self, 777, key)
-AddToTokenMenu(self, 789, key)
-AddToTokenMenu(self, 823, key)
-AddToTokenMenu(self, 824, key)
-AddToTokenMenu(self, 1101, key)
-
-tsort(self.InnerData, sort_menu_fn)
-end
+	twipe(self.InnerData);
+	local prof1, prof2, archaeology, _, cooking = GetProfessions();
+	local key = self:GetName();
+	if archaeology then
+		AddTokenTableToMenu(self, ARCHAEOLOGY_TOKENS, key)
+	end
+	if cooking then
+		AddTokenTableToMenu(self, COOKING_TOKENS, key)
+	end
+	if(prof1 == 9 or prof2 == 9) then
+		AddTokenTableToMenu(self, JEWELCRAFTING_TOKENS, key)
+	end
+	AddTokenTableToMenu(self, GARRISON_TOKENS, key)
+	AddTokenTableToMenu(self, DUNGEON_TOKENS, key)
+	AddTokenTableToMenu(self, LEGION_TOKENS, key)
+	AddTokenTableToMenu(self, PVP_TOKENS, key)
+	AddTokenTableToMenu(self, MISC_TOKENS, key)

-local function TokenInquiry(id, weekly, capped)
---name, amount, texturePath, earnedThisWeek, weeklyMax, totalMax, isDiscovered = GetCurrencyInfo(id)
-local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(id)
-local r, g, b = 1, 1, 1
-for i = 1, GetNumWatchedTokens() do
-local _, _, _, itemID = GetBackpackCurrencyInfo(i)
-if id == itemID then r, g, b = 0.23, 0.88, 0.27 end
-end
-local texStr = ("\124T%s:12\124t %s"):format(tex, name)
-local altStr = ""
-if weekly then
-if discovered then
-if id == 390 then
-local pointsThisWeek, maxPointsThisWeek = GetPVPRewards();
-altStr = ("Current: %d | Weekly: %d / %d"):format(amount, pointsThisWeek, maxPointsThisWeek)
-else
-altStr = ("Current: %d / %d | Weekly: %d / %d"):format(amount, maxed, week, weekmax)
-end
-Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
-end
-elseif capped then
-if id == 392 or id == 395 then maxed = 4000 end
-if id == 396 then maxed = 3000 end
-if id == 1129 then maxed = 10 end
-if discovered then
-altStr = ("%d / %d"):format(amount, maxed)
-Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
-end
-else
-if discovered then
-Reports.ToolTip:AddDoubleLine(texStr, amount, r, g, b, r, g, b)
+
+	tsort(self.InnerData, sort_menu_fn)
 end
+
+local function TokenInquiry(id, weekly, cap)
+	--name, amount, texturePath, earnedThisWeek, weeklyMax, totalMax, isDiscovered = GetCurrencyInfo(id)
+	local name, amount, tex, week, weekmax, maxed, discovered = GetCurrencyInfo(id)
+	local max = maxed or cap -- If there's a maxed value returned, use that not our default - e.g. Ancient Mana
+	local r, g, b = 1, 1, 1
+	for i = 1, GetNumWatchedTokens() do
+		local _, _, _, itemID = GetBackpackCurrencyInfo(i)
+		if id == itemID then r, g, b = 0.23, 0.88, 0.27 end
+	end
+	local texStr = ("\124T%s:12\124t %s"):format(tex, name)
+	local altStr = ""
+	-- JV - 20160919: I think weekly caps are gone in legion...
+	-- if weekly then
+	-- 	if discovered then
+	-- 		if id == 390 then
+	-- 			local pointsThisWeek, maxPointsThisWeek = GetPVPRewards();
+	-- 			altStr = ("Current: %d | Weekly: %d / %d"):format(amount, pointsThisWeek, maxPointsThisWeek)
+	-- 		else
+	-- 			altStr = ("Current: %d / %d | Weekly: %d / %d"):format(amount, maxed, week, weekmax)
+	-- 		end
+	-- 		Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
+	-- 	end
+	-- elseif capped then
+	if max > 0 then
+		if discovered then
+			altStr = ("%d / %d"):format(amount, max)
+			Reports.ToolTip:AddDoubleLine(texStr, altStr, r, g, b, r, g, b)
+		end
+	else
+		if discovered then
+			Reports.ToolTip:AddDoubleLine(texStr, amount, r, g, b, r, g, b)
+		end
+	end
 end
+
+local function TokenInquiryTable(ttable)
+	for k,v in pairs(ttable) do
+		TokenInquiry(v[1], false, v[2])
+	end
 end
+
 --[[
 ##########################################################
 REPORT TEMPLATE
 ##########################################################
 ]]--
 local Report = Reports:NewReport(REPORT_NAME, {
-type = "data source",
-text = REPORT_NAME .. " Info",
-icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
-});
+	type = "data source",
+	text = REPORT_NAME .. " Info",
+	icon = [[Interface\Addons\SVUI_!Core\assets\icons\SVUI]]
+	});

 Report.events = {"PLAYER_ENTERING_WORLD", "PLAYER_MONEY", "CURRENCY_DISPLAY_UPDATE"};

 Report.OnEvent = Tokens_OnEvent;

 Report.OnClick = function(self, button)
-CacheTokenData(self);
-SV.Dropdown:Open(self, self.InnerData, "Select Currency", 200)
+	CacheTokenData(self);
+	SV.Dropdown:Open(self, self.InnerData, "Select Currency", 200)
 end

 Report.OnEnter = function(self)
-Reports:SetDataTip(self)
-Reports.ToolTip:AddLine(playerName .. "\'s Tokens")
-
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddLine("Common")
-TokenInquiry(241)
-TokenInquiry(416)
-TokenInquiry(515)
-TokenInquiry(776)
-TokenInquiry(777)
-TokenInquiry(789)
-
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddLine("Garrison")
-TokenInquiry(823)
-TokenInquiry(824)
-TokenInquiry(1101)
-TokenInquiry(910)
-TokenInquiry(999)
-TokenInquiry(1020)
-TokenInquiry(1008)
-TokenInquiry(1017)
-
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddLine("Raiding and Dungeons")
-TokenInquiry(1166)
-TokenInquiry(1129, false, true)
-TokenInquiry(994, false, true)
-TokenInquiry(697, false, true)
-TokenInquiry(738)
-TokenInquiry(615)
-TokenInquiry(614)
-TokenInquiry(395, false, true)
-TokenInquiry(396, false, true)
-
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddLine("PvP")
-TokenInquiry(390, true)
-TokenInquiry(392, false, true)
-TokenInquiry(391)
-
-local prof1, prof2, archaeology, _, cooking = GetProfessions()
-if(archaeology or cooking or prof1 == 9 or prof2 == 9) then
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddLine("Professions")
-end
-if cooking then
-TokenInquiry(81)
-TokenInquiry(402)
-end
-if(prof1 == 9 or prof2 == 9) then
-TokenInquiry(61)
-TokenInquiry(361)
-TokenInquiry(698)
-end
-if archaeology then
-TokenInquiry(821)
-TokenInquiry(829)
-TokenInquiry(944)
-TokenInquiry(398)
-TokenInquiry(384)
-TokenInquiry(393)
-TokenInquiry(677)
-TokenInquiry(400)
-TokenInquiry(394)
-TokenInquiry(397)
-TokenInquiry(676)
-TokenInquiry(401)
-TokenInquiry(385)
-TokenInquiry(399)
-end
-Reports.ToolTip:AddLine(" ")
-Reports.ToolTip:AddDoubleLine("[Shift + Click]", "Change Watched Token", 0,1,0, 0.5,1,0.5)
-Reports:ShowDataTip(true)
+	Reports:SetDataTip(self)
+	Reports.ToolTip:AddLine(playerName .. "\'s Tokens")
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine("Common")
+	TokenInquiryTable(MISC_TOKENS)
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine("Legion")
+	TokenInquiryTable(LEGION_TOKENS)
+
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine("Garrison")
+	TokenInquiryTable(GARRISON_TOKENS)
+
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine("Raiding and Dungeons")
+	TokenInquiryTable(DUNGEON_TOKENS)
+
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddLine("PvP")
+	TokenInquiryTable(PVP_TOKENS)
+
+
+	local prof1, prof2, archaeology, _, cooking = GetProfessions()
+	if(archaeology or cooking or prof1 == 9 or prof2 == 9) then
+		Reports.ToolTip:AddLine(" ")
+		Reports.ToolTip:AddLine("Professions")
+	end
+	if cooking then
+		TokenInquiryTable(COOKING_TOKENS)
+	end
+	if(prof1 == 9 or prof2 == 9) then
+		TokenInquiryTable(JEWELCRAFTING_TOKENS)
+	end
+	if archaeology then
+		TokenInquiryTable(ARCHAEOLOGY_TOKENS)
+	end
+	Reports.ToolTip:AddLine(" ")
+	Reports.ToolTip:AddDoubleLine("[Shift + Click]", "Change Watched Token", 0,1,0, 0.5,1,0.5)
+	Reports:ShowDataTip(true)
 end

 Report.OnInit = function(self)
-if not IsAddOnLoaded("Blizzard_PVPUI") then
-LoadAddOn("Blizzard_PVPUI")
-end
-if(not self.InnerData) then
-self.InnerData = {}
-end
-Reports:SetAccountantData('tokens', 'table', {})
-local key = self:GetName()
-Reports.Accountant["tokens"][playerName][key] = Reports.Accountant["tokens"][playerName][key] or 738;
-self.TokenKey = Reports.Accountant["tokens"][playerName][key]
-CacheTokenData(self);
+-- JV - 20160919: Bug #15 - This is causing an error. Not sure why it necessary?!
+--	if not IsAddOnLoaded("Blizzard_PVPUI") then
+--		LoadAddOn("Blizzard_PVPUI")
+--	end
+	if(not self.InnerData) then
+		self.InnerData = {}
+	end
+	Reports:SetAccountantData('tokens', 'table', {})
+	local key = self:GetName()
+	Reports.Accountant["tokens"][playerName][key] = Reports.Accountant["tokens"][playerName][key] or 738;
+	self.TokenKey = Reports.Accountant["tokens"][playerName][key]
+	CacheTokenData(self);
 end
\ No newline at end of file
diff --git a/SVUI_!Core/system/alerts.lua b/SVUI_!Core/system/alerts.lua
index faad3f7..4ba42b4 100644
--- a/SVUI_!Core/system/alerts.lua
+++ b/SVUI_!Core/system/alerts.lua
@@ -900,33 +900,31 @@ local AlertFramePostMove_Hook = function(forced)
 		SVUI_AlertFrame_MOVE:SetText(SVUI_AlertFrame_MOVE.textString.." (Grow Up)")
 	end

-	-- if(SV.RollFrames and SV.RollFrames[1]) then
-	-- 	local lastFrame = SVUI_AlertFrame;
-	-- 	local newAnchor;
-	-- 	for index, rollFrame in pairs(SV.RollFrames) do
-	-- 		rollFrame:ClearAllPoints()
-	-- 		if(POSITION == "TOP") then
-	-- 			rollFrame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -4)
-	-- 		else
-	-- 			rollFrame:SetPoint("BOTTOM", lastFrame, "TOP", 0, 4)
-	-- 		end
-	-- 		lastFrame = rollFrame;
-	-- 		if(rollFrame:IsShown()) then
-	-- 			newAnchor = rollFrame
-	-- 		end
-	-- 	end
-	-- 	AlertFrame:ClearAllPoints()
-	-- 	if(newAnchor) then
-	-- 		AlertFrame:SetAllPoints(newAnchor)
-	-- 	else
-	-- 		AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
-	-- 	end
-	-- else
-	-- 	AlertFrame:ClearAllPoints()
-	-- 	AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
-	-- end
-	AlertFrame:ClearAllPoints()
-	AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+	if(SV.RollFrames and SV.RollFrames[1]) then
+		local lastFrame = SVUI_AlertFrame;
+		local newAnchor;
+		for index, rollFrame in pairs(SV.RollFrames) do
+			rollFrame:ClearAllPoints()
+			if(POSITION == "TOP") then
+				rollFrame:SetPoint("TOP", lastFrame, "BOTTOM", 0, -4)
+			else
+				rollFrame:SetPoint("BOTTOM", lastFrame, "TOP", 0, 4)
+			end
+			lastFrame = rollFrame;
+			if(rollFrame:IsShown()) then
+				newAnchor = rollFrame
+			end
+		end
+		AlertFrame:ClearAllPoints()
+		if(newAnchor) then
+			AlertFrame:SetAllPoints(newAnchor)
+		else
+			AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+		end
+	else
+		AlertFrame:ClearAllPoints()
+		AlertFrame:SetPoint(POSITION, SVUI_AlertFrame, POSITION, 0, 0)
+	end
 end
 --[[
 ##########################################################
diff --git a/SVUI_!Core/system/core.lua b/SVUI_!Core/system/core.lua
index 00fdd41..34d09ae 100644
--- a/SVUI_!Core/system/core.lua
+++ b/SVUI_!Core/system/core.lua
@@ -156,7 +156,7 @@ if(not CUSTOM_CLASS_COLORS) then
         ["WARRIOR"]       = { r = 0.698, g = 0.36,  b = 0.152 },
         ["DEATHKNIGHT"]   = { r = 0.847, g = 0.117, b = 0.074 },
         ["MONK"]          = { r = 0.015, g = 0.886, b = 0.38 },
-        ["DEMONHUNTER"]   = { r = 0.454, g = 0.015, b = 0.894 },
+        ["DEMONHUNTER"]   = { r = 0.286, g = 0,     b = 0.788 },
     };

     ---- IF WE NEED TO FORCE DEFAULT COLORS, USE THIS INSTEAD ----
diff --git a/SVUI_!Core/system/credits.lua b/SVUI_!Core/system/credits.lua
index 1cde84b..0418488 100644
--- a/SVUI_!Core/system/credits.lua
+++ b/SVUI_!Core/system/credits.lua
@@ -20,6 +20,7 @@ local PRINTED_TEMPLATE = [[
 |cffff9900SUPERVILLAIN CREDITS:|r
 |cff4f4f4f---------------------------------------------|r
 |cffff9900CREATED BY:|r  Failcoder
+|cffff9900MAINTAINED BY:|r  joev
 |cff4f4f4f---------------------------------------------|r
 |cffff9900CODE GRANTS BY:|r  Azilroka, Sortokk, Kkthnx
 |cff4f4f4f---------------------------------------------|r
@@ -93,14 +94,14 @@ SV.Credits["investors"] = {
   "BloodEagle", "Egbert", "Jerry Ferguson", "Hyti", "Elton",
   "James Watson", "Lathron", "Adam Vargas", "Daphne", "Dave (Naméra)",
   "Soulkrusher-Shu-Halo", "Talirrine", "Gaeline", "Malinche", "StealthyMangos",
-  "Monger", "JoeyMagz",
+  "Monger", "JoeyMagz", "joev",
   "Cherep2267", "Ravensongs", "Huggiedabear", "Titatotemaar", "Mahga"
 };

 SV.Credits["contributors"] = {
   "Azilroka", "Sortokk", "Kkthnx", "Vyntrox", "Mydraal", "Profitz",
   "AlleyKat", "Quokka", "Duugu", "Zork", "Haleth", "P3lim",
-  "Haste", "Totalpackage", "Kryso", "Thepilli", "Phanx"
+  "Haste", "Totalpackage", "Kryso", "Thepilli", "Phanx", "Abu"
 };

 SV.Credits["community"] = {
@@ -109,7 +110,7 @@ SV.Credits["community"] = {
   "Xarioth", "AtomicKiller", "Meljen", "Moondoggy", "Stormblade",
   "Schreibstift", "Anj", "Risien", "Cromax", "Nitro_Turtle",
   "Shinzou", "Autolykus", "Taotao", "ColorsGaming", "Necroo", "Panser (TradeChat)",
-  "Synnistry", "MetaGoblin", "Panda Co Live!"
+  "Synnistry", "MetaGoblin", "Panda Co Live!", "klepp0906"
 };

 local LIST_PATTERN = "    %s\n        %s\n            %s\n                %s";
diff --git a/SVUI_!Core/system/dock.lua b/SVUI_!Core/system/dock.lua
index 6d26e7d..0420081 100644
--- a/SVUI_!Core/system/dock.lua
+++ b/SVUI_!Core/system/dock.lua
@@ -1498,8 +1498,14 @@ DOCKS
 MOD.TopCenter = _G["SVUI_DockTopCenter"];
 MOD.BottomCenter = _G["SVUI_DockBottomCenter"];

+local dockAlertCombatActive = false
+
 local DockAlert_OnEvent = function(self, event)
     if(event == 'PLAYER_REGEN_ENABLED') then
+    	if dockAlertCombatActive then
+    		DockAlert_Deactivate(self)
+    		dockAlertCombatActive = false
+    	end
         self:SetHeight(self.activeHeight)
         self:UnregisterEvent(event)
     end
@@ -1515,6 +1521,11 @@ local DockAlert_Activate = function(self, child, newHeight)
 end

 local DockAlert_Deactivate = function(self)
+	if InCombatLockdown() then
+		-- Make sure we deactivate later
+		dockAlertCombatActive = true
+		return
+	end
 	self:SetHeight(1)
 end

@@ -2103,7 +2114,7 @@ function MOD:Load()
 		dock.Alert:ClearAllPoints()
 		dock.Alert:SetSize(width, 1)
 		dock.Alert:SetPoint(anchor, dock, anchor, 0, 0)
-		dock.Alert:SetParent(UIParent)
+		--dock.Alert:SetParent(UIParent)

 		dock.Window:ClearAllPoints()
 		dock.Window:SetSize(width, height)
@@ -2114,7 +2125,7 @@ function MOD:Load()
 		SV:NewAnchor(dock, location .. " Dock Window");
 		SV:SetAnchorResizing(dock, dockPostSizeFunc, 10, 500);

-		dock.Alert:SetParent(UIParent)
+		--dock.Alert:SetParent(UIParent)
 	end

 	if MOD.private.LeftFaded then MOD.BottomLeft:Hide() end
diff --git a/SVUI_!Core/system/gear.lua b/SVUI_!Core/system/gear.lua
index 20e9e25..5825a70 100644
--- a/SVUI_!Core/system/gear.lua
+++ b/SVUI_!Core/system/gear.lua
@@ -26,6 +26,8 @@ GET ADDON DATA
 ]]--
 local SV = select(2, ...)
 local L = SV.L
+
+local LIUI = LibStub("LibItemUpgradeInfo-1.0");
 --[[
 ##########################################################
 LOCAL VARS
@@ -171,41 +173,43 @@ do
     end

     function ParseItemLevel(unit, itemLink)
-        local name, link, quality;
-        local iLevel = 0;
-        if(itemLink and type(itemLink) == "string") then
-          name, link, quality, iLevel = GetItemInfo(itemLink)
-          local itemId = tonumber(itemLink:match("item:%d+:%d+:%d+:%d+:%d+:%d+:%-?%d+:%-?%d+:%d+:%d+:(%d+)"))
-          if iLevel and itemId then
-              if(quality == 7) then
-                  iLevel = _getHeirloomLevel(unit, itemId)
-              end
-          end
-        end
-        return iLevel or 0
+        -- local name, link, quality;
+        -- local iLevel = 0;
+        -- if(itemLink and type(itemLink) == "string") then
+        --   name, link, quality, iLevel = GetItemInfo(itemLink)
+        --   local itemId = tonumber(itemLink:match("item:%d+:%d+:%d+:%d+:%d+:%d+:%-?%d+:%-?%d+:%d+:%d+:(%d+)"))
+        --   if iLevel and itemId then
+        --       if(quality == 7) then
+        --           iLevel = _getHeirloomLevel(unit, itemId)
+        --       end
+        --   end
+        -- end
+        -- return iLevel or 0
+        return LIUI:GetUpgradedItemLevel(itemLink) or 0
     end

     local function _getEquippedItemLevel(unit, itemLink)
-        local tooltip = _justthetip();
-        if(not tooltip) then return ParseItemLevel(unit, itemLink) end
-        tooltip:SetOwner(UIParent, "ANCHOR_NONE");
-        tooltip:SetHyperlink(itemLink);
-        tooltip:Show();
-
-        local iLevel = 0;
-        local tname = tooltip:GetName().."TextLeft%s";
-        for i = 2, tooltip:NumLines() do
-            local text = _G[tname:format(i)]:GetText();
-            if(text and text ~= "") then
-                local value = tonumber(text:match(iLevelFilter));
-                if(value) then
-                    iLevel = value;
-                end
-            end
-        end
-
-        tooltip:Hide();
-        return iLevel
+        -- local tooltip = _justthetip();
+        -- if(not tooltip) then return ParseItemLevel(unit, itemLink) end
+        -- tooltip:SetOwner(UIParent, "ANCHOR_NONE");
+        -- tooltip:SetHyperlink(itemLink);
+        -- tooltip:Show();
+
+        -- local iLevel = 0;
+        -- local tname = tooltip:GetName().."TextLeft%s";
+        -- for i = 2, tooltip:NumLines() do
+        --     local text = _G[tname:format(i)]:GetText();
+        --     if(text and text ~= "") then
+        --         local value = tonumber(text:match(iLevelFilter));
+        --         if(value) then
+        --             iLevel = value;
+        --         end
+        --     end
+        -- end
+
+        -- tooltip:Hide();
+        -- return iLevel
+        return LIUI:GetUpgradedItemLevel(itemLink) or 0
     end

     local function _setLevelDisplay(frame, iLevel)
@@ -317,17 +321,17 @@ end

 local function GetActiveGear()
 	local count = GetNumEquipmentSets()
-	local resultSpec = GetActiveSpecGroup()
+	local resultSpec = GetSpecialization()
+  local _, sname = GetSpecializationInfo(resultSpec)
 	local resultSet
-  BG_SET = "none"
+
+  BG_SET = SV.db.Gear.battleground.equipmentset
 	SPEC_SET = "none"
-	if(resultSpec and GetSpecializationInfo(resultSpec) and (resultSpec ~= 1)) then
-    SPEC_SET = SV.db.Gear.specialization.secondary
-    BG_SET = SV.db.Gear.battleground.secondary
-  else
-    SPEC_SET = SV.db.Gear.specialization.primary
-    BG_SET = SV.db.Gear.battleground.primary
+
+	if(sname) then
+    SPEC_SET = SV.db.Gear.specialization[sname] or SPEC_SET
 	end
+
 	if(count == 0) then
 		return resultSpec,false
 	end
@@ -502,18 +506,20 @@ local function InitializeGearInfo()
 	ONLY_DAMAGED = SV.db.Gear.durability.onlydamaged
 	MAX_LEVEL, AVG_LEVEL = GetAverageItemLevel()

+
+  LoadAddOn("Blizzard_InspectUI")
+  SetDisplayStats("Character")
+  SetDisplayStats("Inspect")
+
   GearHandler:RegisterEvent("PLAYER_ENTERING_WORLD")
 	GearHandler:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
 	GearHandler:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
 	GearHandler:RegisterEvent("SOCKET_INFO_UPDATE")
 	GearHandler:RegisterEvent("COMBAT_RATING_UPDATE")
 	GearHandler:RegisterEvent("MASTERY_UPDATE")
-	GearHandler:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
+  GearHandler:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
 	GearHandler:SetScript("OnEvent", GearHandler_OnEvent)

-	LoadAddOn("Blizzard_InspectUI")
-	SetDisplayStats("Character")
-	SetDisplayStats("Inspect")
 	NewHook('InspectFrame_UpdateTabs', Gear_UpdateTabs)
 	SV.Timers:ExecuteTimer(SV.UpdateGearInfo, 10)
 	SV:GearSwap()
diff --git a/SVUI_!Core/system/layout.lua b/SVUI_!Core/system/layout.lua
index 54e9ec7..f52943b 100644
--- a/SVUI_!Core/system/layout.lua
+++ b/SVUI_!Core/system/layout.lua
@@ -64,6 +64,7 @@ local UIPanels = {};
 UIPanels["AchievementFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["AuctionFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["ArchaeologyFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["ArtifactFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["BattlefieldMinimap"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
 UIPanels["BarberShopFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["BlackMarketFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
@@ -95,6 +96,7 @@ UIPanels["MacroFrame"] 						= { moving = false, snapped = false, canupdate = fa
 UIPanels["MailFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["MerchantFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["ObjectiveTrackerFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+UIPanels["OrderHallMissionFrame"] 			= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["PlayerTalentFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["PetJournalParent"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["PetStableFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
@@ -110,6 +112,7 @@ UIPanels["ReportPlayerNameDialog"] 			= { moving = false, snapped = false, canup
 UIPanels["RolePollPopup"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = true };
 UIPanels["SpellBookFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["TabardFrame"] 					= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
+--UIPanels["TalkingHeadFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["TaxiFrame"] 						= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["TimeManagerFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
 UIPanels["TradeSkillFrame"] 				= { moving = false, snapped = false, canupdate = false, cansetpoint = false, centered = false };
@@ -1002,7 +1005,7 @@ local Dragger = CreateFrame("Frame", nil);
 Dragger.Frames = {};

 local function SetDraggablePoint(frame, data)
-	if((not frame) or (not data)) then return; end
+	if(InCombatLockdown() or (not frame) or (not data)) then return; end
 	local frameName = frame:GetName()
 	local point = Dragger.Frames[frameName];
 	if(point and (type(point) == "string") and (point ~= 'TBD')) then
@@ -1169,6 +1172,7 @@ local DraggerEventHandler = function(self, event, ...)
 		self:UnregisterEvent("UPDATE_WORLD_STATES")
 		self:UnregisterEvent("WORLD_STATE_TIMER_START")
 		self:UnregisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+		self:UnregisterEvent("TALKINGHEAD_REQUESTED");
 		self:SetScript("OnEvent", nil)
 	end
 end
@@ -1186,6 +1190,7 @@ function Dragger:New(frameName)
 			self:RegisterEvent("UPDATE_WORLD_STATES")
 			self:RegisterEvent("WORLD_STATE_TIMER_START")
 			self:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+			self:RegisterEvent("TALKINGHEAD_REQUESTED");
 			self:SetScript("OnEvent", DraggerEventHandler)
 			self.EventsActive = true;
 		end
@@ -1227,6 +1232,7 @@ function Dragger:Reset()
 		self:RegisterEvent("UPDATE_WORLD_STATES")
 		self:RegisterEvent("WORLD_STATE_TIMER_START")
 		self:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
+		self:RegisterEvent("TALKINGHEAD_REQUESTED");
 		self:SetScript("OnEvent", DraggerEventHandler)
 		self.EventsActive = true;
 	end
@@ -1379,7 +1385,7 @@ local function InitializeMovables()
 		Dragger:RegisterEvent("UPDATE_WORLD_STATES")
 		Dragger:RegisterEvent("WORLD_STATE_TIMER_START")
 		Dragger:RegisterEvent("WORLD_STATE_UI_TIMER_UPDATE")
-
+		Dragger:RegisterEvent("TALKINGHEAD_REQUESTED");
 		DraggerEventHandler(Dragger)
 		Dragger:SetScript("OnEvent", DraggerEventHandler)

diff --git a/SVUI_!Core/system/media.lua b/SVUI_!Core/system/media.lua
index d7de399..b54f56d 100644
--- a/SVUI_!Core/system/media.lua
+++ b/SVUI_!Core/system/media.lua
@@ -313,6 +313,7 @@ do
 			["durabilityLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-DUR]],
 			["reputationLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-REP]],
 			["experienceLabel"] 	= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-XP]],
+			["artifactLabel"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\LABEL-ART]],
 			["sizeIcon"] 			= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-SIZE]],
 			["optionsIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-OPTIONS]],
 			["breakStuffIcon"] 		= [[Interface\AddOns\SVUI_!Core\assets\textures\Dock\DOCK-ICON-BREAKSTUFF]],
diff --git a/SVUI_!Core/system/overrides.lua b/SVUI_!Core/system/overrides.lua
index 964a71b..9f708aa 100644
--- a/SVUI_!Core/system/overrides.lua
+++ b/SVUI_!Core/system/overrides.lua
@@ -676,7 +676,7 @@ EventFunc["START_LOOT_ROLL"] = function(rollID, rollTime)
 	rollFrame.status:SetValue(rollTime)
 	rollFrame:SetPoint("CENTER",WorldFrame,"CENTER")
 	rollFrame:Show()
-	AlertFrame_FixAnchors()
+	-- Gone in Legion. AlertFrame_FixAnchors()
 	AutoGreed(rollID, quality, canBreak, bindOnPickUp)
 end
 EventFunc["LOOT_READY"] = function(autoLoot)
@@ -802,6 +802,8 @@ local BailOut_TaxiTimer, BailOut_EarlyLandingRequested;
 local SVUI_BailOut = CreateFrame("Button", "SVUI_BailOut", UIParent)
 SVUI_BailOut:SetSize(50, 50)
 SVUI_BailOut:SetPoint("TOP", SVUI_DockTopCenter, "BOTTOM", 0, -10)
+-- JV - 20160923: This is showing sometimes when it shouldn't so make sure it's hidden by default
+SVUI_BailOut:Hide()

 local function UpdateTaxiBailOut()
 	if(not UnitOnTaxi("player")) then
@@ -1021,7 +1023,7 @@ local function SetOverrides()
 	HelpOpenTicketButton:SetPoint("TOPRIGHT", Minimap, "TOPRIGHT")

 	NewHook(VehicleSeatIndicator, "SetPoint", Vehicle_OnSetPoint)
-	VehicleSeatIndicator:SetPoint("TOPLEFT", MinimapCluster, "TOPLEFT", 2, 2)
+	-- May be taining MinimapCluster -- VehicleSeatIndicator:SetPoint("TOPLEFT", MinimapCluster, "TOPLEFT", 2, 2)

 	SVUI_WorldStateHolder:SetSize(200, 45)
 	SV:NewAnchor(SVUI_WorldStateHolder, L["Capture Bars"])
@@ -1042,6 +1044,7 @@ local function SetOverrides()
 		local size = SVUI_Player:GetHeight()
 		SVUI_BailOut:SetSize(size, size)
 		SVUI_BailOut:SetPoint("TOPLEFT", SVUI_Player, "TOPRIGHT", 4, 0)
+		SVUI_BailOut:Hide()
 	end
 	SVUI_BailOut:SetNormalTexture(SV.media.icon.exitIcon)
 	SVUI_BailOut:SetPushedTexture(SV.media.icon.exitIcon)
@@ -1052,7 +1055,7 @@ local function SetOverrides()
 	SVUI_BailOut:RegisterEvent("UNIT_ENTERED_VEHICLE")
  	SVUI_BailOut:RegisterEvent("UNIT_EXITED_VEHICLE")
  	SVUI_BailOut:RegisterEvent("VEHICLE_UPDATE")
- 	SVUI_BailOut:RegisterEvent("PLAYER_ENTERING_WORLD")
+ 	--SVUI_BailOut:RegisterEvent("PLAYER_ENTERING_WORLD")
  	SVUI_BailOut:SetScript("OnEvent", BailOut_OnEvent)
  	NewHook("TakeTaxiNode", BailOut_OnHook)
 	SV:NewAnchor(SVUI_BailOut, L["Bail Out"])
@@ -1123,4 +1126,4 @@ local function SetOverrides()
 	AlterBlizzMainBar()
 end

-SV:NewScript(SetOverrides)
\ No newline at end of file
+SV:NewScript(SetOverrides)
diff --git a/SVUI_!Options/License.txt b/SVUI_!Options/License.txt
index 69d4d04..18ddca3 100644
--- a/SVUI_!Options/License.txt
+++ b/SVUI_!Options/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_!Options/SVUI_!Options.lua b/SVUI_!Options/SVUI_!Options.lua
index e843b6f..7c98595 100644
--- a/SVUI_!Options/SVUI_!Options.lua
+++ b/SVUI_!Options/SVUI_!Options.lua
@@ -61,6 +61,15 @@ AceConfigDialog:SetDefaultSize(SV.NameID, GUIWidth, 651);

 SVUIOptions.FilterOptionGroups = {};
 SVUIOptions.FilterOptionSpells = {};
+
+--Debug
+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("SVUIOptions")
+else
+	Debug = function() end
+end
+
 --[[
 ##########################################################
 INIT OPTIONS
@@ -1051,6 +1060,37 @@ local function GetGearSetList()
 	return t
 end

+local function GetGearSpecs()
+	local argt = {
+		enable = {
+			type = "toggle",
+			order = 1,
+			name = L["Enable"],
+			desc = L["Enable/Disable auto swapping gear sets when switching specializations."],
+			get = function(key) return SV.db.Gear.specialization.enable end,
+			set = function(key, value) SV.db.Gear.specialization.enable = value; SV:UpdateGearInfo() end
+		},
+	}
+	local numSpecs = GetNumSpecializations()
+
+	if numSpecs then
+		for i=1,numSpecs do
+			local _, sname = GetSpecializationInfo(i)
+			argt[sname] = {
+				type = "select",
+				order = i+1,
+				name = sname,
+				desc = L["Choose the equipment set to use for your "]..sname..L[" specialization."],
+				disabled = function() return not SV.db.Gear.specialization.enable end,
+				values = GetGearSetList(),
+				get = function(e) return SV.db.Gear.specialization[sname] end,
+				set = function(e,value) SV.db.Gear.specialization[sname] = value; SV:UpdateGearInfo() end
+			}
+		end
+	end
+	return argt
+end
+
 SV.Options.args.Core.args.Gear = {
 	order = 3,
 	type = 'group',
@@ -1076,36 +1116,7 @@ SV.Options.args.Core.args.Gear = {
 			name = L["Specialization"],
 			guiInline = true,
 			disabled = function() return GetNumEquipmentSets() == 0 end,
-			args = {
-				enable = {
-					type = "toggle",
-					order = 1,
-					name = L["Enable"],
-					desc = L["Enable/Disable auto swapping gear sets when switching specializations."],
-					get = function(key) return SV.db.Gear.specialization.enable end,
-					set = function(key, value) SV.db.Gear.specialization.enable = value; SV:UpdateGearInfo() end
-				},
-				primary = {
-					type = "select",
-					order = 2,
-					name = L["Primary Gear Set"],
-					desc = L["Choose the equipment set to use for your primary specialization."],
-					disabled = function() return not SV.db.Gear.specialization.enable end,
-					values = GetGearSetList(),
-					get = function(e) return SV.db.Gear.specialization.primary end,
-					set = function(e,value) SV.db.Gear.specialization.primary = value; SV:UpdateGearInfo() end
-				},
-				secondary = {
-					type = "select",
-					order = 3,
-					name = L["Secondary Gear Set"],
-					desc = L["Choose the equipment set to use for your secondary specialization."],
-					disabled = function() return not SV.db.Gear.specialization.enable end,
-					values = GetGearSetList(),
-					get = function(e) return SV.db.Gear.specialization.secondary end,
-					set = function(e,value) SV.db.Gear.specialization.secondary = value; SV:UpdateGearInfo() end
-				}
-			}
+			args = GetGearSpecs();
 		},
 		battleground = {
 			order = 3,
diff --git a/SVUI_!Options/UnitFrames.lua b/SVUI_!Options/UnitFrames.lua
index b6d24cb..872320f 100644
--- a/SVUI_!Options/UnitFrames.lua
+++ b/SVUI_!Options/UnitFrames.lua
@@ -648,6 +648,19 @@ function SVUIOptions:SetHealthConfigGroup(partyRaid, updateFunction, unitName, c
 						func = function() ACD:SelectGroup(SV.NameID, "UnitFrames", "commonGroup", "baseGroup", "allColorsGroup", "healthGroup") end
 					},
 				}
+			},
+			extra = {
+				order = 4,
+				type = "group",
+				guiInline = true,
+				name = "Extras",
+				args = {
+					absorbsBar = {
+						type = "toggle",
+						name = "Absorbs Bar",
+						desc = "Show an absorb bar anchored to health bar. \n It allows to see the current health effective (current health + current absorbs).",
+					}
+				}
 			}
 		}
 	}
@@ -2495,16 +2508,17 @@ SV.Options.args[Schema] = {
 									desc = L["Use handy graphics to focus the current target, or clear the current focus"],
 									type = "toggle"
 								},
-								resolveBar = {
-									order = 6,
-									name = L["Resolve Meter"],
-									desc = L["A convenient meter for tanks to display their current resolve."],
-									type = "toggle",
-									set = function(key, value)
-										MOD:ChangeDBVar(value, "resolveBar");
-										SV:StaticPopup_Show("RL_CLIENT")
-									end
-								},
+								-- JV - 20160919 : Resolve mechanic is now gone as of Legion.
+								-- resolveBar = {
+								-- 	order = 6,
+								-- 	name = L["Resolve Meter"],
+								-- 	desc = L["A convenient meter for tanks to display their current resolve."],
+								-- 	type = "toggle",
+								-- 	set = function(key, value)
+								-- 		MOD:ChangeDBVar(value, "resolveBar");
+								-- 		SV:StaticPopup_Show("RL_CLIENT")
+								-- 	end
+								-- },
 								infoBackgrounds = {
 									order = 7,
 									name = L["Info Backgrounds"],
diff --git a/SVUI_ActionBars/LICENSE.txt b/SVUI_ActionBars/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_ActionBars/LICENSE.txt
+++ b/SVUI_ActionBars/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_ActionBars/Loader.lua b/SVUI_ActionBars/Loader.lua
index 3559f45..9038043 100644
--- a/SVUI_ActionBars/Loader.lua
+++ b/SVUI_ActionBars/Loader.lua
@@ -93,7 +93,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "[bonusbar:1] 7; [bonusbar:2] 8;",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "[bonusbar:1] 7; [bonusbar:2] 8; [bonusbar:3] 9;",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -122,7 +122,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -151,7 +151,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -180,7 +180,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -209,7 +209,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -238,7 +238,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -267,7 +267,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -296,7 +296,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -354,7 +354,7 @@ SV.defaults[Schema] = {
 		    ["WARRIOR"] 	 = "",
 		    ["DEATHKNIGHT"]  = "",
 		    ["MONK"]    	 = "",
-		    ["DEMONHUNTER"]  = "",
+		    ["DEMONHUNTER"]  = "",
 		},
 		["alpha"] = 1
 	},
@@ -1187,4 +1187,4 @@ function MOD:LoadOptions()
 			}
 		}
 	end
-end
\ No newline at end of file
+end
diff --git a/SVUI_ActionBars/components/micro.lua b/SVUI_ActionBars/components/micro.lua
index 0aea9dc..7b7f4f9 100644
--- a/SVUI_ActionBars/components/micro.lua
+++ b/SVUI_ActionBars/components/micro.lua
@@ -74,7 +74,8 @@ local SVUIMicroButton_SetNormal = function()
 	MainMenuMicroButton.overlay:SetFrameLevel(level + 1)
 	MainMenuMicroButton.overlay:SetFrameStrata("HIGH")
 	MainMenuBarPerformanceBar:Hide()
-	HelpMicroButton:Show()
+	MainMenuBarDownload:Hide()
+	--HelpMicroButton:Show()
 end

 local SVUIMicroButtonsParent = function(self)
@@ -136,25 +137,25 @@ function MOD:InitializeMicroBar()
 	microBar:SetPoint('BOTTOMLEFT', SV.Dock.TopLeft.Bar.ToolBar, 'BOTTOMRIGHT', 4, 0)
 	SV:ManageVisibility(microBar)

-	for i=1,13 do
+	for i=1,16 do
 		local data = MOD.media.microMenuCoords[i]
 		if(data) then
 			local button = _G[data[1]]
 			if(button) then
 				button:SetParent(SVUI_MicroBar)
 				button:SetSize(buttonSize, buttonSize + 28)
-				button.Flash:SetTexture("")
+				button.Flash:SetTexture(nil)
 				if button.SetPushedTexture then
-					button:SetPushedTexture("")
+					button:SetPushedTexture(nil)
 				end
 				if button.SetNormalTexture then
-					button:SetNormalTexture("")
+					button:SetNormalTexture(nil)
 				end
 				if button.SetDisabledTexture then
-					button:SetDisabledTexture("")
+					button:SetDisabledTexture(nil)
 				end
 				if button.SetHighlightTexture then
-					button:SetHighlightTexture("")
+					button:SetHighlightTexture(nil)
 				end
 				button:RemoveTextures()

@@ -180,12 +181,17 @@ function MOD:InitializeMicroBar()
 	MicroButtonPortrait:ClearAllPoints()
 	MicroButtonPortrait:Hide()
 	MainMenuBarPerformanceBar:ClearAllPoints()
+	MainMenuBarDownload:ClearAllPoints()
 	MainMenuBarPerformanceBar:Hide()
+	MainMenuBarDownload:Hide()
+

 	NewHook('MainMenuMicroButton_SetNormal', SVUIMicroButton_SetNormal)
+	MainMenuMicroButton:SetScript("OnUpdate",nil) -- Fix for problems with texture behind. Besides, No interest in the perf bar stuff as we already have the performance meters in SVUI
 	NewHook('UpdateMicroButtonsParent', SVUIMicroButtonsParent)
 	NewHook('MoveMicroButtons', RefreshMicrobar)
 	NewHook('UpdateMicroButtons', MOD.UpdateMicroButtons)
+	NewHook('GuildMicroButton_UpdateTabard', MOD.UpdateMicroButtons)

 	SVUIMicroButtonsParent(microBar)
 	SVUIMicroButton_SetNormal()
@@ -194,4 +200,4 @@ function MOD:InitializeMicroBar()

 	RefreshMicrobar()
 	SVUI_MicroBar:SetAlpha(0)
-end
\ No newline at end of file
+end
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.lua
new file mode 100644
index 0000000..2a64013
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -0,0 +1,238 @@
+--[[ $Id: CallbackHandler-1.0.lua 18 2014-10-16 02:52:20Z mikk $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 6
+local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not CallbackHandler then return end -- No upgrade needed
+
+local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
+
+-- Lua APIs
+local tconcat = table.concat
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local next, select, pairs, type, tostring = next, select, pairs, type, tostring
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler
+
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+	local next, xpcall, eh = ...
+
+	local method, ARGS
+	local function call() method(ARGS) end
+
+	local function dispatch(handlers, ...)
+		local index
+		index, method = next(handlers)
+		if not method then return end
+		local OLD_ARGS = ARGS
+		ARGS = ...
+		repeat
+			xpcall(call, eh)
+			index, method = next(handlers, index)
+		until not method
+		ARGS = OLD_ARGS
+	end
+
+	return dispatch
+	]]
+
+	local ARGS, OLD_ARGS = {}, {}
+	for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
+	code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+
+--------------------------------------------------------------------------
+-- CallbackHandler:New
+--
+--   target            - target object to embed public APIs in
+--   RegisterName      - name of the callback registration API, default "RegisterCallback"
+--   UnregisterName    - name of the callback unregistration API, default "UnregisterCallback"
+--   UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
+
+function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName)
+
+	RegisterName = RegisterName or "RegisterCallback"
+	UnregisterName = UnregisterName or "UnregisterCallback"
+	if UnregisterAllName==nil then	-- false is used to indicate "don't want this method"
+		UnregisterAllName = "UnregisterAllCallbacks"
+	end
+
+	-- we declare all objects and exported APIs inside this closure to quickly gain access
+	-- to e.g. function names, the "target" parameter, etc
+
+
+	-- Create the registry object
+	local events = setmetatable({}, meta)
+	local registry = { recurse=0, events=events }
+
+	-- registry:Fire() - fires the given event/message into the registry
+	function registry:Fire(eventname, ...)
+		if not rawget(events, eventname) or not next(events[eventname]) then return end
+		local oldrecurse = registry.recurse
+		registry.recurse = oldrecurse + 1
+
+		Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
+
+		registry.recurse = oldrecurse
+
+		if registry.insertQueue and oldrecurse==0 then
+			-- Something in one of our callbacks wanted to register more callbacks; they got queued
+			for eventname,callbacks in pairs(registry.insertQueue) do
+				local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+				for self,func in pairs(callbacks) do
+					events[eventname][self] = func
+					-- fire OnUsed callback?
+					if first and registry.OnUsed then
+						registry.OnUsed(registry, target, eventname)
+						first = nil
+					end
+				end
+			end
+			registry.insertQueue = nil
+		end
+	end
+
+	-- Registration of a callback, handles:
+	--   self["method"], leads to self["method"](self, ...)
+	--   self with function ref, leads to functionref(...)
+	--   "addonId" (instead of self) with function ref, leads to functionref(...)
+	-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
+	target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
+		if type(eventname) ~= "string" then
+			error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
+		end
+
+		method = method or eventname
+
+		local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+
+		if type(method) ~= "string" and type(method) ~= "function" then
+			error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
+		end
+
+		local regfunc
+
+		if type(method) == "string" then
+			-- self["method"] calling style
+			if type(self) ~= "table" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
+			elseif self==target then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
+			elseif type(self[method]) ~= "function" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) self[method](self,arg,...) end
+			else
+				regfunc = function(...) self[method](self,...) end
+			end
+		else
+			-- function ref with self=object or self="addonId" or self=thread
+			if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
+				error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) method(arg,...) end
+			else
+				regfunc = method
+			end
+		end
+
+
+		if events[eventname][self] or registry.recurse<1 then
+		-- if registry.recurse<1 then
+			-- we're overwriting an existing entry, or not currently recursing. just set it.
+			events[eventname][self] = regfunc
+			-- fire OnUsed callback?
+			if registry.OnUsed and first then
+				registry.OnUsed(registry, target, eventname)
+			end
+		else
+			-- we're currently processing a callback in this registry, so delay the registration of this new entry!
+			-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
+			registry.insertQueue = registry.insertQueue or setmetatable({},meta)
+			registry.insertQueue[eventname][self] = regfunc
+		end
+	end
+
+	-- Unregister a callback
+	target[UnregisterName] = function(self, eventname)
+		if not self or self==target then
+			error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
+		end
+		if type(eventname) ~= "string" then
+			error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
+		end
+		if rawget(events, eventname) and events[eventname][self] then
+			events[eventname][self] = nil
+			-- Fire OnUnused callback?
+			if registry.OnUnused and not next(events[eventname]) then
+				registry.OnUnused(registry, target, eventname)
+			end
+		end
+		if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
+			registry.insertQueue[eventname][self] = nil
+		end
+	end
+
+	-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
+	if UnregisterAllName then
+		target[UnregisterAllName] = function(...)
+			if select("#",...)<1 then
+				error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
+			end
+			if select("#",...)==1 and ...==target then
+				error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
+			end
+
+
+			for i=1,select("#",...) do
+				local self = select(i,...)
+				if registry.insertQueue then
+					for eventname, callbacks in pairs(registry.insertQueue) do
+						if callbacks[self] then
+							callbacks[self] = nil
+						end
+					end
+				end
+				for eventname, callbacks in pairs(events) do
+					if callbacks[self] then
+						callbacks[self] = nil
+						-- Fire OnUnused callback?
+						if registry.OnUnused and not next(callbacks) then
+							registry.OnUnused(registry, target, eventname)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	return registry
+end
+
+
+-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
+-- try to upgrade old implicit embeds since the system is selfcontained and
+-- relies on closures to work.
+
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.xml b/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.xml
new file mode 100644
index 0000000..876df83
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/CallbackHandler-1.0/CallbackHandler-1.0.xml
@@ -0,0 +1,4 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+	<Script file="CallbackHandler-1.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.27.txt b/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.27.txt
new file mode 100644
index 0000000..59094a0
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.27.txt
@@ -0,0 +1,17 @@
+tag 0.27
+e9f4cff39c93f597bcf285af8990cc6c634ba3c1
+Hendrik Leppkes <h.leppkes@gmail.com>
+2015-06-23 15:47:08 +0200
+
+Tag as 0.27
+
+
+--------------------
+
+Hendrik Leppkes:
+	- The year is 2015
+	- Update TOC for 6.2
+	- Remove unused function
+	- Fix leaked global
+	- Update charge cooldown handling for 6.2
+	- Remove obsolete overlay glow variables
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.28.2.txt b/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.28.2.txt
new file mode 100644
index 0000000..7a2f895
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/Changelog-LibActionButton-1.0-0.28.2.txt
@@ -0,0 +1,20 @@
+tag 0.28.2
+7e643e264a0ebbe276693496e0ab548e619f3b41
+Hendrik Leppkes <h.leppkes@gmail.com>
+2016-07-18 21:38:14 +0200
+
+Tag as 0.28.2
+
+
+--------------------
+
+Hendrik Leppkes:
+	- Update TOC to 7.0
+	- Update for Cooldown changes in 7.0.3.21796
+	- Remove redundant charge position set
+	This is already done when an overlay is retrieved from the storage
+	- Support skinning the charge cooldown frame with Masque
+	- Treat spells with one maximum charge like spells without charges
+	These spells usually get a second charge through a talent or glyph,
+	in which case they will be handled as spells with charges again when
+	this talent/glyph is chosen.
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
index 6a1d6eb..5f96414 100644
--- a/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.lua
@@ -1,18 +1,18 @@
 --[[
-Copyright (c) 2010-2014, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
+Copyright (c) 2010-2015, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>

 All rights reserved.

-Redistribution and use in source and binary forms, with or without
+Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

-    * Redistributions of source code must retain the above copyright notice,
+    * Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
-    * Neither the name of the developer nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
+    * Neither the name of the developer nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
       specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -29,12 +29,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ]]
 local MAJOR_VERSION = "LibActionButton-1.0"
-local MINOR_VERSION = 57
+local MINOR_VERSION = 66

 if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
 local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
 if not lib then return end

+local IsLegion = select(4, GetBuildInfo()) >= 70000
+
 -- Lua functions
 local _G = _G
 local type, error, tostring, tonumber, assert, select = type, error, tostring, tonumber, assert, select
@@ -47,7 +49,7 @@ local str_match, format, tinsert, tremove = string.match, format, tinsert, tremo
 -- GLOBALS: LibStub, CreateFrame, InCombatLockdown, ClearCursor, GetCursorInfo, GameTooltip, GameTooltip_SetDefaultAnchor
 -- GLOBALS: GetBindingKey, GetBindingText, SetBinding, SetBindingClick, GetCVar, GetMacroInfo
 -- GLOBALS: PickupAction, PickupItem, PickupMacro, PickupPetAction, PickupSpell, PickupCompanion, PickupEquipmentSet
--- GLOBALS: CooldownFrame_Set, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
+-- GLOBALS: CooldownFrame_SetTimer, UIParent, IsSpellOverlayed, SpellFlyout, GetMouseFocus, SetClampedTextureRotation
 -- GLOBALS: GetActionInfo, GetActionTexture, HasAction, GetActionText, GetActionCount, GetActionCooldown, IsAttackAction
 -- GLOBALS: IsAutoRepeatAction, IsEquippedAction, IsCurrentAction, IsConsumableAction, IsUsableAction, IsStackableAction, IsActionInRange
 -- GLOBALS: GetSpellLink, GetMacroSpell, GetSpellTexture, GetSpellCount, GetSpellCooldown, IsAttackSpell, IsCurrentSpell
@@ -55,9 +57,12 @@ local str_match, format, tinsert, tremove = string.match, format, tinsert, tremo
 -- GLOBALS: GetItemIcon, GetItemCount, GetItemCooldown, IsEquippedItem, IsCurrentItem, IsUsableItem, IsConsumableItem, IsItemInRange
 -- GLOBALS: GetActionCharges, IsItemAction, GetSpellCharges
 -- GLOBALS: RANGE_INDICATOR, ATTACK_BUTTON_FLASH_TIME, TOOLTIP_UPDATE_TIME
+-- GLOBALS: DraenorZoneAbilityFrame, HasDraenorZoneAbility, GetLastDraenorSpellTexture

 local KeyBound = LibStub("LibKeyBound-1.0", true)
 local CBH = LibStub("CallbackHandler-1.0")
+local LBG = LibStub("LibButtonGlow-1.0", true)
+local Masque = LibStub("Masque", true)

 lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
 lib.eventFrame:UnregisterAllEvents()
@@ -70,9 +75,6 @@ lib.nonActionButtons = lib.nonActionButtons or {}
 lib.ChargeCooldowns = lib.ChargeCooldowns or {}
 lib.NumChargeCooldowns = lib.NumChargeCooldowns or 0

-lib.unusedOverlayGlows = lib.unusedOverlayGlows or {}
-lib.numOverlays = lib.numOverlays or 0
-
 lib.ACTION_HIGHLIGHT_MARKS = lib.ACTION_HIGHLIGHT_MARKS or setmetatable({}, { __index = ACTION_HIGHLIGHT_MARKS })

 lib.callbacks = lib.callbacks or CBH:New(lib)
@@ -113,8 +115,8 @@ local ButtonRegistry, ActiveButtons, ActionButtons, NonActionButtons = lib.butto
 local Update, UpdateButtonState, UpdateUsable, UpdateCount, UpdateCooldown, UpdateTooltip, UpdateNewAction
 local StartFlash, StopFlash, UpdateFlash, UpdateHotkeys, UpdateRangeTimer, UpdateOverlayGlow
 local UpdateFlyout, ShowGrid, HideGrid, UpdateGrid, SetupSecureSnippets, WrapOnClick
-local ShowOverlayGlow, HideOverlayGlow, GetOverlayGlow, OverlayGlowAnimOutFinished
-local HookCooldown
+local ShowOverlayGlow, HideOverlayGlow
+local EndChargeCooldown

 local InitializeEventHandler, OnEvent, ForAllButtons, OnUpdate

@@ -184,9 +186,6 @@ function lib:CreateButton(id, name, header, config)
 	-- adjust count/stack size
 	button.Count:SetFont(button.Count:GetFont(), 16, "OUTLINE")

-	-- hook Cooldown stuff for alpha fix in 6.0
-	HookCooldown(button)
-
 	-- Store the button in the registry, needed for event and OnUpdate handling
 	if not next(ButtonRegistry) then
 		InitializeEventHandler()
@@ -1031,6 +1030,7 @@ function Update(self)
 		end
 		self.cooldown:Hide()
 		self:SetChecked(false)
+
 		if self.chargeCooldown then
 			EndChargeCooldown(self.chargeCooldown)
 		end
@@ -1053,6 +1053,23 @@ function Update(self)

 	-- Update icon and hotkey
 	local texture = self:GetTexture()
+
+	-- Draenor zone button handling
+	self.draenorZoneDisabled = false
+	self.icon:SetDesaturated(false)
+	if self._state_type == "action" then
+		local action_type, id = GetActionInfo(self._state_action)
+		if ((action_type == "spell" or action_type == "companion") and DraenorZoneAbilityFrame and DraenorZoneAbilityFrame.baseName and not HasDraenorZoneAbility()) then
+			local name = GetSpellInfo(DraenorZoneAbilityFrame.baseName)
+			local abilityName = GetSpellInfo(id)
+			if name == abilityName then
+				texture = GetLastDraenorSpellTexture()
+				self.draenorZoneDisabled = true
+				self.icon:SetDesaturated(true)
+			end
+		end
+	end
+
 	if texture then
 		self.icon:SetTexture(texture)
 		self.icon:Show()
@@ -1152,7 +1169,7 @@ function UpdateCount(self)
 		end
 	else
 		local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()
-		if charges and maxCharges and maxCharges > 0 then
+		if charges and maxCharges and maxCharges > 1 then
 			self.Count:SetText(charges)
 		else
 			self.Count:SetText("")
@@ -1160,45 +1177,6 @@ function UpdateCount(self)
 	end
 end

-local function SetCooldownHook(cooldown, ...)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	local start, duration = ...
-
-	if start ~= 0 or duration ~= 0 then
-		-- update swipe alpha
-		cooldown.__metaLAB.SetSwipeColor(cooldown, cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA * effectiveAlpha)
-
-		-- only draw bling and edge if alpha is over 50%
-		cooldown:SetDrawBling(effectiveAlpha > 0.5)
-		if effectiveAlpha < 0.5 then
-			cooldown:SetDrawEdge(false)
-		end
-
-		-- ensure the swipe isn't drawn on fully faded bars
-		if effectiveAlpha <= 0.0 then
-			cooldown:SetDrawSwipe(false)
-		end
-	end
-
-	return cooldown.__metaLAB.SetCooldown(cooldown, ...)
-end
-
-local function SetSwipeColorHook(cooldown, r, g, b, a)
-	local effectiveAlpha = cooldown:GetEffectiveAlpha()
-	cooldown.__SwipeR, cooldown.__SwipeG, cooldown.__SwipeB, cooldown.__SwipeA = r, g, b, (a or 1)
-	return cooldown.__metaLAB.SetSwipeColor(cooldown, r, g, b, a * effectiveAlpha)
-end
-
-function HookCooldown(button)
-	if not button.cooldown.__metaLAB then
-		button.cooldown.__metaLAB = getmetatable(button.cooldown).__index
-		button.cooldown.__SwipeR, button.cooldown.__SwipeG, button.cooldown.__SwipeB, button.cooldown.__SwipeA = 0, 0, 0, 0.8
-
-		button.cooldown.SetCooldown = SetCooldownHook
-		button.cooldown.SetSwipeColor = SetSwipeColorHook
-	end
-end
-
 function EndChargeCooldown(self)
 	self:Hide()
 	self:SetParent(UIParent)
@@ -1225,13 +1203,21 @@ local function StartChargeCooldown(parent, chargeStart, chargeDuration)
 		parent.chargeCooldown = cooldown
 		cooldown.parent = parent
 	end
+	-- set cooldown
+	parent.chargeCooldown:SetDrawBling(parent.chargeCooldown:GetEffectiveAlpha() > 0.5)
 	parent.chargeCooldown:SetCooldown(chargeStart, chargeDuration)
+
+	-- update charge cooldown skin when masque is used
+	if Masque and Masque.UpdateCharge then
+		Masque:UpdateCharge(parent)
+	end
+
 	if not chargeStart or chargeStart == 0 then
 		EndChargeCooldown(parent.chargeCooldown)
 	end
 end

-function OnCooldownDone(self)
+local function OnCooldownDone(self)
 	self:SetScript("OnCooldownDone", nil)
 	UpdateCooldown(self:GetParent())
 end
@@ -1241,30 +1227,41 @@ function UpdateCooldown(self)
 	local start, duration, enable = self:GetCooldown()
 	local charges, maxCharges, chargeStart, chargeDuration = self:GetCharges()

+	self.cooldown:SetDrawBling(self.cooldown:GetEffectiveAlpha() > 0.5)
+
 	if (locStart + locDuration) > (start + duration) then
 		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_LOSS_OF_CONTROL then
 			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge-LoC")
+			self.cooldown:SetSwipeColor(0.17, 0, 0)
 			self.cooldown:SetHideCountdownNumbers(true)
 			self.cooldown.currentCooldownType = COOLDOWN_TYPE_LOSS_OF_CONTROL
-			self.cooldown:SetSwipeColor(0.17, 0, 0, 0.8)
 		end
-		CooldownFrame_Set(self.cooldown, locStart, locDuration, 1, nil, nil, true)
+		if IsLegion then
+			CooldownFrame_Set(self.cooldown, locStart, locDuration, true, true)
+		else
+			CooldownFrame_SetTimer(self.cooldown, locStart, locDuration, 1, true)
+		end
 	else
 		if self.cooldown.currentCooldownType ~= COOLDOWN_TYPE_NORMAL then
 			self.cooldown:SetEdgeTexture("Interface\\Cooldown\\edge")
+			self.cooldown:SetSwipeColor(0, 0, 0)
 			self.cooldown:SetHideCountdownNumbers(false)
 			self.cooldown.currentCooldownType = COOLDOWN_TYPE_NORMAL
-			self.cooldown:SetSwipeColor(0, 0, 0, 0.8)
 		end
 		if locStart > 0 then
 			self.cooldown:SetScript("OnCooldownDone", OnCooldownDone)
 		end
-		if charges and maxCharges and maxCharges > 0 and charges < maxCharges then
+
+		if charges and maxCharges and charges > 0 and charges < maxCharges then
 			StartChargeCooldown(self, chargeStart, chargeDuration)
 		elseif self.chargeCooldown then
 			EndChargeCooldown(self.chargeCooldown)
 		end
-		CooldownFrame_Set(self.cooldown, start, duration, enable, charges, maxCharges)
+		if IsLegion then
+			CooldownFrame_Set(self.cooldown, start, duration, enable)
+		else
+			CooldownFrame_SetTimer(self.cooldown, start, duration, enable)
+		end
 	end
 end

@@ -1312,70 +1309,20 @@ function UpdateHotkeys(self)
 		self.HotKey:SetPoint("TOPLEFT", self, "TOPLEFT", - 2, - 2)
 		self.HotKey:Show()
 	end
-
-	if self.postKeybind then
-		self.postKeybind(nil, self)
-	end
-end
-
-local function OverlayGlow_OnHide(self)
-	if self.animOut:IsPlaying() then
-		self.animOut:Stop()
-		OverlayGlowAnimOutFinished(self.animOut)
-	end
-end
-
-function GetOverlayGlow()
-	local overlay = tremove(lib.unusedOverlayGlows);
-	if not overlay then
-		lib.numOverlays = lib.numOverlays + 1
-		overlay = CreateFrame("Frame", "LAB10ActionButtonOverlay"..lib.numOverlays, UIParent, "ActionBarButtonSpellActivationAlert")
-		overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
-		overlay:SetScript("OnHide", OverlayGlow_OnHide)
-	end
-	return overlay
 end

 function ShowOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animOut:IsPlaying() then
-			self.overlay.animOut:Stop()
-			self.overlay.animIn:Play()
-		end
-	else
-		self.overlay = GetOverlayGlow()
-		local frameWidth, frameHeight = self:GetSize()
-		self.overlay:SetParent(self)
-		self.overlay:ClearAllPoints()
-		--Make the height/width available before the next frame:
-		self.overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
-		self.overlay:SetPoint("TOPLEFT", self, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
-		self.overlay:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
-		self.overlay.animIn:Play()
+	if LBG then
+		LBG.ShowOverlayGlow(self)
 	end
 end

 function HideOverlayGlow(self)
-	if self.overlay then
-		if self.overlay.animIn:IsPlaying() then
-			self.overlay.animIn:Stop()
-		end
-		if self:IsVisible() then
-			self.overlay.animOut:Play()
-		else
-			OverlayGlowAnimOutFinished(self.overlay.animOut)
-		end
+	if LBG then
+		LBG.HideOverlayGlow(self)
 	end
 end

-function OverlayGlowAnimOutFinished(animGroup)
-	local overlay = animGroup:GetParent()
-	local actionButton = overlay:GetParent()
-	overlay:Hide()
-	tinsert(lib.unusedOverlayGlows, overlay)
-	actionButton.overlay = nil
-end
-
 function UpdateOverlayGlow(self)
 	local spellId = self:GetSpellId()
 	if spellId and IsSpellOverlayed(spellId) then
@@ -1457,15 +1404,6 @@ function UpdateRangeTimer()
 	rangeTimer = -1
 end

-local function GetSpellIdByName(spellName)
-	if not spellName then return end
-	local spellLink = GetSpellLink(spellName)
-	if spellLink then
-		return tonumber(spellLink:match("spell:(%d+)"))
-	end
-	return nil
-end
-
 -----------------------------------------------------------
 --- WoW API mapping
 --- Generic Button
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.toc b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.toc
new file mode 100644
index 0000000..61153b6
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## Title: Lib: ActionButton-1.0
+## Notes: Creates and manages secure Action Buttons
+## Author: Nevcairiel
+## X-eMail: h.leppkes@gmail.com
+## X-Category: Library
+## X-License: BSD
+## OptionalDeps: LibKeyBound-1.0, LibButtonGlow-1.0
+## X-Curse-Packaged-Version: 0.28.2
+## X-Curse-Project-Name: LibActionButton-1.0
+## X-Curse-Project-ID: libactionbutton-1-0
+## X-Curse-Repository-ID: wow/libactionbutton-1-0/mainline
+
+LibStub\LibStub.lua
+CallbackHandler-1.0\CallbackHandler-1.0.lua
+LibButtonGlow-1.0\LibButtonGlow-1.0.lua
+
+LibActionButton-1.0.lua
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.xml b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.xml
new file mode 100644
index 0000000..2ae6662
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibActionButton-1.0.xml
@@ -0,0 +1,5 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+	<Script file="LibButtonGlow-1.0\LibButtonGlow-1.0.lua"/>
+	<Script file="LibActionButton-1.0.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.lua
new file mode 100644
index 0000000..0c764da
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.lua
@@ -0,0 +1,244 @@
+--[[
+Copyright (c) 2015, Hendrik "nevcairiel" Leppkes <h.leppkes@gmail.com>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of the developer nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+]]
+local MAJOR_VERSION = "LibButtonGlow-1.0"
+local MINOR_VERSION = 6
+
+if not LibStub then error(MAJOR_VERSION .. " requires LibStub.") end
+local lib, oldversion = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
+if not lib then return end
+
+local Masque = LibStub("Masque", true)
+
+lib.unusedOverlays = lib.unusedOverlays or {}
+lib.numOverlays = lib.numOverlays or 0
+
+local tinsert, tremove, tostring = table.insert, table.remove, tostring
+
+local function OverlayGlowAnimOutFinished(animGroup)
+	local overlay = animGroup:GetParent()
+	local frame = overlay:GetParent()
+	overlay:Hide()
+	tinsert(lib.unusedOverlays, overlay)
+	frame.__LBGoverlay = nil
+end
+
+local function OverlayGlow_OnHide(self)
+	if self.animOut:IsPlaying() then
+		self.animOut:Stop()
+		OverlayGlowAnimOutFinished(self.animOut)
+	end
+end
+
+local function CreateScaleAnim(group, target, order, duration, x, y, delay)
+	local scale = group:CreateAnimation("Scale")
+	scale:SetTarget(target:GetName())
+	scale:SetOrder(order)
+	scale:SetDuration(duration)
+	scale:SetScale(x, y)
+
+	if delay then
+		scale:SetStartDelay(delay)
+	end
+end
+
+local function CreateAlphaAnim(group, target, order, duration, fromAlpha, toAlpha, delay)
+	local alpha = group:CreateAnimation("Alpha")
+	alpha:SetTarget(target:GetName())
+	alpha:SetOrder(order)
+	alpha:SetDuration(duration)
+	alpha:SetFromAlpha(fromAlpha)
+	alpha:SetToAlpha(toAlpha)
+
+	if delay then
+		alpha:SetStartDelay(delay)
+	end
+end
+
+local function AnimIn_OnPlay(group)
+	local frame = group:GetParent()
+	local frameWidth, frameHeight = frame:GetSize()
+	frame.spark:SetSize(frameWidth, frameHeight)
+	frame.spark:SetAlpha(0.3)
+	frame.innerGlow:SetSize(frameWidth / 2, frameHeight / 2)
+	frame.innerGlow:SetAlpha(1.0)
+	frame.innerGlowOver:SetAlpha(1.0)
+	frame.outerGlow:SetSize(frameWidth * 2, frameHeight * 2)
+	frame.outerGlow:SetAlpha(1.0)
+	frame.outerGlowOver:SetAlpha(1.0)
+	frame.ants:SetSize(frameWidth * 0.85, frameHeight * 0.85)
+	frame.ants:SetAlpha(0)
+	frame:Show()
+end
+
+local function AnimIn_OnFinished(group)
+	local frame = group:GetParent()
+	local frameWidth, frameHeight = frame:GetSize()
+	frame.spark:SetAlpha(0)
+	frame.innerGlow:SetAlpha(0)
+	frame.innerGlow:SetSize(frameWidth, frameHeight)
+	frame.innerGlowOver:SetAlpha(0.0)
+	frame.outerGlow:SetSize(frameWidth, frameHeight)
+	frame.outerGlowOver:SetAlpha(0.0)
+	frame.outerGlowOver:SetSize(frameWidth, frameHeight)
+	frame.ants:SetAlpha(1.0)
+end
+
+local function CreateOverlayGlow()
+	lib.numOverlays = lib.numOverlays + 1
+
+	-- create frame and textures
+	local name = "ButtonGlowOverlay" .. tostring(lib.numOverlays)
+	local overlay = CreateFrame("Frame", name, UIParent)
+
+	-- spark
+	overlay.spark = overlay:CreateTexture(name .. "Spark", "BACKGROUND")
+	overlay.spark:SetPoint("CENTER")
+	overlay.spark:SetAlpha(0)
+	overlay.spark:SetTexture([[Interface\SpellActivationOverlay\IconAlert]])
+	overlay.spark:SetTexCoord(0.00781250, 0.61718750, 0.00390625, 0.26953125)
+
+	-- inner glow
+	overlay.innerGlow = overlay:CreateTexture(name .. "InnerGlow", "ARTWORK")
+	overlay.innerGlow:SetPoint("CENTER")
+	overlay.innerGlow:SetAlpha(0)
+	overlay.innerGlow:SetTexture([[Interface\SpellActivationOverlay\IconAlert]])
+	overlay.innerGlow:SetTexCoord(0.00781250, 0.50781250, 0.27734375, 0.52734375)
+
+	-- inner glow over
+	overlay.innerGlowOver = overlay:CreateTexture(name .. "InnerGlowOver", "ARTWORK")
+	overlay.innerGlowOver:SetPoint("TOPLEFT", overlay.innerGlow, "TOPLEFT")
+	overlay.innerGlowOver:SetPoint("BOTTOMRIGHT", overlay.innerGlow, "BOTTOMRIGHT")
+	overlay.innerGlowOver:SetAlpha(0)
+	overlay.innerGlowOver:SetTexture([[Interface\SpellActivationOverlay\IconAlert]])
+	overlay.innerGlowOver:SetTexCoord(0.00781250, 0.50781250, 0.53515625, 0.78515625)
+
+	-- outer glow
+	overlay.outerGlow = overlay:CreateTexture(name .. "OuterGlow", "ARTWORK")
+	overlay.outerGlow:SetPoint("CENTER")
+	overlay.outerGlow:SetAlpha(0)
+	overlay.outerGlow:SetTexture([[Interface\SpellActivationOverlay\IconAlert]])
+	overlay.outerGlow:SetTexCoord(0.00781250, 0.50781250, 0.27734375, 0.52734375)
+
+	-- outer glow over
+	overlay.outerGlowOver = overlay:CreateTexture(name .. "OuterGlowOver", "ARTWORK")
+	overlay.outerGlowOver:SetPoint("TOPLEFT", overlay.outerGlow, "TOPLEFT")
+	overlay.outerGlowOver:SetPoint("BOTTOMRIGHT", overlay.outerGlow, "BOTTOMRIGHT")
+	overlay.outerGlowOver:SetAlpha(0)
+	overlay.outerGlowOver:SetTexture([[Interface\SpellActivationOverlay\IconAlert]])
+	overlay.outerGlowOver:SetTexCoord(0.00781250, 0.50781250, 0.53515625, 0.78515625)
+
+	-- ants
+	overlay.ants = overlay:CreateTexture(name .. "Ants", "OVERLAY")
+	overlay.ants:SetPoint("CENTER")
+	overlay.ants:SetAlpha(0)
+	overlay.ants:SetTexture([[Interface\SpellActivationOverlay\IconAlertAnts]])
+
+	-- setup antimations
+	overlay.animIn = overlay:CreateAnimationGroup()
+	CreateScaleAnim(overlay.animIn, overlay.spark,          1, 0.2, 1.5, 1.5)
+	CreateAlphaAnim(overlay.animIn, overlay.spark,          1, 0.2, 0, 1)
+	CreateScaleAnim(overlay.animIn, overlay.innerGlow,      1, 0.3, 2, 2)
+	CreateScaleAnim(overlay.animIn, overlay.innerGlowOver,  1, 0.3, 2, 2)
+	CreateAlphaAnim(overlay.animIn, overlay.innerGlowOver,  1, 0.3, 1, 0)
+	CreateScaleAnim(overlay.animIn, overlay.outerGlow,      1, 0.3, 0.5, 0.5)
+	CreateScaleAnim(overlay.animIn, overlay.outerGlowOver,  1, 0.3, 0.5, 0.5)
+	CreateAlphaAnim(overlay.animIn, overlay.outerGlowOver,  1, 0.3, 1, 0)
+	CreateScaleAnim(overlay.animIn, overlay.spark,          1, 0.2, 2/3, 2/3, 0.2)
+	CreateAlphaAnim(overlay.animIn, overlay.spark,          1, 0.2, 1, 0, 0.2)
+	CreateAlphaAnim(overlay.animIn, overlay.innerGlow,      1, 0.2, 1, 0, 0.3)
+	CreateAlphaAnim(overlay.animIn, overlay.ants,           1, 0.2, 0, 1, 0.3)
+	overlay.animIn:SetScript("OnPlay", AnimIn_OnPlay)
+	overlay.animIn:SetScript("OnFinished", AnimIn_OnFinished)
+
+	overlay.animOut = overlay:CreateAnimationGroup()
+	CreateAlphaAnim(overlay.animOut, overlay.outerGlowOver, 1, 0.2, 0, 1)
+	CreateAlphaAnim(overlay.animOut, overlay.ants,          1, 0.2, 1, 0)
+	CreateAlphaAnim(overlay.animOut, overlay.outerGlowOver, 2, 0.2, 1, 0)
+	CreateAlphaAnim(overlay.animOut, overlay.outerGlow,     2, 0.2, 1, 0)
+	overlay.animOut:SetScript("OnFinished", OverlayGlowAnimOutFinished)
+
+	-- scripts
+	overlay:SetScript("OnUpdate", ActionButton_OverlayGlowOnUpdate)
+	overlay:SetScript("OnHide", OverlayGlow_OnHide)
+
+	overlay.__LBGVersion = MINOR_VERSION
+
+	return overlay
+end
+
+local function GetOverlayGlow()
+	local overlay = tremove(lib.unusedOverlays)
+	if not overlay then
+		overlay = CreateOverlayGlow()
+	end
+	return overlay
+end
+
+function lib.ShowOverlayGlow(frame)
+	if frame.__LBGoverlay then
+		if frame.__LBGoverlay.animOut:IsPlaying() then
+			frame.__LBGoverlay.animOut:Stop()
+			frame.__LBGoverlay.animIn:Play()
+		end
+	else
+		local overlay = GetOverlayGlow()
+		local frameWidth, frameHeight = frame:GetSize()
+		overlay:SetParent(frame)
+		overlay:SetFrameLevel(frame:GetFrameLevel() + 5)
+		overlay:ClearAllPoints()
+		--Make the height/width available before the next frame:
+		overlay:SetSize(frameWidth * 1.4, frameHeight * 1.4)
+		overlay:SetPoint("TOPLEFT", frame, "TOPLEFT", -frameWidth * 0.2, frameHeight * 0.2)
+		overlay:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", frameWidth * 0.2, -frameHeight * 0.2)
+		overlay.animIn:Play()
+		frame.__LBGoverlay = overlay
+
+		if Masque and Masque.UpdateSpellAlert and (not frame.overlay or not issecurevariable(frame, "overlay")) then
+			local old_overlay = frame.overlay
+			frame.overlay = overlay
+			Masque:UpdateSpellAlert(frame)
+
+			frame.overlay = old_overlay
+		end
+	end
+end
+
+function lib.HideOverlayGlow(frame)
+	if frame.__LBGoverlay then
+		if frame.__LBGoverlay.animIn:IsPlaying() then
+			frame.__LBGoverlay.animIn:Stop()
+		end
+		if frame:IsVisible() then
+			frame.__LBGoverlay.animOut:Play()
+		else
+			OverlayGlowAnimOutFinished(frame.__LBGoverlay.animOut)
+		end
+	end
+end
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.toc b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
new file mode 100644
index 0000000..186c094
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibButtonGlow-1.0.toc
@@ -0,0 +1,18 @@
+## Interface: 70000
+## Title: Lib: ButtonGlow-1.0
+## Notes: Replacement for ActionButton_Show/HideOverlayGlow APIs
+## Author: Nevcairiel
+## X-eMail: h.leppkes@gmail.com
+## X-Category: Library
+## X-License: BSD
+## X-Website: http://www.wowace.com/addons/libbuttonglow-1-0/
+## Version: 1.2.5
+## OptionalDeps: Masque
+## X-Curse-Packaged-Version: 1.2.5
+## X-Curse-Project-Name: LibButtonGlow-1.0
+## X-Curse-Project-ID: libbuttonglow-1-0
+## X-Curse-Repository-ID: wow/libbuttonglow-1-0/mainline
+
+LibStub\LibStub.lua
+
+LibButtonGlow-1.0.lua
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.lua
new file mode 100644
index 0000000..0a41ac0
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.lua
@@ -0,0 +1,30 @@
+-- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+	LibStub = LibStub or {libs = {}, minors = {} }
+	_G[LIBSTUB_MAJOR] = LibStub
+	LibStub.minor = LIBSTUB_MINOR
+
+	function LibStub:NewLibrary(major, minor)
+		assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+		minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+		local oldminor = self.minors[major]
+		if oldminor and oldminor >= minor then return nil end
+		self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+		return self.libs[major], oldminor
+	end
+
+	function LibStub:GetLibrary(major, silent)
+		if not self.libs[major] and not silent then
+			error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+		end
+		return self.libs[major], self.minors[major]
+	end
+
+	function LibStub:IterateLibraries() return pairs(self.libs) end
+	setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.toc b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.toc
new file mode 100644
index 0000000..17cf732
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibButtonGlow-1.0/LibStub/LibStub.toc
@@ -0,0 +1,13 @@
+## Interface: 20400
+## Title: Lib: LibStub
+## Notes: Universal Library Stub
+## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
+## X-Website: http://jira.wowace.com/browse/LS
+## X-Category: Library
+## X-License: Public Domain
+## X-Curse-Packaged-Version: 1.0
+## X-Curse-Project-Name: LibStub
+## X-Curse-Project-ID: libstub
+## X-Curse-Repository-ID: wow/libstub/mainline
+
+LibStub.lua
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.lua b/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.lua
new file mode 100644
index 0000000..0a41ac0
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.lua
@@ -0,0 +1,30 @@
+-- LibStub is a simple versioning stub meant for use in Libraries.  http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2  -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+	LibStub = LibStub or {libs = {}, minors = {} }
+	_G[LIBSTUB_MAJOR] = LibStub
+	LibStub.minor = LIBSTUB_MINOR
+
+	function LibStub:NewLibrary(major, minor)
+		assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+		minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+		local oldminor = self.minors[major]
+		if oldminor and oldminor >= minor then return nil end
+		self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+		return self.libs[major], oldminor
+	end
+
+	function LibStub:GetLibrary(major, silent)
+		if not self.libs[major] and not silent then
+			error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+		end
+		return self.libs[major], self.minors[major]
+	end
+
+	function LibStub:IterateLibraries() return pairs(self.libs) end
+	setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
diff --git a/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.toc b/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.toc
new file mode 100644
index 0000000..17cf732
--- /dev/null
+++ b/SVUI_ActionBars/libs/LibActionButton-1.0/LibStub/LibStub.toc
@@ -0,0 +1,13 @@
+## Interface: 20400
+## Title: Lib: LibStub
+## Notes: Universal Library Stub
+## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
+## X-Website: http://jira.wowace.com/browse/LS
+## X-Category: Library
+## X-License: Public Domain
+## X-Curse-Packaged-Version: 1.0
+## X-Curse-Project-Name: LibStub
+## X-Curse-Project-ID: libstub
+## X-Curse-Repository-ID: wow/libstub/mainline
+
+LibStub.lua
diff --git a/SVUI_ActionBars/libs/_load.xml b/SVUI_ActionBars/libs/_load.xml
index 2c06c97..692c69d 100644
--- a/SVUI_ActionBars/libs/_load.xml
+++ b/SVUI_ActionBars/libs/_load.xml
@@ -1,5 +1,6 @@
 <Ui xmlns="http://www.blizzard.com/wow/ui/">
 	<Script file="LibStub\LibStub.lua"/>
     <Script file="CallbackHandler-1.0\CallbackHandler-1.0.lua"/>
+    <Script file="LibActionButton-1.0\LibButtonGlow-1.0\LibButtonGlow-1.0.lua"/>
     <Script file="LibActionButton-1.0\LibActionButton-1.0.lua"/>
-</Ui>
\ No newline at end of file
+</Ui>
diff --git a/SVUI_Auras/LICENSE.txt b/SVUI_Auras/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Auras/LICENSE.txt
+++ b/SVUI_Auras/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_Auras/SVUI_Auras.lua b/SVUI_Auras/SVUI_Auras.lua
index 28884d8..1ab847a 100644
--- a/SVUI_Auras/SVUI_Auras.lua
+++ b/SVUI_Auras/SVUI_Auras.lua
@@ -60,6 +60,13 @@ local LSM = _G.LibStub("LibSharedMedia-3.0")
 local MOD = SV.Auras;
 if(not MOD) then return end;

+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("Auras")
+else
+	Debug = function() end
+end
+
 MOD.Holder = CreateFrame("Frame", "SVUI_AurasAnchor", UIParent)
 MOD.HyperBuffFrame = CreateFrame('Frame', 'SVUI_ConsolidatedBuffs', UIParent)
 --[[
@@ -378,8 +385,8 @@ do
 			UpdateConsolidatedReminder()
 		else
 			MOD.HyperBuffFrame:Hide()
-			BuffFrame:UnregisterEvent("UNIT_AURA")
-			MOD:UnregisterEvent("UNIT_AURA")
+			--BuffFrame:UnregisterEvent("UNIT_AURA")
+			--MOD:UnregisterEvent("UNIT_AURA")
 			MOD:UnregisterEvent("GROUP_ROSTER_UPDATE")
 			MOD:UnregisterEvent("PLAYER_SPECIALIZATION_CHANGED")
 		end
@@ -466,6 +473,7 @@ function MOD:UpdateAuraHeader(auraHeader, auraType)
 	local showBy = db.showBy

 	if(auraType == "buffs") then
+		Debug("consolidateTo - ",SV.db.Auras.hyperBuffsEnabled == true and 1 or 0)
 		auraHeader:SetAttribute("consolidateTo", SV.db.Auras.hyperBuffsEnabled == true and 1 or 0)
 		auraHeader:SetAttribute("weaponTemplate", ("SVUI_AuraTemplate%d"):format(db.size))
 	end
@@ -607,6 +615,7 @@ function MOD:Load()
 	end
 	]]--
 	if(SV.db.Auras.aurasEnabled) then
+		Debug("Auras enabled")
 		BuffFrame:Die()
 		TemporaryEnchantFrame:Die()
 		InterfaceOptionsFrameCategoriesButton12:SetScale(0.0001)
diff --git a/SVUI_Auras/components/procs.lua b/SVUI_Auras/components/procs.lua
index 06d20aa..ffd80e1 100644
--- a/SVUI_Auras/components/procs.lua
+++ b/SVUI_Auras/components/procs.lua
@@ -60,6 +60,15 @@ local SV = _G['SVUI']
 local L = SV.L
 local MOD = SV.Auras;
 if(not MOD) then return end;
+
+--Debug
+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("Auras")
+else
+	Debug = function() end
+end
+
 --[[
 ##########################################################
 LOCAL VARS
@@ -120,7 +129,9 @@ local PROC_UNIT_AURA = function(self, event, unit)
 	local lastIndex = 1;

 	while true do
+
 		name, _, texture, count, _, duration, expiration, caster, _, _, spellID = UnitAura(unit, index, filter)
+
 		if not name then
 			if filter == "HELPFUL" then
 				filter = "HARMFUL"
diff --git a/SVUI_Chat/LICENSE.txt b/SVUI_Chat/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Chat/LICENSE.txt
+++ b/SVUI_Chat/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_CraftOMatic/License.txt b/SVUI_CraftOMatic/License.txt
index 05ceba8..c907acb 100644
--- a/SVUI_CraftOMatic/License.txt
+++ b/SVUI_CraftOMatic/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_FightOMatic/License.txt b/SVUI_FightOMatic/License.txt
index 69d4d04..18ddca3 100644
--- a/SVUI_FightOMatic/License.txt
+++ b/SVUI_FightOMatic/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_FightOMatic/SVUI_FightOMatic.lua b/SVUI_FightOMatic/SVUI_FightOMatic.lua
index df51313..550a191 100644
--- a/SVUI_FightOMatic/SVUI_FightOMatic.lua
+++ b/SVUI_FightOMatic/SVUI_FightOMatic.lua
@@ -94,7 +94,7 @@ _G.SVUISayIncoming = function()
 end
 --[[
 ##########################################################
-MUNGLUNCH's FAVORITE EMOTE GENERATOR
+Failcoder's FAVORITE EMOTE GENERATOR
 ##########################################################
 ]]--
 local SpecialEmotes = {
diff --git a/SVUI_Inventory/LICENSE.txt b/SVUI_Inventory/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Inventory/LICENSE.txt
+++ b/SVUI_Inventory/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_Inventory/SVUI_Inventory.lua b/SVUI_Inventory/SVUI_Inventory.lua
index 0214620..b1c19f2 100644
--- a/SVUI_Inventory/SVUI_Inventory.lua
+++ b/SVUI_Inventory/SVUI_Inventory.lua
@@ -58,6 +58,7 @@ local DEBUG_BAGS = false;
 local CreateFrame = _G.CreateFrame;
 local hooksecurefunc = _G.hooksecurefunc;
 local numBagFrame = NUM_BAG_FRAMES + 1;
+local MULTI_BAG_LAYOUT = false;
 local MULTI_BAG_HEIGHT_OFFSET = 0;
 local LOOT_CACHE, GEAR_CACHE, GEARSET_LISTING = {}, {}, {};
 local internalTimer;
diff --git a/SVUI_Maps/LICENSE.txt b/SVUI_Maps/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Maps/LICENSE.txt
+++ b/SVUI_Maps/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_Maps/SVUI_Maps.lua b/SVUI_Maps/SVUI_Maps.lua
index 020ffdc..9b82aae 100644
--- a/SVUI_Maps/SVUI_Maps.lua
+++ b/SVUI_Maps/SVUI_Maps.lua
@@ -226,7 +226,8 @@ do
 				local frame = select(i, btn:GetRegions())
 				if frame:GetObjectType() == "Texture" then
 					local iconFile = frame:GetTexture()
-					if(iconFile ~= nil and (iconFile:find("Border") or iconFile:find("Background") or iconFile:find("AlphaMask"))) then
+					--JV: Check type in case iconFile is a number - reported error involving LiDBIcon - need to find root cause
+					if((iconFile ~= nil and type(iconFile) == "string") and (iconFile:find("Border") or iconFile:find("Background") or iconFile:find("AlphaMask"))) then
 						frame:SetTexture("")
 					else
 						frame:ClearAllPoints()
diff --git a/SVUI_NamePlates/LICENSE.txt b/SVUI_NamePlates/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_NamePlates/LICENSE.txt
+++ b/SVUI_NamePlates/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_NamePlates/Loader.lua b/SVUI_NamePlates/Loader.lua
index 568384d..55b2a7e 100644
--- a/SVUI_NamePlates/Loader.lua
+++ b/SVUI_NamePlates/Loader.lua
@@ -248,31 +248,32 @@ function MOD:LoadOptions()
 								desc = L["This will enable/disable the extra fancy styling around elite/rare plates."],
 								set = function(d,e)MOD:ChangeDBVar(e,d[#d])SV:StaticPopup_Show("RL_CLIENT")end
 							},
-							combatHide = {
-								type = "toggle",
-								order = 2,
-								name = L["Combat Toggle"],
-								desc = L["Toggle the nameplates to be invisible outside of combat and visible inside combat."],
-								set = function(d,e)MOD:ChangeDBVar(e,d[#d])MOD:CombatToggle()end
-							},
+							-- combatHide = {
+							-- 	type = "toggle",
+							-- 	order = 2,
+							-- 	name = L["Combat Toggle"],
+							-- 	desc = L["Toggle the nameplates to be invisible outside of combat and visible inside combat."],
+							-- 	set = function(d,e)MOD:ChangeDBVar(e,d[#d]);MOD:CombatToggle();SV:StaticPopup_Show("RL_CLIENT");end
+							-- },
 							comboPoints = {
 								type = "toggle",
 								order = 3,
-								name = L["Combo Points"],
-								desc = L["Display combo points on nameplates."]
-							},
-							colorNameByValue = {
-								type = "toggle",
-								order = 4,
-								name = L["Color Name By Health Value"],
-								width = 'full',
-							},
-							showthreat = {
-								type = "toggle",
-								order = 5,
-								name = L["Threat Text"],
-								desc = L["Display threat level as text on targeted,	boss or mouseover nameplate."]
+								name = L["Combo Points on Enemy"],
+								desc = L["Display combo points on enemy nameplates"],
+								set = function(d,e)MOD:ChangeDBVar(e,d[#d]);MOD:ComboToggle();SV:StaticPopup_Show("RL_CLIENT");end
 							},
+							-- colorNameByValue = {
+							-- 	type = "toggle",
+							-- 	order = 4,
+							-- 	name = L["Color Name By Health Value"],
+							-- 	width = 'full',
+							-- },
+							-- showthreat = {
+							-- 	type = "toggle",
+							-- 	order = 5,
+							-- 	name = L["Threat Text"],
+							-- 	desc = L["Display threat level as text on targeted,	boss or mouseover nameplate."]
+							-- },
 							barTexture = {
 								type = "select",
 								dialogControl = "LSM30_Statusbar",
@@ -281,189 +282,189 @@ function MOD:LoadOptions()
 								desc = L["Main statusbar texture."],
 								values = AceVillainWidgets.statusbar
 							},
-							nonTargetAlpha = {
-								type = "range",
-								order = 7,
-								name = L["Non-Target Alpha"],
-								desc = L["Alpha of nameplates that are not your current target."],
-								width = 'full',
-								min = 0,
-								max = 1,
-								step = 0.01,
-								isPercent = true
-							},
-							spacer1 = {
-								order = 8,
-								type = "description",
-								name = "",
-								width = "full",
-							},
-							reactions = {
-								order = 9,
-								type = "group",
-								name = L["Reaction Coloring"],
-								guiInline = true,
-								get = function(key)
-									local color = SV.db[Schema].reactions[key[#key]]
-									if color then
-										return color[1],color[2],color[3],color[4]
-									end
-								end,
-								set = function(key,r,g,b)
-									local color = {r,g,b}
-									MOD:ChangeDBVar(color, key[#key], "reactions")
-									MOD:UpdateAllPlates()
-								end,
-								args = {
-									friendlyNPC = {
-										type = "color",
-										order = 1,
-										name = L["Friendly NPC"],
-										hasAlpha = false
-									},
-									friendlyPlayer = {
-										name = L["Friendly Player"],
-										order = 2,
-										type = "color",
-										hasAlpha = false
-									},
-									neutral = {
-										name = L["Neutral"],
-										order = 3,
-										type = "color",
-										hasAlpha = false
-									},
-									enemy = {
-										name = L["Enemy"],
-										order = 4,
-										type = "color",
-										hasAlpha = false
-									},
-									tapped = {
-										name = L["Tagged NPC"],
-										order = 5,
-										type = "color",
-										hasAlpha = false
-									},
-								}
-							},
-							threat = {
-								type = "group",
-								name = L["Threat Coloring"],
-								guiInline = true,
-								order = 10,
-								args = {
-									enable = {
-										type = "toggle",
-										order = 1,
-										name = L["Enable Threat Coloring"],
-										width = "full",
-										get = function(key)return SV.db[Schema].threat.enable end,
-										set = function(key,value) SV.db[Schema].threat.enable = value; MOD:UpdateAllPlates() end,
-									},
-									goodColor = {
-										type = "color",
-										order = 2,
-										name = L["Good Threat"],
-										hasAlpha = false,
-										disabled = function(key) return not SV.db[Schema].threat.enable end,
-										get = function(key)
-											local color = SV.db[Schema].threat.goodColor
-											if color then
-												return color[1],color[2],color[3],color[4]
-											end
-										end,
-										set = function(key,r,g,b)
-											SV.db[Schema].threat.goodColor = {r,g,b}
-											MOD:UpdateAllPlates()
-										end,
-									},
-									badColor = {
-										name = L["Bad Threat"],
-										order = 3,
-										type = "color",
-										hasAlpha = false,
-										disabled = function(key) return not SV.db[Schema].threat.enable end,
-										get = function(key)
-											local color = SV.db[Schema].threat.badColor
-											if color then
-												return color[1],color[2],color[3],color[4]
-											end
-										end,
-										set = function(key,r,g,b)
-											SV.db[Schema].threat.badColor = {r,g,b}
-											MOD:UpdateAllPlates()
-										end,
-									},
-									goodTransitionColor = {
-										name = L["Good Threat Transition"],
-										order = 4,
-										type = "color",
-										hasAlpha = false,
-										disabled = function(key) return not SV.db[Schema].threat.enable end,
-										get = function(key)
-											local color = SV.db[Schema].threat.goodTransitionColor
-											if color then
-												return color[1],color[2],color[3],color[4]
-											end
-										end,
-										set = function(key,r,g,b)
-											SV.db[Schema].threat.goodTransitionColor = {r,g,b}
-											MOD:UpdateAllPlates()
-										end,
-									},
-									badTransitionColor = {
-										name = L["Bad Threat Transition"],
-										order = 5,
-										type = "color",
-										hasAlpha = false,
-										disabled = function(key) return not SV.db[Schema].threat.enable end,
-										get = function(key)
-											local color = SV.db[Schema].threat.badTransitionColor
-											if color then
-												return color[1],color[2],color[3],color[4]
-											end
-										end,
-										set = function(key,r,g,b)
-											SV.db[Schema].threat.badTransitionColor = {r,g,b}
-											MOD:UpdateAllPlates()
-										end,
-									},
-								}
-							},
-							scaling = {
-								type = "group",
-								name = L["Threat Scaling"],
-								guiInline = true,
-								order = 11,
-								disabled = function(key) return not SV.db[Schema].threat.enable end,
-								args = {
-									goodScale = {
-										type = "range",
-										name = L["Good"],
-										order = 1,
-										min = 0.5,
-										max = 1.5,
-										step = 0.01,
-										width = 'full',
-										isPercent = true,
-										get = function(key)return SV.db[Schema].threat.goodScale end,
-										set = function(key,value) SV.db[Schema].threat.goodScale = value; MOD:UpdateAllPlates() end,
-									},
-									badScale = {
-										type = "range",
-										name = L["Bad"],
-										order = 1,
-										min = 0.5,
-										max = 1.5,
-										step = 0.01,
-										width = 'full',
-										isPercent = true,
-										get = function(key)return SV.db[Schema].threat.badScale end,
-										set = function(key,value) SV.db[Schema].threat.badScale = value; MOD:UpdateAllPlates() end,
-									}
-								}
-							},
+							-- nonTargetAlpha = {
+							-- 	type = "range",
+							-- 	order = 7,
+							-- 	name = L["Non-Target Alpha"],
+							-- 	desc = L["Alpha of nameplates that are not your current target."],
+							-- 	width = 'full',
+							-- 	min = 0,
+							-- 	max = 1,
+							-- 	step = 0.01,
+							-- 	isPercent = true
+							-- },
+							-- spacer1 = {
+							-- 	order = 8,
+							-- 	type = "description",
+							-- 	name = "",
+							-- 	width = "full",
+							-- },
+							-- reactions = {
+							-- 	order = 9,
+							-- 	type = "group",
+							-- 	name = L["Reaction Coloring"],
+							-- 	guiInline = true,
+							-- 	get = function(key)
+							-- 		local color = SV.db[Schema].reactions[key[#key]]
+							-- 		if color then
+							-- 			return color[1],color[2],color[3],color[4]
+							-- 		end
+							-- 	end,
+							-- 	set = function(key,r,g,b)
+							-- 		local color = {r,g,b}
+							-- 		MOD:ChangeDBVar(color, key[#key], "reactions")
+							-- 		MOD:UpdateAllPlates()
+							-- 	end,
+							-- 	args = {
+							-- 		friendlyNPC = {
+							-- 			type = "color",
+							-- 			order = 1,
+							-- 			name = L["Friendly NPC"],
+							-- 			hasAlpha = false
+							-- 		},
+							-- 		friendlyPlayer = {
+							-- 			name = L["Friendly Player"],
+							-- 			order = 2,
+							-- 			type = "color",
+							-- 			hasAlpha = false
+							-- 		},
+							-- 		neutral = {
+							-- 			name = L["Neutral"],
+							-- 			order = 3,
+							-- 			type = "color",
+							-- 			hasAlpha = false
+							-- 		},
+							-- 		enemy = {
+							-- 			name = L["Enemy"],
+							-- 			order = 4,
+							-- 			type = "color",
+							-- 			hasAlpha = false
+							-- 		},
+							-- 		tapped = {
+							-- 			name = L["Tagged NPC"],
+							-- 			order = 5,
+							-- 			type = "color",
+							-- 			hasAlpha = false
+							-- 		},
+							-- 	}
+							-- },
+							-- threat = {
+							-- 	type = "group",
+							-- 	name = L["Threat Coloring"],
+							-- 	guiInline = true,
+							-- 	order = 10,
+							-- 	args = {
+							-- 		enable = {
+							-- 			type = "toggle",
+							-- 			order = 1,
+							-- 			name = L["Enable Threat Coloring"],
+							-- 			width = "full",
+							-- 			get = function(key)return SV.db[Schema].threat.enable end,
+							-- 			set = function(key,value) SV.db[Schema].threat.enable = value; MOD:UpdateAllPlates() end,
+							-- 		},
+							-- 		goodColor = {
+							-- 			type = "color",
+							-- 			order = 2,
+							-- 			name = L["Good Threat"],
+							-- 			hasAlpha = false,
+							-- 			disabled = function(key) return not SV.db[Schema].threat.enable end,
+							-- 			get = function(key)
+							-- 				local color = SV.db[Schema].threat.goodColor
+							-- 				if color then
+							-- 					return color[1],color[2],color[3],color[4]
+							-- 				end
+							-- 			end,
+							-- 			set = function(key,r,g,b)
+							-- 				SV.db[Schema].threat.goodColor = {r,g,b}
+							-- 				MOD:UpdateAllPlates()
+							-- 			end,
+							-- 		},
+							-- 		badColor = {
+							-- 			name = L["Bad Threat"],
+							-- 			order = 3,
+							-- 			type = "color",
+							-- 			hasAlpha = false,
+							-- 			disabled = function(key) return not SV.db[Schema].threat.enable end,
+							-- 			get = function(key)
+							-- 				local color = SV.db[Schema].threat.badColor
+							-- 				if color then
+							-- 					return color[1],color[2],color[3],color[4]
+							-- 				end
+							-- 			end,
+							-- 			set = function(key,r,g,b)
+							-- 				SV.db[Schema].threat.badColor = {r,g,b}
+							-- 				MOD:UpdateAllPlates()
+							-- 			end,
+							-- 		},
+							-- 		goodTransitionColor = {
+							-- 			name = L["Good Threat Transition"],
+							-- 			order = 4,
+							-- 			type = "color",
+							-- 			hasAlpha = false,
+							-- 			disabled = function(key) return not SV.db[Schema].threat.enable end,
+							-- 			get = function(key)
+							-- 				local color = SV.db[Schema].threat.goodTransitionColor
+							-- 				if color then
+							-- 					return color[1],color[2],color[3],color[4]
+							-- 				end
+							-- 			end,
+							-- 			set = function(key,r,g,b)
+							-- 				SV.db[Schema].threat.goodTransitionColor = {r,g,b}
+							-- 				MOD:UpdateAllPlates()
+							-- 			end,
+							-- 		},
+							-- 		badTransitionColor = {
+							-- 			name = L["Bad Threat Transition"],
+							-- 			order = 5,
+							-- 			type = "color",
+							-- 			hasAlpha = false,
+							-- 			disabled = function(key) return not SV.db[Schema].threat.enable end,
+							-- 			get = function(key)
+							-- 				local color = SV.db[Schema].threat.badTransitionColor
+							-- 				if color then
+							-- 					return color[1],color[2],color[3],color[4]
+							-- 				end
+							-- 			end,
+							-- 			set = function(key,r,g,b)
+							-- 				SV.db[Schema].threat.badTransitionColor = {r,g,b}
+							-- 				MOD:UpdateAllPlates()
+							-- 			end,
+							-- 		},
+							-- 	}
+							-- },
+							-- scaling = {
+							-- 	type = "group",
+							-- 	name = L["Threat Scaling"],
+							-- 	guiInline = true,
+							-- 	order = 11,
+							-- 	disabled = function(key) return not SV.db[Schema].threat.enable end,
+							-- 	args = {
+							-- 		goodScale = {
+							-- 			type = "range",
+							-- 			name = L["Good"],
+							-- 			order = 1,
+							-- 			min = 0.5,
+							-- 			max = 1.5,
+							-- 			step = 0.01,
+							-- 			width = 'full',
+							-- 			isPercent = true,
+							-- 			get = function(key)return SV.db[Schema].threat.goodScale end,
+							-- 			set = function(key,value) SV.db[Schema].threat.goodScale = value; MOD:UpdateAllPlates() end,
+							-- 		},
+							-- 		badScale = {
+							-- 			type = "range",
+							-- 			name = L["Bad"],
+							-- 			order = 1,
+							-- 			min = 0.5,
+							-- 			max = 1.5,
+							-- 			step = 0.01,
+							-- 			width = 'full',
+							-- 			isPercent = true,
+							-- 			get = function(key)return SV.db[Schema].threat.badScale end,
+							-- 			set = function(key,value) SV.db[Schema].threat.badScale = value; MOD:UpdateAllPlates() end,
+							-- 		}
+							-- 	}
+							-- },
 						}
 					},
 					healthBar = {
@@ -473,16 +474,16 @@ function MOD:LoadOptions()
 						get = function(d)return SV.db[Schema].healthBar[d[#d]]end,
 						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"healthBar");MOD:UpdateAllPlates()end,
 						args = {
-							width = {
-								type = "range",
-								order = 1,
-								name = L["Width"],
-								desc = L["Controls the width of the nameplate"],
-								type = "range",
-								min = 50,
-								max = 125,
-								step = 1
-							},
+							-- width = {
+							-- 	type = "range",
+							-- 	order = 1,
+							-- 	name = L["Width"],
+							-- 	desc = L["Controls the width of the nameplate"],
+							-- 	type = "range",
+							-- 	min = 50,
+							-- 	max = 125,
+							-- 	step = 1
+							-- },
 							height = {
 								type = "range",
 								order = 2,
@@ -493,76 +494,76 @@ function MOD:LoadOptions()
 								max = 30,
 								step = 1
 							},
-							lowThreshold = {
-								type = "range",
-								order = 3,
-								name = L["Low Health Threshold"],
-								desc = L["Color the border of the nameplate yellow when it reaches this point,it will be colored red when it reaches half this value."],
-								isPercent = true,
-								min = 0,
-								max = 1,
-								step = 0.01
-							},
-							fontGroup = {
-								order = 4,
-								type = "group",
-								name = L["Texts"],
-								guiInline = true,
-								get = function(d)return SV.db[Schema].healthBar.text[d[#d]]end,
-								set = function(d,e)MOD:ChangeDBVar(e,d[#d],"healthBar","text");MOD:UpdateAllPlates()end,
-								args = {
-									enable = {
-										type = "toggle",
-										name = L["Enable"],
-										order = 1
-									},
-									attachTo = {
-										type = "select",
-										order = 2,
-										name = L["Attach To"],
-										values = {
-											TOPLEFT = "TOPLEFT",
-											LEFT = "LEFT",
-											BOTTOMLEFT = "BOTTOMLEFT",
-											RIGHT = "RIGHT",
-											TOPRIGHT = "TOPRIGHT",
-											BOTTOMRIGHT = "BOTTOMRIGHT",
-											CENTER = "CENTER",
-											TOP = "TOP",
-											BOTTOM = "BOTTOM"
-										}
-									},
-									format = {
-										type = "select",
-										order = 3,
-										name = L["Format"],
-										values = {
-											["CURRENT_MAX_PERCENT"] = L["Current - Max | Percent"],
-											["CURRENT_PERCENT"] = L["Current - Percent"],
-											["CURRENT_MAX"] = L["Current - Max"],
-											["CURRENT"] = L["Current"],
-											["PERCENT"] = L["Percent"],
-											["DEFICIT"] = L["Deficit"]
-										}
-									},
-									xOffset = {
-										type = "range",
-										order = 4,
-										name = L["X-Offset"],
-										min = -150,
-										max = 150,
-										step = 1
-									},
-									yOffset = {
-										type = "range",
-										order = 5,
-										name = L["Y-Offset"],
-										min = -150,
-										max = 150,
-										step = 1
-									}
-								}
-							}
+							-- lowThreshold = {
+							-- 	type = "range",
+							-- 	order = 3,
+							-- 	name = L["Low Health Threshold"],
+							-- 	desc = L["Color the border of the nameplate yellow when it reaches this point,it will be colored red when it reaches half this value."],
+							-- 	isPercent = true,
+							-- 	min = 0,
+							-- 	max = 1,
+							-- 	step = 0.01
+							-- },
+							-- fontGroup = {
+							-- 	order = 4,
+							-- 	type = "group",
+							-- 	name = L["Texts"],
+							-- 	guiInline = true,
+							-- 	get = function(d)return SV.db[Schema].healthBar.text[d[#d]]end,
+							-- 	set = function(d,e)MOD:ChangeDBVar(e,d[#d],"healthBar","text");MOD:UpdateAllPlates()end,
+							-- 	args = {
+							-- 		enable = {
+							-- 			type = "toggle",
+							-- 			name = L["Enable"],
+							-- 			order = 1
+							-- 		},
+							-- 		attachTo = {
+							-- 			type = "select",
+							-- 			order = 2,
+							-- 			name = L["Attach To"],
+							-- 			values = {
+							-- 				TOPLEFT = "TOPLEFT",
+							-- 				LEFT = "LEFT",
+							-- 				BOTTOMLEFT = "BOTTOMLEFT",
+							-- 				RIGHT = "RIGHT",
+							-- 				TOPRIGHT = "TOPRIGHT",
+							-- 				BOTTOMRIGHT = "BOTTOMRIGHT",
+							-- 				CENTER = "CENTER",
+							-- 				TOP = "TOP",
+							-- 				BOTTOM = "BOTTOM"
+							-- 			}
+							-- 		},
+							-- 		format = {
+							-- 			type = "select",
+							-- 			order = 3,
+							-- 			name = L["Format"],
+							-- 			values = {
+							-- 				["CURRENT_MAX_PERCENT"] = L["Current - Max | Percent"],
+							-- 				["CURRENT_PERCENT"] = L["Current - Percent"],
+							-- 				["CURRENT_MAX"] = L["Current - Max"],
+							-- 				["CURRENT"] = L["Current"],
+							-- 				["PERCENT"] = L["Percent"],
+							-- 				["DEFICIT"] = L["Deficit"]
+							-- 			}
+							-- 		},
+							-- 		xOffset = {
+							-- 			type = "range",
+							-- 			order = 4,
+							-- 			name = L["X-Offset"],
+							-- 			min = -150,
+							-- 			max = 150,
+							-- 			step = 1
+							-- 		},
+							-- 		yOffset = {
+							-- 			type = "range",
+							-- 			order = 5,
+							-- 			name = L["Y-Offset"],
+							-- 			min = -150,
+							-- 			max = 150,
+							-- 			step = 1
+							-- 		}
+							-- 	}
+							--}
 						}
 					},
 					castBar = {
@@ -614,231 +615,231 @@ function MOD:LoadOptions()
 							}
 						}
 					},
-					pointer = {
-						type = "group",
-						order = 4,
-						name = L["Target Indicator"],
-						get = function(d)return SV.db[Schema].pointer[d[#d]]end,
-						set = function(d,e) MOD:ChangeDBVar(e,d[#d],"pointer"); _G.WorldFrame.elapsed = 3; MOD:UpdateAllPlates() end,
-						args = {
-							enable = {
-								order = 1,
-								type = "toggle",
-								name = L["Enable"]
-							},
-							useArrowEffect = {
-								order = 2,
-								type = "toggle",
-								name = L["Use 3D Arrow"]
-							},
-							colorMatchHealthBar = {
-								order = 3,
-								type = "toggle",
-								name = L["Color By Healthbar"],
-								desc = L["Match the color of the healthbar."],
-								set = function(key, value)
-									MOD:ChangeDBVar(value, key[#key], "pointer");
-									if value then
-										_G.WorldFrame.elapsed = 3
-									end
-								end
-							},
-							color = {
-								type = "color",
-								name = L["Color"],
-								order = 4,
-								disabled = function()return SV.db[Schema].pointer.colorMatchHealthBar end,
-								get = function(key)
-									local color = SV.db[Schema].pointer[key[#key]]
-									if color then
-										return color[1],color[2],color[3],color[4]
-									end
-								end,
-								set = function(key,r,g,b)
-									local color = {r,g,b}
-									MOD:ChangeDBVar(color, key[#key], "pointer")
-									MOD:UpdateAllPlates()
-								end,
-							}
-						}
-					},
-					raidHealIcon = {
-						type = "group",
-						order = 5,
-						name = L["Raid Icon"],
-						get = function(d)return SV.db[Schema].raidHealIcon[d[#d]]end,
-						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"raidHealIcon")MOD:UpdateAllPlates()end,
-						args = {
-							attachTo = {
-								type = "select",
-								order = 1,
-								name = L["Attach To"],
-								values = positionTable
-							},
-							xOffset = {
-								type = "range",
-								order = 2,
-								name = L["X-Offset"],
-								min = -150,
-								max = 150,
-								step = 1
-							},
-							yOffset = {
-								type = "range",
-								order = 3,
-								name = L["Y-Offset"],
-								min = -150,
-								max = 150,
-								step = 1
-							},
-							size = {
-								order = 4,
-								type = "range",
-								name = L["Size"],
-								width = "full",
-								min = 10,
-								max = 200,
-								step = 1
-							},
-						}
-					},
-					auras = {
-						type = "group",
-						order = 4,
-						name = L["Auras"],
-						get = function(d)return SV.db[Schema].auras[d[#d]]end,
-						set = function(d,e)MOD:ChangeDBVar(e,d[#d],"auras")MOD:UpdateAllPlates()end,
-						args = {
-							numAuras = {
-								type = "range",
-								order = 1,
-								name = L["Number of Auras"],
-								min = 2,
-								max = 8,
-								step = 1
-							},
-							additionalFilter = {
-								type = "select",
-								order = 2,
-								name = L["Additional Filter"],
-								values = function()
-									filters = {}
-									filters[""] = _G.NONE;
-									for j in pairs(SV.db.Filters.Custom) do
-										filters[j] = j
-									end
-									return filters
-								end
-							},
-							configureButton = {
-								order = 4,
-								name = L["Configure Selected Filter"],
-								type = "execute",
-								width = "full",
-								func = function()ns:SetToFilterConfig(SV.db[Schema].auras.additionalFilter)end
-							},
-							fontGroup = {
-								order = 100,
-								type = "group",
-								guiInline = true,
-								name = L["Fonts"],
-								args = {
-									font = {
-										type = "select",
-										dialogControl = "LSM30_Font",
-										order = 4,
-										name = L["Font"],
-										values = AceVillainWidgets.font
-									},
-									fontSize = {
-										order = 5,
-										name = L["Font Size"],
-										type = "range",
-										min = 6,
-										max = 22,
-										step = 1
-									},
-									fontOutline = {
-										order = 6,
-										name = L["Font Outline"],
-										desc = L["Set the font outline."],
-										type = "select",
-										values = {
-											["NONE"] = L["None"],
-											["OUTLINE"] = "OUTLINE",
-											["MONOCHROMEOUTLINE"] = "MONOCROMEOUTLINE",
-											["THICKOUTLINE"] = "THICKOUTLINE"
-										}
-									}
-								}
-							}
-						}
-					},
-					filters = {
-						type = "group",
-						order = 5,
-						name = L["Filters"],
-						args = {
-							addname = {
-								type = "input",
-								order = 1,
-								name = L["Add Name"],
-								get = function(d)return""end,
-								set = function(d,e)
-									if SV.db["NamePlates"]["filter"][e]then
-										SV:AddonMessage(L["Filter already exists!"])
-										return
-									end
-									SV.db["NamePlates"]["filter"][e] = {
-										["enable"] = true,
-										["hide"] = false,
-										["customColor"] = false,
-										["customScale"] = 1,
-										["color"] = {
-											g = 104/255,
-											h = 138/255,
-											i = 217/255
-										}
-									}
-									UpdateFilterGroupOptions()
-									MOD:UpdateAllPlates()
-								end
-							},
-							deletename = {
-								type = "input",
-								order = 2,
-								name = L["Remove Name"],
-								get = function(d)return""end,
-								set = function(d,e)
-									if SV.db["NamePlates"]["filter"][e] then
-										SV.db["NamePlates"]["filter"][e].enable = false;
-										SV:AddonMessage(L["You can't remove a default name from the filter,disabling the name."])
-									else
-										SV.db["NamePlates"]["filter"][e] = nil;
-										SV.Options.args[Schema].args.Filters.args.filterGroup = nil
-									end
-									UpdateFilterGroupOptions()
-									MOD:UpdateAllPlates()
-								end
-							},
-							selectFilter = {
-								order = 3,
-								type = "select",
-								name = L["Select Filter"],
-								get = function(d)return activeFilter end,
-								set = function(d,e)activeFilter = e;UpdateFilterGroupOptions()end,
-								values = function()
-									filters = {}
-									if(SV.db["NamePlates"]["filter"]) then
-										for j in pairs(SV.db["NamePlates"]["filter"])do
-											filters[j] = j
-										end
-									end
-									return filters
-								end
-							}
-						}
-					}
+					-- pointer = {
+					-- 	type = "group",
+					-- 	order = 4,
+					-- 	name = L["Target Indicator"],
+					-- 	get = function(d)return SV.db[Schema].pointer[d[#d]]end,
+					-- 	set = function(d,e) MOD:ChangeDBVar(e,d[#d],"pointer"); _G.WorldFrame.elapsed = 3; MOD:UpdateAllPlates() end,
+					-- 	args = {
+					-- 		enable = {
+					-- 			order = 1,
+					-- 			type = "toggle",
+					-- 			name = L["Enable"]
+					-- 		},
+					-- 		useArrowEffect = {
+					-- 			order = 2,
+					-- 			type = "toggle",
+					-- 			name = L["Use 3D Arrow"]
+					-- 		},
+					-- 		colorMatchHealthBar = {
+					-- 			order = 3,
+					-- 			type = "toggle",
+					-- 			name = L["Color By Healthbar"],
+					-- 			desc = L["Match the color of the healthbar."],
+					-- 			set = function(key, value)
+					-- 				MOD:ChangeDBVar(value, key[#key], "pointer");
+					-- 				if value then
+					-- 					_G.WorldFrame.elapsed = 3
+					-- 				end
+					-- 			end
+					-- 		},
+					-- 		color = {
+					-- 			type = "color",
+					-- 			name = L["Color"],
+					-- 			order = 4,
+					-- 			disabled = function()return SV.db[Schema].pointer.colorMatchHealthBar end,
+					-- 			get = function(key)
+					-- 				local color = SV.db[Schema].pointer[key[#key]]
+					-- 				if color then
+					-- 					return color[1],color[2],color[3],color[4]
+					-- 				end
+					-- 			end,
+					-- 			set = function(key,r,g,b)
+					-- 				local color = {r,g,b}
+					-- 				MOD:ChangeDBVar(color, key[#key], "pointer")
+					-- 				MOD:UpdateAllPlates()
+					-- 			end,
+					-- 		}
+					-- 	}
+					-- },
+					-- raidHealIcon = {
+					-- 	type = "group",
+					-- 	order = 5,
+					-- 	name = L["Raid Icon"],
+					-- 	get = function(d)return SV.db[Schema].raidHealIcon[d[#d]]end,
+					-- 	set = function(d,e)MOD:ChangeDBVar(e,d[#d],"raidHealIcon")MOD:UpdateAllPlates()end,
+					-- 	args = {
+					-- 		attachTo = {
+					-- 			type = "select",
+					-- 			order = 1,
+					-- 			name = L["Attach To"],
+					-- 			values = positionTable
+					-- 		},
+					-- 		xOffset = {
+					-- 			type = "range",
+					-- 			order = 2,
+					-- 			name = L["X-Offset"],
+					-- 			min = -150,
+					-- 			max = 150,
+					-- 			step = 1
+					-- 		},
+					-- 		yOffset = {
+					-- 			type = "range",
+					-- 			order = 3,
+					-- 			name = L["Y-Offset"],
+					-- 			min = -150,
+					-- 			max = 150,
+					-- 			step = 1
+					-- 		},
+					-- 		size = {
+					-- 			order = 4,
+					-- 			type = "range",
+					-- 			name = L["Size"],
+					-- 			width = "full",
+					-- 			min = 10,
+					-- 			max = 200,
+					-- 			step = 1
+					-- 		},
+					-- 	}
+					-- },
+					-- auras = {
+					-- 	type = "group",
+					-- 	order = 4,
+					-- 	name = L["Auras"],
+					-- 	get = function(d)return SV.db[Schema].auras[d[#d]]end,
+					-- 	set = function(d,e)MOD:ChangeDBVar(e,d[#d],"auras")MOD:UpdateAllPlates()end,
+					-- 	args = {
+					-- 		numAuras = {
+					-- 			type = "range",
+					-- 			order = 1,
+					-- 			name = L["Number of Auras"],
+					-- 			min = 2,
+					-- 			max = 8,
+					-- 			step = 1
+					-- 		},
+					-- 		additionalFilter = {
+					-- 			type = "select",
+					-- 			order = 2,
+					-- 			name = L["Additional Filter"],
+					-- 			values = function()
+					-- 				filters = {}
+					-- 				filters[""] = _G.NONE;
+					-- 				for j in pairs(SV.db.Filters.Custom) do
+					-- 					filters[j] = j
+					-- 				end
+					-- 				return filters
+					-- 			end
+					-- 		},
+					-- 		configureButton = {
+					-- 			order = 4,
+					-- 			name = L["Configure Selected Filter"],
+					-- 			type = "execute",
+					-- 			width = "full",
+					-- 			func = function()ns:SetToFilterConfig(SV.db[Schema].auras.additionalFilter)end
+					-- 		},
+					-- 		fontGroup = {
+					-- 			order = 100,
+					-- 			type = "group",
+					-- 			guiInline = true,
+					-- 			name = L["Fonts"],
+					-- 			args = {
+					-- 				font = {
+					-- 					type = "select",
+					-- 					dialogControl = "LSM30_Font",
+					-- 					order = 4,
+					-- 					name = L["Font"],
+					-- 					values = AceVillainWidgets.font
+					-- 				},
+					-- 				fontSize = {
+					-- 					order = 5,
+					-- 					name = L["Font Size"],
+					-- 					type = "range",
+					-- 					min = 6,
+					-- 					max = 22,
+					-- 					step = 1
+					-- 				},
+					-- 				fontOutline = {
+					-- 					order = 6,
+					-- 					name = L["Font Outline"],
+					-- 					desc = L["Set the font outline."],
+					-- 					type = "select",
+					-- 					values = {
+					-- 						["NONE"] = L["None"],
+					-- 						["OUTLINE"] = "OUTLINE",
+					-- 						["MONOCHROMEOUTLINE"] = "MONOCROMEOUTLINE",
+					-- 						["THICKOUTLINE"] = "THICKOUTLINE"
+					-- 					}
+					-- 				}
+					-- 			}
+					-- 		}
+					-- 	}
+					-- },
+					-- filters = {
+					-- 	type = "group",
+					-- 	order = 5,
+					-- 	name = L["Filters"],
+					-- 	args = {
+					-- 		addname = {
+					-- 			type = "input",
+					-- 			order = 1,
+					-- 			name = L["Add Name"],
+					-- 			get = function(d)return""end,
+					-- 			set = function(d,e)
+					-- 				if SV.db["NamePlates"]["filter"][e]then
+					-- 					SV:AddonMessage(L["Filter already exists!"])
+					-- 					return
+					-- 				end
+					-- 				SV.db["NamePlates"]["filter"][e] = {
+					-- 					["enable"] = true,
+					-- 					["hide"] = false,
+					-- 					["customColor"] = false,
+					-- 					["customScale"] = 1,
+					-- 					["color"] = {
+					-- 						g = 104/255,
+					-- 						h = 138/255,
+					-- 						i = 217/255
+					-- 					}
+					-- 				}
+					-- 				UpdateFilterGroupOptions()
+					-- 				MOD:UpdateAllPlates()
+					-- 			end
+					-- 		},
+					-- 		deletename = {
+					-- 			type = "input",
+					-- 			order = 2,
+					-- 			name = L["Remove Name"],
+					-- 			get = function(d)return""end,
+					-- 			set = function(d,e)
+					-- 				if SV.db["NamePlates"]["filter"][e] then
+					-- 					SV.db["NamePlates"]["filter"][e].enable = false;
+					-- 					SV:AddonMessage(L["You can't remove a default name from the filter,disabling the name."])
+					-- 				else
+					-- 					SV.db["NamePlates"]["filter"][e] = nil;
+					-- 					SV.Options.args[Schema].args.Filters.args.filterGroup = nil
+					-- 				end
+					-- 				UpdateFilterGroupOptions()
+					-- 				MOD:UpdateAllPlates()
+					-- 			end
+					-- 		},
+					-- 		selectFilter = {
+					-- 			order = 3,
+					-- 			type = "select",
+					-- 			name = L["Select Filter"],
+					-- 			get = function(d)return activeFilter end,
+					-- 			set = function(d,e)activeFilter = e;UpdateFilterGroupOptions()end,
+					-- 			values = function()
+					-- 				filters = {}
+					-- 				if(SV.db["NamePlates"]["filter"]) then
+					-- 					for j in pairs(SV.db["NamePlates"]["filter"])do
+					-- 						filters[j] = j
+					-- 					end
+					-- 				end
+					-- 				return filters
+					-- 			end
+					-- 		}
+					-- 	}
+					-- }
 				}
 			}
 		}
diff --git a/SVUI_NamePlates/SVUI_NamePlates.lua b/SVUI_NamePlates/SVUI_NamePlates.lua
index 191974b..5669c62 100644
--- a/SVUI_NamePlates/SVUI_NamePlates.lua
+++ b/SVUI_NamePlates/SVUI_NamePlates.lua
@@ -1,8 +1,8 @@
 --[[
 ##############################################################################
-S V U I   By: Failcoder
+S V U I NAMEPLATES   By: joev
 ##############################################################################
-credit: Elv.       NamePlatess was parently nameplates.lua adapted from ElvUI #
+credit: Abu.       NamePlates was adapted from AbuNameplates                 #
 ##############################################################################
 ##########################################################
 LOCALIZED LUA FUNCTIONS
@@ -45,170 +45,1221 @@ local MOD = SV.NamePlates;
 if(not MOD) then return end;

 local LSM = _G.LibStub("LibSharedMedia-3.0")
+
 --[[
 ##########################################################
 LOCAL VARS
 ##########################################################
 ]]--
-local PlateRegistry, VisiblePlates = {}, {};
-local _hook_NamePlateDriverMixin, PlateForge, PlateUpdate;
-local CURRENT_TARGET_NAME;
-local TARGET_CHECKS = 0;
 local PLATE_TOP = MOD.media.topArt;
 local PLATE_BOTTOM = MOD.media.bottomArt;
 local PLATE_RIGHT = MOD.media.rightArt;
 local PLATE_LEFT = MOD.media.leftArt;
-local NPBarTex = [[Interface\BUTTONS\WHITE8X8]];
---[[
-##########################################################
-UTILITY FRAMES
-##########################################################
-]]--
-local NPGrip = _G.SVUI_PlateParentFrame
-local NPGlow = _G.SVUI_PlateGlowFrame
+
+local DriverFrame = CreateFrame('Frame', 'SVUI_Nameplates_DriverFrame', UIParent)
+local UnitFrameMixin = {}
+local UnitBuffMixin = {}
+
+local path= "Interface\\Addons\\SVUI_NamePlates\\assets\\"
+
+local NPUseThreat = false;
+local NPThreatGS = 1;
+local NPThreatBS = 1;
+local NPReactTap = {0.3,0.3,0.3}
+local NPReactNPCGood = {0.31,0.45,0.63}
+local NPReactPlayerGood = {0.29,0.68,0.3}
+local NPReactNeutral = {0.85,0.77,0.36}
+local NPReactEnemy = {0.78,0.25,0.25}
 --[[
 ##########################################################
-PLATE UPDATE HANDLERS
+COLORING THREAT/REACTIONS
 ##########################################################
 ]]--
-function _hook_NamePlateDriverMixin(self, event, ...)
-	if event == "NAME_PLATE_CREATED" then
-		local frame = ...;
-		if(not PlateRegistry[frame]) then
-			PlateForge(frame)
+local CONFIG_THREAT_HOSTILE = { {0.29,0.68,0.3}, {0.85,0.77,0.36}, {0.94,0.6,0.06}, {0.78,0.25,0.25} };
+local CONFIG_THREAT_SCALE = { 1,1,1,1 };
+local PLATE_CLASS_COLORS = {};
+
+do
+	for classToken, colorData in pairs(RAID_CLASS_COLORS) do
+			PLATE_CLASS_COLORS[classToken] = {colorData.r, colorData.g, colorData.b}
+	end
+end
+
+local REACTION_COLORING = {
+	-- (1) PLAYER
+	function(token)
+		if(not token) then
+			return NPReactPlayerGood,NPThreatGS
 		else
-			PlateUpdate(frame)
+			return PLATE_CLASS_COLORS[token],NPThreatGS
 		end
-	elseif event == "NAME_PLATE_UNIT_ADDED" then
-		local namePlateUnitToken = ...;
-		local frame = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken);
-		if(not PlateRegistry[frame]) then
-			PlateForge(frame)
+	end,
+	-- (2) TAPPED
+	function() return NPReactTap,NPThreatGS end,
+	-- (3) FRIENDLY
+	function() return NPReactNPCGood,NPThreatGS end,
+	-- (4) NEUTRAL
+	function(threatLevel)
+		local color,scale;
+		if((not threatLevel) or (not NPUseThreat) or (not InCombatLockdown())) then
+			color = NPReactNeutral
+			scale = NPThreatGS
+		else
+			color = CONFIG_THREAT_HOSTILE[threatLevel]
+			scale = CONFIG_THREAT_SCALE[threatLevel]
+		end
+		return color,scale
+	end,
+	-- (5) HOSTILE
+	function(threatLevel)
+		local color,scale;
+		if((not threatLevel) or (not NPUseThreat) or (not InCombatLockdown())) then
+			color = NPReactEnemy
+			scale = NPThreatGS
+		else
+			color = CONFIG_THREAT_HOSTILE[threatLevel]
+			scale = CONFIG_THREAT_SCALE[threatLevel]
+		end
+		return color,scale
+	end,
+};
+
+
+local config = {
+	Colors = {
+		Frame 	= { 0, 0, 0 },
+		Border   = { 0.5, 0.5, 0.4 },
+		Interrupt = { 0.5, 0.5, 0.4 },
+	},
+
+	IconTextures = {
+		White = path..'Border\\textureWhite',
+		Normal = path..'Border\\textureNormal',
+		Shadow = path..'Border\\textureShadow',
+	},
+
+	-- Nameplates
+	StatusbarTexture = SV.media.statusbar.default,
+	Font = SV.media.font.default,
+	FontSize = 10,
+
+	SuperStyled = false,
+
+	CombatHide = false,
+
+	friendlyConfig = {
+		useClassColors = false,
+		displaySelectionHighlight = true,
+		colorHealthBySelection = true,
+		considerSelectionInCombatAsHostile = true,
+		displayNameByPlayerNameRules = true,
+		colorHealthByRaidIcon = true,
+		displayName = true,
+		filter = "NONE",
+
+		castBarHeight = 8,
+		healthBarHeight = 4*2,
+
+		displayAggroHighlight = false,
+		displaySelectionHighlight = true,
+		--fadeOutOfRange = false,
+		--displayStatusText = true,
+		displayHealPrediction = true,
+		--displayDispelDebuffs = true,
+		colorNameBySelection = true,
+		colorNameWithExtendedColors = true,
+		colorHealthWithExtendedColors = true,
+		colorHealthBySelection = true,
+		considerSelectionInCombatAsHostile = true,
+		--smoothHealthUpdates = false,
+		displayNameWhenSelected = true,
+		displayNameByPlayerNameRules = true,
+	},
+
+	enemyConfig = {
+		useClassColors = true,
+		displayAggroHighlight = true,
+		--playLoseAggroHighlight = true,
+		displaySelectionHighlight = true,
+		colorHealthBySelection = true,
+		considerSelectionInCombatAsHostile = true,
+		displayNameByPlayerNameRules = true,
+		colorHealthByRaidIcon = true,
+		tankBorderColor = true,
+		castBarHeight = 8,
+		healthBarHeight = 4*2,
+		filter = "HARMFUL|INCLUDE_NAME_PLATE_ONLY",
+		displayName = true,
+		--fadeOutOfRange = false,
+		displayHealPrediction = true,
+		colorNameBySelection = true,
+		--smoothHealthUpdates = false,
+		displayNameWhenSelected = true,
+		greyOutWhenTapDenied = true,
+		--showClassificationIndicator = true,
+	},
+
+	playerConfig = {
+		displayHealPrediction = true,
+		filter = "HELPFUL",
+		useClassColors = true,
+		hideCastbar = true,
+		healthBarHeight = 4*2,
+		manaBarHeight = 4*2,
+
+		displaySelectionHighlight = false,
+		displayAggroHighlight = false,
+		displayName = false,
+		fadeOutOfRange = false,
+		colorNameBySelection = true,
+		smoothHealthUpdates = false,
+		displayNameWhenSelected = false,
+	},
+}
+
+MOD.config = config
+MOD.DriverFrame = DriverFrame
+MOD.UnitFrameMixin = UnitFrameMixin
+
+local BorderTex = path..'Border\\Plate.blp'
+local BorderTexGlow = path..'Border\\PlateGlow.blp'
+local MarkTex = path..'Border\\Mark.blp'
+local HighlightTex = path..'Border\\Highlight.blp'
+
+
+local TexCoord 		= {24/256, 186/256, 35/128, 59/128}
+local CbTexCoord 	= {24/256, 186/256, 59/128, 35/128}
+
+local GlowTexCoord 	= {15/256, 195/256, 21/128, 73/128}
+local CbGlowTexCoord= {15/256, 195/256, 73/128, 21/128}
+
+local HiTexCoord 	= {5/128, 105/128, 20/32, 26/32}
+
+local raidIconColor = {
+	[1] = {r = 1.0,  g = 0.92, b = 0,     },
+	[2] = {r = 0.98, g = 0.57, b = 0,     },
+	[3] = {r = 0.83, g = 0.22, b = 0.9,   },
+	[4] = {r = 0.04, g = 0.95, b = 0,     },
+	[5] = {r = 0.7,  g = 0.82, b = 0.875, },
+	[6] = {r = 0,    g = 0.71, b = 1,     },
+	[7] = {r = 1.0,  g = 0.24, b = 0.168, },
+	[8] = {r = 0.98, g = 0.98, b = 0.98,  },
+}
+
+local Backdrop = {
+	bgFile = 'Interface\\Buttons\\WHITE8x8',
+}
+
+local NPComboColor={
+	[1]={0.69,0.31,0.31},
+	[2]={0.69,0.31,0.31},
+	[3]={0.65,0.63,0.35},
+	[4]={0.65,0.63,0.35},
+	[5]={0.33,0.59,0.33},
+	[6]={0.22,0.79,0.22},
+	[7]={0.11,0.99,0.11},
+	[8]={0.11,0.99,0.11}
+}
+
+
+--------
+-- Utils
+--------
+
+function MOD.GetPlateThreatReaction(plate)
+	if plate.aggroHighlight:IsShown() then
+		local r, g, b = plate.aggroHighlight:GetVertexColor()
+		local lastThreat = plate.reaction or 1
+		if g + b < 1 then
+			plate.reaction = 4
+			return 4
 		else
-			PlateUpdate(frame)
+			if lastThreat > 2 then
+				plate.reaction = 2
+				return 2
+			elseif lastThreat < 3 then
+				plate.reaction = 3
+				return 3
+			end
 		end
-	elseif event == "NAME_PLATE_UNIT_REMOVED" then
-		local namePlateUnitToken = ...;
-		local frame = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken);
-		PlateUpdate(frame)
-	elseif event == "PLAYER_TARGET_CHANGED" then
-		-- DO STUFF
-	elseif event == "DISPLAY_SIZE_CHANGED" then
-		-- DO STUFF
-	elseif event == "RAID_TARGET_UPDATE" then
-		-- DO STUFF
-	elseif ( event == "UNIT_FACTION" ) then
-		-- DO STUFF
 	end
+	plate.reaction = 1
+	return 1
 end

-function PlateUpdate(source)
-	local plate = source.UnitFrame;
-	if(not plate) then return end;
-	plate.healthBar:SetStatusBarTexture(NPBarTex)
-	plate.castBar:SetStatusBarTexture(NPBarTex)
-	plate.name:SetFontObject(SVUI_Font_NamePlate)
-	plate.name:SetTextColor(1, 1, 1)
+function MOD.GetPlateReaction(plate)
+	if plate.unit ~= nil then
+		local class, classToken, _, _, _, _, _ = GetPlayerInfoByGUID(UnitGUID(plate.unit))
+		if RAID_CLASS_COLORS[classToken] then
+			return REACTION_COLORING[1](classToken)
+		end
+	end
+
+	local oldR,oldG,oldB = plate.healthBar:GetStatusBarColor()
+	local r = floor(oldR * 100 + .5) * 0.01;
+	local g = floor(oldG * 100 + .5) * 0.01;
+	local b = floor(oldB * 100 + .5) * 0.01;
+	--print(plate.health:GetStatusBarColor())
+	for classToken, _ in pairs(RAID_CLASS_COLORS) do
+		local bb = b
+		if classToken == 'MONK' then
+			bb = bb - 0.01
+		end
+		if RAID_CLASS_COLORS[classToken].r == r and RAID_CLASS_COLORS[classToken].g == g and RAID_CLASS_COLORS[classToken].b == bb then
+			return REACTION_COLORING[1](classToken)
+		end
+	end
+
+	if(r + b < 0.25) then
+		return REACTION_COLORING[3]()
+	else
+		local threatReaction = MOD.GetPlateThreatReaction(plate)
+		if(r + g > 1.8) then
+			return REACTION_COLORING[4](threatReaction)
+		elseif(g + b < 0.25) then
+			return REACTION_COLORING[5](threatReaction)
+		elseif((r > 0.45 and r < 0.55) and (g > 0.45 and g < 0.55) and (b > 0.45 and b < 0.55)) then
+			REACTION_COLORING[2]()
+		else
+			REACTION_COLORING[1]()
+		end
+	end
 end

-function PlateForge(source)
-	local plate = source.UnitFrame;
-	if(not plate) then return end;
+function MOD.Colorize(plate)

-	plate.healthBar:SetStyle("Frame", "Bar")
-	plate.castBar:SetStyle("Frame", 'Bar')
+	local latestColor, scale = MOD.GetPlateReaction(plate);
+	local r,g,b
+	if(latestColor) then
+		r,g,b = unpack(latestColor)
+	else
+		r,g,b = plate.healthBar:GetStatusBarColor()
+	end
+	plate.healthBar:SetStatusBarColor(r,g,b)
+end
+
+function MOD.IsPlayerEffectivelyTank()
+	local assignedRole = UnitGroupRolesAssigned("player");
+	if ( assignedRole == "NONE" ) then
+		local spec = GetSpecialization();
+		return spec and GetSpecializationRole(spec) == "TANK";
+	end

-	VisiblePlates[plate] = true
-	PlateRegistry[source] = true;
-	PlateUpdate(source)
+	return assignedRole == "TANK";
 end
---[[
-##########################################################
-EVENTS
-##########################################################
-]]--
-function MOD:PLAYER_REGEN_DISABLED()
-	SetCVar("nameplateShowEnemies", 1)
+
+local scanner = CreateFrame("GameTooltip", "SVUI_NameplatesScanner", nil, "GameTooltipTemplate")
+local questtipLine = setmetatable({}, { __index = function(k, i)
+	local line = _G["SVUI_NameplatesScannerTextLeft" .. i]
+	if line then rawset(k, i, line) end
+	return line
+end })
+
+function MOD.IsEliteUnit(namePlateUnitToken)
+	local isElite = false
+	if not UnitIsUnit('player', namePlateUnitToken) and not UnitIsFriend('player', namePlateUnitToken) then
+		if 	(UnitClassification(namePlateUnitToken) == "worldboss" or UnitLevel(namePlateUnitToken) == -1 or
+			UnitClassification(namePlateUnitToken) == "rare" or UnitClassification(namePlateUnitToken) =="rareelite" or
+			UnitClassification(namePlateUnitToken) == "elite") then
+			isElite = true
+		end
+	end
+	return isElite
 end

-function MOD:PLAYER_REGEN_ENABLED()
-	SetCVar("nameplateShowEnemies", 0)
+function MOD.GetUnitQuestInfo(namePlateUnitToken)
+	if not namePlateUnitToken or UnitIsPlayer(namePlateUnitToken) then
+		return false
+	end
+
+	local is_quest
+	local num_left = 0
+
+	scanner:SetOwner(UIParent, "ANCHOR_NONE")
+	scanner:SetUnit(namePlateUnitToken)
+
+	for i = 3, scanner:NumLines() do
+		local str = questtipLine[i]
+		if (not str) then break; end
+		local r,g,b = str:GetTextColor()
+		if (r > .99) and (g > .82) and (g < .83) and (b < .01) then -- quest title (yellow)
+			is_quest = true
+		else
+			local done, total = str:GetText():match('(%d+)/(%d+)')  -- kill objective
+			if (done and total) then
+				local left = total - done
+				if (left > num_left) then
+					num_left = left
+				end
+			end
+		end
+	end
+	return is_quest, num_left
 end

-function MOD:PLAYER_TARGET_CHANGED()
-	-- NPGlow:Hide()
-	-- if(NPGlow.FX:IsShown()) then
-	-- 	NPGlow.FX:Hide()
-	-- end
-	if(UnitExists("target")) then
-		CURRENT_TARGET_NAME = UnitName("target");
-		TARGET_CHECKS = 1;
+function MOD.CreatePlateBorder(plate)
+
+	plate.bordertop = plate:CreateTexture(nil, "BORDER")
+	plate.bordertop:SetPoint("TOPLEFT", plate, "TOPLEFT", -2, 2)
+	plate.bordertop:SetPoint("TOPRIGHT", plate, "TOPRIGHT", 2, 2)
+	plate.bordertop:SetHeight(2)
+	plate.bordertop:SetColorTexture(0,0,0)
+	plate.bordertop:SetDrawLayer("BORDER", 1)
+
+	plate.borderbottom = plate:CreateTexture(nil, "BORDER")
+	plate.borderbottom:SetPoint("BOTTOMLEFT", plate, "BOTTOMLEFT", -2, -2)
+	plate.borderbottom:SetPoint("BOTTOMRIGHT", plate, "BOTTOMRIGHT", 2, -2)
+	plate.borderbottom:SetHeight(2)
+	plate.borderbottom:SetColorTexture(0,0,0)
+	plate.borderbottom:SetDrawLayer("BORDER", 1)
+
+	plate.borderleft = plate:CreateTexture(nil, "BORDER")
+	plate.borderleft:SetPoint("TOPLEFT", plate, "TOPLEFT", -2, 2)
+	plate.borderleft:SetPoint("BOTTOMLEFT", plate, "BOTTOMLEFT", 2, -2)
+	plate.borderleft:SetWidth(2)
+	plate.borderleft:SetColorTexture(0,0,0)
+	plate.borderleft:SetDrawLayer("BORDER", 1)
+
+	plate.borderright = plate:CreateTexture(nil, "BORDER")
+	plate.borderright:SetPoint("TOPRIGHT", plate, "TOPRIGHT", 2, 2)
+	plate.borderright:SetPoint("BOTTOMRIGHT", plate, "BOTTOMRIGHT", -2, -2)
+	plate.borderright:SetWidth(2)
+	plate.borderright:SetColorTexture(0,0,0)
+	plate.borderright:SetDrawLayer("BORDER", 1)
+
+	if(not plate.eliteborder) then
+		plate.eliteborder = CreateFrame("Frame", nil, plate)
+		plate.eliteborder:SetAllPoints(plate)
+		plate.eliteborder:SetFrameStrata("BACKGROUND")
+		plate.eliteborder:SetFrameLevel(0)
+
+		plate.eliteborder.top = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.top:SetPoint("BOTTOMLEFT", plate.eliteborder, "TOPLEFT", 0, 0)
+		plate.eliteborder.top:SetPoint("BOTTOMRIGHT", plate.eliteborder, "TOPRIGHT", 0, 0)
+		plate.eliteborder.top:SetHeight(22)
+		plate.eliteborder.top:SetTexture(PLATE_TOP)
+		plate.eliteborder.top:SetVertexColor(1, 1, 0)
+		plate.eliteborder.top:SetBlendMode("BLEND")
+
+		plate.eliteborder.bottom = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.bottom:SetPoint("TOPLEFT", plate.eliteborder, "BOTTOMLEFT", 0, 0)
+		plate.eliteborder.bottom:SetPoint("TOPRIGHT", plate.eliteborder, "BOTTOMRIGHT", 0, 0)
+		plate.eliteborder.bottom:SetHeight(32)
+		plate.eliteborder.bottom:SetTexture(PLATE_BOTTOM)
+		plate.eliteborder.bottom:SetVertexColor(1, 1, 0)
+		plate.eliteborder.bottom:SetBlendMode("BLEND")
+
+		plate.eliteborder.right = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.right:SetPoint("TOPLEFT", plate.eliteborder, "TOPRIGHT", 0, 0)
+		plate.eliteborder.right:SetPoint("BOTTOMLEFT", plate.eliteborder, "BOTTOMRIGHT", 0, 0)
+		plate.eliteborder.right:SetWidth(plate:GetHeight() * 4)
+		plate.eliteborder.right:SetTexture(PLATE_RIGHT)
+		plate.eliteborder.right:SetVertexColor(1, 1, 0)
+		plate.eliteborder.right:SetBlendMode("BLEND")
+
+		plate.eliteborder.left = plate.eliteborder:CreateTexture(nil, "BACKGROUND")
+		plate.eliteborder.left:SetPoint("TOPRIGHT", plate.eliteborder, "TOPLEFT", 0, 0)
+		plate.eliteborder.left:SetPoint("BOTTOMRIGHT", plate.eliteborder, "BOTTOMLEFT", 0, 0)
+		plate.eliteborder.left:SetWidth(plate:GetHeight() * 4)
+		plate.eliteborder.left:SetTexture(PLATE_LEFT)
+		plate.eliteborder.left:SetVertexColor(1, 1, 0)
+		plate.eliteborder.left:SetBlendMode("BLEND")
+
+		plate.eliteborder:SetAlpha(0.35)
+
+		plate.eliteborder:Hide()
+	end
+
+end
+
+
+function MOD:ComboToggle()
+	if(config.ComboPoints) then
+		config.ComboPoints = false
+		SetCVar("nameplateResourceOnTarget", 0)
 	else
-		CURRENT_TARGET_NAME = nil;
-		TARGET_CHECKS = 0;
+		config.ComboPoints = true
+		SetCVar("nameplateResourceOnTarget", 1)
 	end
+	DriverFrame:UpdateComboPointsBar()
 end
---[[
-##########################################################
-UPDATE AND BUILD
-##########################################################
-]]--
+
+function MOD:CombatToggle()
+	if(config.CombatHide) then
+		config.CombatHide = false
+		SetCVar("nameplateShowEnemies", 0)
+	else
+		config.CombatHide = true
+		SetCVar("nameplateShowEnemies", 1)
+	end
+end
+
+function MOD:UpdateAllPlates()
+	self:UpdateLocals()
+	DriverFrame:UpdateNamePlateOptions()
+end
+
 function MOD:UpdateLocals()
 	local db = SV.db.NamePlates
 	if not db then return end

-	NPBarTex = LSM:Fetch("statusbar", db.barTexture);
+	config.StatusbarTexture = LSM:Fetch("statusbar", db.barTexture);
+
+	config.CombatHide = db.combatHide;
+	config.ComboPoimts = db.comboPoints;
+
+	config.SuperStyled = db.themed;
+
+	config.friendlyConfig.healthBarHeight = db.healthBar.height;
+	config.enemyConfig.healthBarHeight = db.healthBar.height;
+	config.playerConfig.healthBarHeight = db.healthBar.height;
+
+
+	config.friendlyConfig.castBarHeight = db.castBar.height;
+	config.enemyConfig.castBarHeight = db.castBar.height;
+	config.playerConfig.manaBarHeight = db.castBar.height;
+
+end
+
+function MOD:Load()
+	self:UpdateLocals();
+	DriverFrame:SetScript('OnEvent', DriverFrame.OnEvent)
+	DriverFrame:RegisterEvent'PLAYER_ENTERING_WORLD'
+end
+-------
+--  DriverFrame
+------
+
+function DriverFrame:OnEvent(event, ...)
+
+	if event == 'PLAYER_ENTERING_WORLD' then
+		self:OnLoad();
+	elseif (event == 'NAME_PLATE_CREATED') then
+		local namePlateFrameBase = ...
+		self:OnNamePlateCreated(namePlateFrameBase)
+	elseif (event == 'NAME_PLATE_UNIT_ADDED') then
+		local namePlateUnitToken = ...
+		self:OnNamePlateAdded(namePlateUnitToken)
+	elseif (event == 'NAME_PLATE_UNIT_REMOVED') then
+		local namePlateUnitToken = ...
+		self:OnNamePlateRemoved(namePlateUnitToken)
+	elseif event == 'PLAYER_TARGET_CHANGED' then
+		self:OnTargetChanged();
+	elseif event == 'DISPLAY_SIZE_CHANGED' then -- resolution change
+		self:UpdateNamePlateOptions()
+	elseif event == "CVAR_UPDATE" then
+		local name = ...;
+		if name == "SHOW_CLASS_COLOR_IN_V_KEY" or name == "SHOW_NAMEPLATE_LOSE_AGGRO_FLASH" then
+			self:UpdateNamePlateOptions();
+		end
+	elseif event == 'UPDATE_MOUSEOVER_UNIT' then
+		self:UpdateMouseOver()
+	elseif event == 'UNIT_FACTION' then
+		self:OnUnitFactionChanged(...)
+	elseif event == 'RAID_TARGET_UPDATE' then
+		self:OnRaidTargetUpdate()
+	elseif event == 'QUEST_LOG_UPDATE' then
+		self:OnQuestLogUpdate()
+	end
+end
+
+function DriverFrame:DisableBlizzard()
+	NamePlateDriverFrame:UnregisterAllEvents()
+	NamePlateDriverFrame:Hide()
+
+	NamePlateDriverFrame.UpdateNamePlateOptions = function()
+		DriverFrame:UpdateNamePlateOptions()
+	end
+end
+
+function DriverFrame:OnLoad()
+
+	self:DisableBlizzard()
+
+	self:RegisterEvent'NAME_PLATE_CREATED'
+	self:RegisterEvent'NAME_PLATE_UNIT_ADDED'
+	self:RegisterEvent'NAME_PLATE_UNIT_REMOVED'
+
+	self:RegisterEvent'PLAYER_TARGET_CHANGED'
+
+	self:RegisterEvent'DISPLAY_SIZE_CHANGED' -- Resolution change
+	self:RegisterEvent'CVAR_UPDATE'
+
+	self:RegisterEvent'UPDATE_MOUSEOVER_UNIT'
+	self:RegisterEvent'UNIT_FACTION'
+
+	self:RegisterEvent'RAID_TARGET_UPDATE'
+	self:RegisterEvent'QUEST_LOG_UPDATE'
+	self:UpdateNamePlateOptions();
+
+end
+
+function DriverFrame:UpdateNamePlateOptions()
+	self.baseNamePlateWidth = 110;
+	self.baseNamePlateHeight = 45;
+
+	local namePlateVerticalScale = tonumber(GetCVar("NamePlateVerticalScale"));
+	local horizontalScale = tonumber(GetCVar("NamePlateHorizontalScale"));
+	C_NamePlate.SetNamePlateOtherSize(self.baseNamePlateWidth * horizontalScale, self.baseNamePlateHeight);
+	C_NamePlate.SetNamePlateSelfSize(self.baseNamePlateWidth * horizontalScale, self.baseNamePlateHeight);
+
+
+	for i, frame in ipairs(C_NamePlate.GetNamePlates()) do
+		frame.UnitFrame:ApplyFrameOptions(frame.UnitFrame.unit);
+		frame.UnitFrame:UpdateAllElements()
+	end
+
+	self:UpdateClassResourceBar()
+	self:UpdateManaBar()
+	self:UpdateComboPointsBar()
+end
+
+function DriverFrame:OnNamePlateCreated(nameplate)
+	local f = CreateFrame('Button', nameplate:GetName()..'UnitFrame', nameplate)
+	f:SetAllPoints(nameplate)
+	f:Show()
+	Mixin(f, UnitFrameMixin)
+	f:Create(nameplate)
+	f:EnableMouse(false)
+
+	nameplate.UnitFrame = f
+end
+
+function DriverFrame:OnNamePlateAdded(namePlateUnitToken)
+	local nameplate = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken)
+	nameplate.UnitFrame:ApplyFrameOptions(namePlateUnitToken)
+	nameplate.UnitFrame:OnAdded(namePlateUnitToken)
+	nameplate.UnitFrame:UpdateAllElements()
+
+	self:UpdateClassResourceBar()
+	self:UpdateManaBar()
+	self:UpdateComboPointsBar()
+end
+
+function DriverFrame:OnNamePlateRemoved(namePlateUnitToken)
+	local nameplate = C_NamePlate.GetNamePlateForUnit(namePlateUnitToken)
+	nameplate.UnitFrame:OnAdded(nil)
+end
+
+function DriverFrame:OnTargetChanged()
+	local nameplate = C_NamePlate.GetNamePlateForUnit'target'
+	if nameplate then
+		if nameplate.UnitFrame then nameplate.UnitFrame:OnUnitAuraUpdate() end
+	end
+
+	self:UpdateClassResourceBar()
+	self:UpdateManaBar()
+	self:UpdateComboPointsBar()
+end
+
+function DriverFrame:OnRaidTargetUpdate()
+	for _, frame in pairs(C_NamePlate.GetNamePlates()) do
+		frame.UnitFrame:UpdateRaidTarget()
+		CompactUnitFrame_UpdateHealthColor(frame.UnitFrame)
+	end
+end

-	if(not db.themed) then
-		PLATE_TOP = SV.NoTexture
-		PLATE_BOTTOM = SV.NoTexture
-		PLATE_RIGHT = SV.NoTexture
-		PLATE_LEFT = SV.NoTexture
+function DriverFrame:OnUnitFactionChanged(unit)
+	local nameplate = C_NamePlate.GetNamePlateForUnit(unit);
+	if (nameplate) then
+		CompactUnitFrame_UpdateName(nameplate.UnitFrame);
+		CompactUnitFrame_UpdateHealthColor(nameplate.UnitFrame);
+	end
+end
+
+function DriverFrame:OnQuestLogUpdate()
+	for _, frame in pairs(C_NamePlate.GetNamePlates()) do
+		frame.UnitFrame:UpdateQuestVisuals()
+	end
+end
+
+local mouseoverframe -- if theres a better way im all ears
+function DriverFrame:OnUpdate(elapsed)
+	local nameplate = C_NamePlate.GetNamePlateForUnit('mouseover')
+	if not nameplate or nameplate ~= mouseoverframe then
+		mouseoverframe.UnitFrame.hoverHighlight:Hide()
+		mouseoverframe = nil
+		self:SetScript('OnUpdate', nil)
+	end
+end
+
+function DriverFrame:UpdateMouseOver()
+	local nameplate = C_NamePlate.GetNamePlateForUnit('mouseover')
+
+	if mouseoverframe == nameplate then
+		return
+	elseif mouseoverframe then
+		mouseoverframe.UnitFrame.hoverHighlight:Hide()
+		self:SetScript('OnUpdate', nil)
+	end
+
+	if nameplate then
+		nameplate.UnitFrame.hoverHighlight:Show()
+		mouseoverframe = nameplate
+		self:SetScript('OnUpdate', self.OnUpdate) --onupdate until mouse leaves frame
+	end
+end
+
+-------------------------
+--	Class Resource bar
+-------------------------
+
+function DriverFrame:UpdateClassResourceBar()
+	local classResourceBar = NamePlateDriverFrame.nameplateBar;
+	if ( not classResourceBar ) then
+		return;
+	end
+	classResourceBar:Hide();
+
+	local showSelf = GetCVar("nameplateShowSelf");
+	if ( showSelf == "0" ) then
+		return;
+	end
+
+	local targetMode = GetCVarBool("nameplateResourceOnTarget");
+	if (classResourceBar.overrideTargetMode ~= nil) then
+		targetMode = classResourceBar.overrideTargetMode;
+	end
+
+	if ( targetMode ) then
+		local namePlateTarget = C_NamePlate.GetNamePlateForUnit("target");
+		if ( namePlateTarget ) then
+			classResourceBar:SetParent(NamePlateTargetResourceFrame);
+			NamePlateTargetResourceFrame:SetParent(namePlateTarget.UnitFrame);
+			NamePlateTargetResourceFrame:ClearAllPoints();
+			NamePlateTargetResourceFrame:SetPoint("BOTTOM", namePlateTarget.UnitFrame.name, "TOP", 0, 9);
+			classResourceBar:Show();
+		end
+		NamePlateTargetResourceFrame:SetShown(namePlateTarget ~= nil);
+	elseif ( not targetMode ) then
+		local namePlatePlayer = C_NamePlate.GetNamePlateForUnit("player");
+		if ( namePlatePlayer ) then
+			classResourceBar:SetParent(NamePlatePlayerResourceFrame);
+			NamePlatePlayerResourceFrame:SetParent(namePlatePlayer.UnitFrame);
+			NamePlatePlayerResourceFrame:ClearAllPoints();
+			--NamePlatePlayerResourceFrame:SetPoint("TOP",ClassNameplateManaBarFrame, "BOTTOM", 0, -3);
+			classResourceBar:Show();
+		end
+		NamePlatePlayerResourceFrame:SetShown(namePlatePlayer ~= nil);
+	end
+end
+
+-------------------------
+--	Class Mana Bar
+-------------------------
+
+local manabar = ClassNameplateManaBarFrame
+manabar:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+manabar:SetBackdrop(Backdrop)
+manabar:SetBackdropColor(0, 0, 0, .8)
+manabar.Border:Hide()
+
+manabar.FeedbackFrame.BarTexture:SetTexture(config.StatusbarTexture)
+
+manabar.border = manabar:CreateTexture(nil, 'ARTWORK', nil, 2)
+-- manabar.border:SetTexture(BorderTex)
+-- manabar.border:SetTexCoord(unpack(TexCoord))
+MOD.CreatePlateBorder(manabar)
+manabar.border:SetPoint('TOPLEFT', manabar, -4, 6)
+manabar.border:SetPoint('BOTTOMRIGHT', manabar, 4, -6)
+manabar.border:SetVertexColor(unpack(config.Colors.Frame))
+manabar:SetFrameLevel(90)
+
+function ClassNameplateManaBarFrame:OnOptionsUpdated()
+	local width, height = C_NamePlate.GetNamePlateSelfSize();
+	self:SetHeight(config.playerConfig.manaBarHeight);
+	self:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+end
+
+
+-------------------------
+--	Class ComboPoints Bar
+-------------------------
+local comboBar = nil
+
+local _, myclass = UnitClass("player")
+if (myclass == "ROGUE" or myclass=="DRUID") then
+	comboBar=ClassNameplateBarRogueDruidFrame
+	comboBar:SetSize(68, 1)
+	comboBar:SetFrameStrata("HIGH")
+	comboBar:SetFrameLevel(50) -- Make sure it's always on top, even over castBar...
+
+	for i = 1, #comboBar.ComboPoints do
+		comboBar.ComboPoints[i].Background:SetTexture(nil)
+		comboBar.ComboPoints[i].Point:SetTexture(MOD.media.comboIcon)
+		comboBar.ComboPoints[i].Point:SetSize(12, 12)
+		comboBar.ComboPoints[i].Point:SetVertexColor(unpack(NPComboColor[i]))
+		comboBar.ComboPoints[i]:SetFrameLevel(49)
+	end
+end
+
+function DriverFrame:UpdateComboPointsBar()
+	if ( not comboBar ) then
+		return;
+	end
+
+	local targetMode = GetCVarBool("nameplateResourceOnTarget");
+
+	local showSelf = GetCVar("nameplateShowSelf");
+	if (not targetMode and showSelf == "0") then
+		return;
+	end
+	local h = nil
+	if ( targetMode ) then
+		local namePlateTarget = C_NamePlate.GetNamePlateForUnit("target");
+		if ( namePlateTarget ) then
+			h = namePlateTarget.UnitFrame.healthBar;
+		end
+	elseif ( not targetMode ) then
+		local namePlatePlayer = C_NamePlate.GetNamePlateForUnit("player");
+		if ( namePlatePlayer ) then
+			h = namePlatePlayer.UnitFrame.healthBar;
+		end
+	end
+	if (h) then
+		comboBar:ClearAllPoints()
+		comboBar:SetPoint("CENTER", h, "CENTER",0,0)
+		comboBar:SetSize(68, 1)
+		comboBar:SetFrameStrata("HIGH")
+		comboBar:SetFrameLevel(50)
+	end
+end
+
+function DriverFrame:UpdateManaBar()
+	manabar:Hide()
+
+	local showSelf = GetCVar("nameplateShowSelf");
+	if ( showSelf == "0" ) then
+		return;
+	end
+
+	local namePlatePlayer = C_NamePlate.GetNamePlateForUnit("player");
+	if ( namePlatePlayer ) then
+		manabar:SetParent(namePlatePlayer);
+		manabar:ClearAllPoints();
+		manabar:SetPoint("TOPLEFT", namePlatePlayer.UnitFrame.healthBar, "BOTTOMLEFT", 0, -6);
+		manabar:SetPoint("TOPRIGHT", namePlatePlayer.UnitFrame.healthBar, "BOTTOMRIGHT", 0, -6);
+		manabar:Show();
+	end
+end
+
+------------------------
+--	Nameplate
+------------------------
+
+function UnitFrameMixin:Create(unitframe)
+	-- Healthbar
+	local h = CreateFrame('Statusbar', '$parentHealthBar', unitframe)
+	self.healthBar = h
+	h:SetFrameLevel(90)
+    h:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+	h:SetBackdrop(Backdrop)
+	h:SetBackdropColor(0, 0, 0, .8)
+
+	-- 	Healthbar textures --blizzard capital letters policy
+	self.myHealPrediction = h:CreateTexture(nil, 'BORDER', nil, 5)
+	self.myHealPrediction:SetVertexColor(0.0, 0.659, 0.608)
+	self.myHealPrediction:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-BarFill]]
+
+	self.otherHealPrediction = h:CreateTexture(nil, 'ARTWORK', nil, 5)
+	self.otherHealPrediction:SetVertexColor(0.0, 0.659, 0.608)
+	self.otherHealPrediction:SetTexture[[Interface\TargetingFrame\UI-TargetingFrame-BarFill]]
+
+	self.totalAbsorb = h:CreateTexture(nil, 'ARTWORK', nil, 5)
+	self.totalAbsorb:SetTexture[[Interface\RaidFrame\Shield-Fill]]
+	--
+	self.totalAbsorbOverlay = h:CreateTexture(nil, 'BORDER', nil, 6)
+	self.totalAbsorbOverlay:SetTexture([[Interface\RaidFrame\Shield-Overlay]], true, true);	--Tile both vertically and horizontally
+	self.totalAbsorbOverlay:SetAllPoints(self.totalAbsorb);
+	self.totalAbsorbOverlay.tileSize = 20;
+	--
+	self.myHealAbsorb = h:CreateTexture(nil, 'ARTWORK', nil, 1)
+	self.myHealAbsorb:SetTexture([[Interface\RaidFrame\Absorb-Fill]], true, true)
+
+	self.myHealAbsorbLeftShadow = h:CreateTexture(nil, 'ARTWORK', nil, 1)
+	self.myHealAbsorbLeftShadow:SetTexture[[Interface\RaidFrame\Absorb-Edge]]
+
+	self.myHealAbsorbRightShadow = h:CreateTexture(nil, 'ARTWORK', nil, 1)
+	self.myHealAbsorbRightShadow:SetTexture[[Interface\RaidFrame\Absorb-Edge]]
+	self.myHealAbsorbRightShadow:SetTexCoord(1, 0, 0, 1)
+	--
+	h.border = h:CreateTexture(nil, 'ARTWORK', nil, 2)
+
+	MOD.CreatePlateBorder(h)
+
+	h.border:SetVertexColor(unpack(config.Colors.Frame))
+
+	self.level = h:CreateFontString(nil, 'OVERLAY',"SVUI_Font_NamePlate_Number")
+	self.level:SetPoint("RIGHT", h, "RIGHT", 2, 0)
+	self.level:SetJustifyH("RIGHT")
+
+	--
+	self.overAbsorbGlow = h:CreateTexture(nil, 'ARTWORK', nil, 3)
+	self.overAbsorbGlow:SetTexture[[Interface\RaidFrame\Shield-Overshield]]
+	self.overAbsorbGlow:SetBlendMode'ADD'
+	self.overAbsorbGlow:SetPoint('BOTTOMLEFT', h, 'BOTTOMRIGHT', -4, -1)
+	self.overAbsorbGlow:SetPoint('TOPLEFT', h, 'TOPRIGHT', -4, 1)
+	self.overAbsorbGlow:SetWidth(8);
+
+	self.overHealAbsorbGlow = h:CreateTexture(nil, 'ARTWORK', nil, 3)
+	self.overHealAbsorbGlow:SetTexture[[Interface\RaidFrame\Absorb-Overabsorb]]
+	self.overHealAbsorbGlow:SetBlendMode'ADD'
+	self.overHealAbsorbGlow:SetPoint('BOTTOMRIGHT', h, 'BOTTOMLEFT', 2, -1)
+	self.overHealAbsorbGlow:SetPoint('TOPRIGHT', h, 'TOPLEFT', 2, 1)
+	self.overHealAbsorbGlow:SetWidth(8);
+
+	-- Castbar
+	local c = CreateFrame('StatusBar', '$parentCastBar', nameplate)
+	do
+		self.castBar = c
+		c:SetFrameLevel(90)
+		c:Hide()
+		c:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+		c:SetBackdrop(Backdrop)
+		c:SetBackdropColor(0, 0, 0, .5)
+
+		--		Castbar textures
+		c.border = c:CreateTexture(nil, 'ARTWORK', nil, 0)
+		--c.border:SetTexCoord(unpack(CbTexCoord))
+		-- c.border:SetTexture(BorderTex)
+		-- c.border:SetPoint('TOPLEFT', c, -4, 6)
+		-- c.border:SetPoint('BOTTOMRIGHT', c, 4, -6)
+		MOD.CreatePlateBorder(c)
+		c.border:SetVertexColor(unpack(config.Colors.Frame))
+
+		c.BorderShield = c:CreateTexture(nil, 'ARTWORK', nil, 1)
+		c.BorderShield:SetTexture(MarkTex)
+		c.BorderShield:SetTexCoord(unpack(CbTexCoord))
+		c.BorderShield:SetAllPoints(c.border)
+		c.BorderShield:SetBlendMode'ADD'
+		c.BorderShield:SetVertexColor(1, .9, 0, 0.7)
+		CastingBarFrame_AddWidgetForFade(c, c.BorderShield)
+
+		c.Text = c:CreateFontString(nil, 'OVERLAY', "SVUI_Font_NamePlate")
+		c.Text:SetPoint('CENTER', c, 0, 0)
+		c.Text:SetPoint('LEFT', c, 0, 0)
+		c.Text:SetPoint('RIGHT', c, 0, 0)
+		--c.Text:SetFont(config.Font, config.FontSize, 'THINOUTLINE')
+		c.Text:SetShadowColor(0, 0, 0, 0)
+
+		c.Icon = c:CreateTexture(nil, 'OVERLAY', nil, 1)
+		c.Icon:SetTexCoord(.1, .9, .1, .9)
+		c.Icon:SetPoint('BOTTOMRIGHT', c, 'BOTTOMLEFT', -7, 0)
+		c.Icon:SetPoint('TOPRIGHT', h, 'TOPLEFT', -7, 0)
+		CastingBarFrame_AddWidgetForFade(c, c.Icon)
+
+		c.IconBorder = c:CreateTexture(nil, 'OVERLAY', nil, 2)
+		c.IconBorder:SetTexture(config.IconTextures.Normal)
+		c.IconBorder:SetVertexColor(unpack(config.Colors.Border))
+		c.IconBorder:SetPoint('TOPRIGHT', c.Icon, 2, 2)
+		c.IconBorder:SetPoint('BOTTOMLEFT', c.Icon, -2, -2)
+		CastingBarFrame_AddWidgetForFade(c, c.IconBorder)
+
+		c.Spark = c:CreateTexture(nil, 'OVERLAY', nil, 2)
+		c.Spark:SetTexture[[Interface\CastingBar\UI-CastingBar-Spark]]
+		c.Spark:SetBlendMode'ADD'
+		c.Spark:SetSize(16,16)
+		c.Spark:SetPoint('CENTER', c, 0, 0)
+
+		c.Flash = c:CreateTexture(nil, 'OVERLAY', nil, 2)
+		c.Flash:SetTexture(config.StatusbarTexture)
+		c.Flash:SetBlendMode'ADD'
+
+		c:SetScript('OnEvent', CastingBarFrame_OnEvent)
+		c:SetScript('OnUpdate',CastingBarFrame_OnUpdate)
+		c:SetScript('OnShow', CastingBarFrame_OnShow)
+		CastingBarFrame_OnLoad(c, nil, false, true);
+		--CastingBarFrame_SetNonInterruptibleCastColor(c, 0.7, 0.7, 0.7)
+	end
+
+	self.raidTargetIcon = h:CreateTexture(nil, 'OVERLAY', nil)
+	self.raidTargetIcon:SetSize(18,18)
+	self.raidTargetIcon:SetPoint('LEFT', h, 'RIGHT', 4, 1)
+	self.raidTargetIcon:SetTexture[[Interface\TargetingFrame\UI-RaidTargetingIcons]]
+
+	self.name = h:CreateFontString(nil, 'ARTWORK', "SVUI_Font_NamePlate")
+	self.name:SetPoint('BOTTOM', h, 'TOP', 0, 4)
+	self.name:SetWordWrap(false)
+	self.name:SetJustifyH'CENTER'
+	--self.name:SetFont(config.Font, config.FontSize, 'THINOUTLINE')
+
+	self.aggroHighlight = h:CreateTexture(nil, 'BORDER', nil, 4)
+	self.aggroHighlight:SetTexture(BorderTexGlow)
+	self.aggroHighlight:SetTexCoord(unpack(GlowTexCoord))
+	self.aggroHighlight:SetPoint('TOPLEFT', h.border, -7, 15)
+	self.aggroHighlight:SetPoint('BOTTOMRIGHT', h.border, 7, -15)
+	self.aggroHighlight:SetAlpha(.7)
+	self.aggroHighlight:Hide()
+
+	self.hoverHighlight = h:CreateTexture(nil, 'ARTWORK', nil, 1)
+	self.hoverHighlight:SetTexture(HighlightTex)
+	self.hoverHighlight:SetAllPoints(h)
+	self.hoverHighlight:SetVertexColor(1, 1, 1)
+	self.hoverHighlight:SetBlendMode('ADD')
+	self.hoverHighlight:SetTexCoord(unpack(HiTexCoord))
+	self.hoverHighlight:Hide()
+
+	self.selectionHighlight = h:CreateTexture(nil, 'ARTWORK', nil, 4)
+	self.selectionHighlight:SetTexture(MarkTex)
+	self.selectionHighlight:SetTexCoord(unpack(TexCoord))
+	self.selectionHighlight:SetAllPoints(h.border)
+	self.selectionHighlight:SetBlendMode('ADD')
+	self.selectionHighlight:SetVertexColor(.8, .8, 1, .7)
+	self.selectionHighlight:Hide()
+
+	self.BuffFrame = CreateFrame('StatusBar', '$parentBuffFrame', self, 'HorizontalLayoutFrame')
+	Mixin(self.BuffFrame, NameplateBuffContainerMixin)
+	self.BuffFrame:SetPoint('LEFT', self.healthBar, -1, 0)
+	self.BuffFrame.spacing = 4
+	self.BuffFrame.fixedHeight = 14
+	self.BuffFrame:SetScript('OnEvent', self.BuffFrame.OnEvent)
+	self.BuffFrame:SetScript('OnUpdate', self.BuffFrame.OnUpdate)
+	self.BuffFrame:OnLoad()
+
+	-- Quest
+	self.questIcon = self:CreateTexture(nil, nil, nil, 0)
+	self.questIcon:SetSize(12, 12)
+
+	self.questIcon:SetTexture(path..'QUEST-BG-ICON.blp')
+	self.questIcon:SetPoint('LEFT', h, 'RIGHT', 2, 0)
+
+	self.questText = self:CreateFontString(nil, nil, "SVUI_Font_NamePlate_Number")
+	self.questText:SetPoint('CENTER', self.questIcon, 0, 0)
+	self.questText:SetShadowOffset(1, -1)
+	self.questText:SetTextColor(1,.82,0)
+
+
+
+end
+
+function UnitFrameMixin:ApplyFrameOptions(namePlateUnitToken)
+	if UnitIsUnit('player', namePlateUnitToken) then
+		self.optionTable = config.playerConfig
+		self.healthBar:SetPoint('LEFT', self, 'LEFT', 12, 5);
+		self.healthBar:SetPoint('RIGHT', self, 'RIGHT', -12, 5);
+		self.healthBar:SetHeight(self.optionTable.healthBarHeight);
+		self.healthBar.eliteborder:Hide()
 	else
-		PLATE_TOP = self.media.topArt
-		PLATE_BOTTOM = self.media.bottomArt
-		PLATE_RIGHT = self.media.rightArt
-		PLATE_LEFT = self.media.leftArt
+
+		if UnitIsFriend('player', namePlateUnitToken) then
+			self.optionTable = config.friendlyConfig
+		else
+			self.optionTable = config.enemyConfig
+		end
+
+		self.castBar:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 12, 6);
+		self.castBar:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', -12, 6);
+		self.castBar:SetHeight(self.optionTable.castBarHeight);
+		self.castBar.Icon:SetWidth(self.optionTable.castBarHeight + self.optionTable.healthBarHeight + 6)
+
+		self.healthBar:SetPoint('BOTTOMLEFT', self.castBar, 'TOPLEFT', 0, 6);
+		self.healthBar:SetPoint('BOTTOMRIGHT', self.castBar, 'TOPRIGHT', 0, 6);
+		self.healthBar:SetHeight(self.optionTable.healthBarHeight);
 	end
 end

-function MOD:CombatToggle(noToggle)
-	if(NPCombatHide) then
-		self:RegisterEvent("PLAYER_REGEN_DISABLED")
-		self:RegisterEvent("PLAYER_REGEN_ENABLED")
-		if(not noToggle) then
-			SetCVar("nameplateShowEnemies", 0)
+function UnitFrameMixin:OnAdded(namePlateUnitToken)
+	self.unit = namePlateUnitToken
+	self.displayedUnit = namePlateUnitToken
+	self.inVehicle = false;
+
+	if namePlateUnitToken then
+		self:RegisterEvents()
+	else
+		self:UnregisterEvents()
+	end
+
+	if self.castBar then
+		if namePlateUnitToken and (not self.optionTable.hideCastbar) then
+			CastingBarFrame_SetUnit(self.castBar, namePlateUnitToken, false, true);
+		else
+			CastingBarFrame_SetUnit(self.castBar, nil, nil, nil);
+		end
+	end
+end
+
+function UnitFrameMixin:RegisterEvents()
+	self:RegisterEvent'UNIT_NAME_UPDATE'
+	self:RegisterEvent'PLAYER_TARGET_CHANGED'
+
+	self:RegisterEvent'UNIT_ENTERED_VEHICLE'
+	self:RegisterEvent'UNIT_EXITED_VEHICLE'
+	self:RegisterEvent'UNIT_PET'
+
+	self:UpdateUnitEvents();
+	self:SetScript('OnEvent', self.OnEvent);
+end
+
+function UnitFrameMixin:UpdateUnitEvents()
+	local unit = self.unit;
+	local displayedUnit;
+	if ( unit ~= self.displayedUnit ) then
+		displayedUnit = self.displayedUnit;
+	end
+	self:RegisterUnitEvent('UNIT_MAXHEALTH', unit, displayedUnit);
+	self:RegisterUnitEvent('UNIT_HEALTH', unit, displayedUnit);
+	self:RegisterUnitEvent('UNIT_HEALTH_FREQUENT', unit, displayedUnit);
+
+	self:RegisterUnitEvent('UNIT_AURA', unit, displayedUnit);
+	self:RegisterUnitEvent('UNIT_THREAT_SITUATION_UPDATE', unit, displayedUnit);
+	self:RegisterUnitEvent('UNIT_THREAT_LIST_UPDATE', unit, displayedUnit);
+	self:RegisterUnitEvent('UNIT_HEAL_PREDICTION', unit, displayedUnit);
+
+	self:RegisterUnitEvent('UNIT_ABSORB_AMOUNT_CHANGED', unit.displayedUnit);
+	self:RegisterUnitEvent('UNIT_HEAL_ABSORB_AMOUNT_CHANGED', unit.displayedUnit);
+end
+
+function UnitFrameMixin:UnregisterEvents()
+	self:SetScript('OnEvent', nil)
+end
+
+
+function UnitFrameMixin:UpdateAllElements()
+	self:UpdateInVehicle()
+
+	if UnitExists(self.displayedUnit) then
+		CompactUnitFrame_UpdateSelectionHighlight(self)
+		CompactUnitFrame_UpdateMaxHealth(self)
+		CompactUnitFrame_UpdateHealth(self)
+		CompactUnitFrame_UpdateHealPrediction(self)
+
+		self:UpdateRaidTarget()
+		CompactUnitFrame_UpdateHealthColor(self)
+		CompactUnitFrame_UpdateName(self);
+		self:UpdateThreat()
+		self:OnUnitAuraUpdate()
+		self:UpdateQuestVisuals()
+		self:UpdateStatusBar()
+	end
+end
+
+function UnitFrameMixin:OnEvent(event, ...)
+	local arg1, arg2, arg3, arg4 = ...
+	if ( event == 'PLAYER_TARGET_CHANGED' ) then
+		CompactUnitFrame_UpdateSelectionHighlight(self);
+		CompactUnitFrame_UpdateName(self);
+
+	elseif ( arg1 == self.unit or arg1 == self.displayedUnit ) then
+		if ( event == 'UNIT_MAXHEALTH' ) then
+			CompactUnitFrame_UpdateMaxHealth(self)
+			CompactUnitFrame_UpdateHealth(self)
+			CompactUnitFrame_UpdateHealPrediction(self)
+		elseif ( event == 'UNIT_HEALTH' or event == 'UNIT_HEALTH_FREQUENT' ) then
+			CompactUnitFrame_UpdateHealth(self)
+			CompactUnitFrame_UpdateHealPrediction(self)
+		elseif ( event == 'UNIT_NAME_UPDATE' ) then
+			CompactUnitFrame_UpdateName(self)
+			CompactUnitFrame_UpdateHealthColor(self)
+		elseif ( event == 'UNIT_AURA' ) then
+			self:OnUnitAuraUpdate()
+		elseif ( event == 'UNIT_THREAT_SITUATION_UPDATE' ) then
+			self:UpdateThreat()
+			--CompactUnitFrame_UpdateHealthBorder(self)
+		elseif ( event == 'UNIT_THREAT_LIST_UPDATE' ) then
+			if ( self.optionTable.considerSelectionInCombatAsHostile ) then
+				CompactUnitFrame_UpdateHealthColor(self)
+				CompactUnitFrame_UpdateName(self)
+			end
+			self:UpdateThreat()
+		elseif ( event == 'UNIT_HEAL_PREDICTION' or event == 'UNIT_ABSORB_AMOUNT_CHANGED' or event == 'UNIT_HEAL_ABSORB_AMOUNT_CHANGED' ) then
+			CompactUnitFrame_UpdateHealPrediction(self)
+		elseif ( event == 'UNIT_ENTERED_VEHICLE' or event == 'UNIT_EXITED_VEHICLE' or event == 'UNIT_PET' ) then
+			self:UpdateAllElements()
+		end
+	end
+end
+
+function UnitFrameMixin:UpdateInVehicle()
+	if ( UnitHasVehicleUI(self.unit) ) then
+		if ( not self.inVehicle ) then
+			self.inVehicle = true
+			local prefix, id, suffix = string.match(self.unit, '([^%d]+)([%d]*)(.*)')
+			self.displayedUnit = prefix..'pet'..id..suffix
+			self:UpdateUnitEvents()
 		end
 	else
-		self:UnregisterEvent("PLAYER_REGEN_DISABLED")
-		self:UnregisterEvent("PLAYER_REGEN_ENABLED")
-		if(not noToggle) then
-			SetCVar("nameplateShowEnemies", 1)
+		if ( self.inVehicle ) then
+			self.inVehicle = false
+			self.displayedUnit = self.unit
+			self:UpdateUnitEvents()
 		end
 	end
 end

-function MOD:ReLoad()
-	self:UpdateAllPlates();
+function UnitFrameMixin:UpdateRaidTarget()
+	local icon = self.raidTargetIcon;
+	local index = GetRaidTargetIndex(self.unit)
+	if ( index ) then
+		SetRaidTargetIconTexture(icon, index);
+		icon:Show();
+		if self.optionTable.colorHealthByRaidIcon then
+			self.optionTable.healthBarColorOverride = raidIconColor[index]
+		end
+	else
+		self.optionTable.healthBarColorOverride = nil
+		icon:Hide();
+	end
 end

-function MOD:Load()
-	SV:FontManager(SystemFont_NamePlate, "platename")
-	--SV.SpecialFX:Register("platepoint", [[Spells\Arrow_state_animated.m2]], -12, 12, 12, -50, 0.75, 0, 0.1)
-	--SV.SpecialFX:SetFXFrame(NPGlow, "platepoint", true)
-	-- NPGlow.FX:SetParent(SV.Screen)
-	-- NPGlow.FX:SetFrameStrata("BACKGROUND")
-	-- NPGlow.FX:SetFrameLevel(0)
-	-- NPGlow.FX:Hide()
-	self:UpdateLocals()
-	self:RegisterEvent("PLAYER_ENTERING_WORLD")
-	self:RegisterEvent("PLAYER_TARGET_CHANGED")
-	NamePlateDriverFrame:HookScript("OnEvent", _hook_NamePlateDriverMixin)
+function UnitFrameMixin:UpdateThreat()
+	local tex = self.aggroHighlight
+	if not self.optionTable.tankBorderColor then
+		tex:Hide()
+		return
+	end
+
+	local isTanking, status = UnitDetailedThreatSituation('player', self.displayedUnit)
+	if status ~= nil then
+		if MOD.IsPlayerEffectivelyTank() then
+			status = math.abs(status - 3)
+		end
+		if status > 0 then
+			tex:SetVertexColor(GetThreatStatusColor(status))
+			if not tex:IsShown() then
+				tex:Show()
+			end
+			return
+		end
+	end
+	tex:Hide()
+end
+
+function UnitFrameMixin:UpdateStatusBar()
+	self.healthBar:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+	self.castBar:SetStatusBarTexture(config.StatusbarTexture, 'BACKGROUND', 1)
+	if not UnitIsUnit(self.displayedUnit,'player') then
+		self.level:SetText(UnitLevel(self.displayedUnit))
+
+		if config.SuperStyled and MOD.IsEliteUnit(self.displayedUnit) then
+			self.healthBar.eliteborder:Show()
+		else
+			self.healthBar.eliteborder:Hide()
+		end
+		MOD.Colorize(self)
+	else
+		self.level:SetText(nil)
+		self.healthBar.eliteborder:Hide()
+	end
+end

-	if (ClassNameplateManaBarFrame) then
-		ClassNameplateManaBarFrame:SetStyle("Frame", "Bar")
-		ClassNameplateManaBarFrame:SetStatusBarTexture(SV.media.statusbar.glow)
+function UnitFrameMixin:UpdateQuestVisuals()
+	local isQuest, numLeft = MOD.GetUnitQuestInfo(self.displayedUnit)
+	if (isQuest) then
+		if (numLeft > 0) then
+			self.questText:SetText(numLeft)
+		else
+			self.questText:SetText('?')
+		end
+		self.questIcon:Show()
+	else
+		self.questText:SetText(nil)
+		self.questIcon:Hide()
 	end
+end
+
+function UnitFrameMixin:OnUnitAuraUpdate()
+	self.BuffFrame:UpdateBuffs(self.displayedUnit, self.optionTable.filter)
+

-	self:CombatToggle(true)
 end
+
diff --git a/SVUI_NamePlates/SVUI_NamePlates.xml b/SVUI_NamePlates/SVUI_NamePlates.xml
index d3b8e47..2125120 100644
--- a/SVUI_NamePlates/SVUI_NamePlates.xml
+++ b/SVUI_NamePlates/SVUI_NamePlates.xml
@@ -36,7 +36,7 @@
 	<Frame name="SVUI_PlateParentFrame" frameStrata="BACKGROUND" hidden="true">
         <Scripts>
             <OnLoad>
-                self:SetParent(_G['WorldFrame'])
+                -- self:SetParent(_G['WorldFrame'])
             </OnLoad>
         </Scripts>
     </Frame>
@@ -51,7 +51,7 @@
         </Backdrop>
     	<Scripts>
             <OnLoad>
-            	self:SetParent(_G['WorldFrame'])
+            	-- self:SetParent(_G['WorldFrame'])
 				self:SetScale(2.5)
             </OnLoad>
         </Scripts>
diff --git a/SVUI_NamePlates/assets/Border/Highlight.blp b/SVUI_NamePlates/assets/Border/Highlight.blp
new file mode 100644
index 0000000..943bbe6
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/Highlight.blp differ
diff --git a/SVUI_NamePlates/assets/Border/Mark.blp b/SVUI_NamePlates/assets/Border/Mark.blp
new file mode 100644
index 0000000..9f5946e
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/Mark.blp differ
diff --git a/SVUI_NamePlates/assets/Border/Plate.blp b/SVUI_NamePlates/assets/Border/Plate.blp
new file mode 100644
index 0000000..83d0241
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/Plate.blp differ
diff --git a/SVUI_NamePlates/assets/Border/PlateGlow.blp b/SVUI_NamePlates/assets/Border/PlateGlow.blp
new file mode 100644
index 0000000..bfa7378
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/PlateGlow.blp differ
diff --git a/SVUI_NamePlates/assets/Border/textureBackground.tga b/SVUI_NamePlates/assets/Border/textureBackground.tga
new file mode 100644
index 0000000..9223a28
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureBackground.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureChecked.tga b/SVUI_NamePlates/assets/Border/textureChecked.tga
new file mode 100644
index 0000000..8627b8a
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureChecked.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureDebuff.tga b/SVUI_NamePlates/assets/Border/textureDebuff.tga
new file mode 100644
index 0000000..22b7663
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureDebuff.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureHighlight.tga b/SVUI_NamePlates/assets/Border/textureHighlight.tga
new file mode 100644
index 0000000..7ed5614
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureHighlight.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureNormal.tga b/SVUI_NamePlates/assets/Border/textureNormal.tga
new file mode 100644
index 0000000..f3d4b68
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureNormal.tga differ
diff --git a/SVUI_NamePlates/assets/Border/texturePushed.tga b/SVUI_NamePlates/assets/Border/texturePushed.tga
new file mode 100644
index 0000000..531dfae
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/texturePushed.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureShadow.tga b/SVUI_NamePlates/assets/Border/textureShadow.tga
new file mode 100644
index 0000000..582cecc
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureShadow.tga differ
diff --git a/SVUI_NamePlates/assets/Border/textureWhite.tga b/SVUI_NamePlates/assets/Border/textureWhite.tga
new file mode 100644
index 0000000..9166530
Binary files /dev/null and b/SVUI_NamePlates/assets/Border/textureWhite.tga differ
diff --git a/SVUI_NamePlates/assets/QUEST-BG-ICON.blp b/SVUI_NamePlates/assets/QUEST-BG-ICON.blp
new file mode 100644
index 0000000..ff48e9b
Binary files /dev/null and b/SVUI_NamePlates/assets/QUEST-BG-ICON.blp differ
diff --git a/SVUI_QuestTracker/LICENSE.txt b/SVUI_QuestTracker/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_QuestTracker/LICENSE.txt
+++ b/SVUI_QuestTracker/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_QuestTracker/SVUI_QuestTracker.lua b/SVUI_QuestTracker/SVUI_QuestTracker.lua
index 22b0426..c304836 100644
--- a/SVUI_QuestTracker/SVUI_QuestTracker.lua
+++ b/SVUI_QuestTracker/SVUI_QuestTracker.lua
@@ -367,7 +367,7 @@ function MOD:UpdateDimensions()
 		end
 		headerFrame:SetWidth(scrollWidth)
 	end
-
+	if totalHeight < 1 then totalHeight = 1 end
 	MOD.Docklet.ScrollFrame.MaxVal = totalHeight;
 	MOD.Docklet.ScrollFrame.ScrollBar:SetMinMaxValues(1, totalHeight);
 	--MOD.Docklet.ScrollFrame.ScrollBar:SetHeight(scrollHeight);
diff --git a/SVUI_Skins/License.txt b/SVUI_Skins/License.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Skins/License.txt
+++ b/SVUI_Skins/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_Skins/components/blizzard/achievement.lua b/SVUI_Skins/components/blizzard/achievement.lua
index c0e7c6d..1072149 100644
--- a/SVUI_Skins/components/blizzard/achievement.lua
+++ b/SVUI_Skins/components/blizzard/achievement.lua
@@ -141,7 +141,7 @@ local function AchievementStyle()
 		return
 	end

-	AchievementFrameHeader:EnableMouse(false)
+	--AchievementFrameHeader:EnableMouse(false)

 	for _, gName in pairs(AchievementFrameList) do
 		local frame = _G[gName]
@@ -453,6 +453,8 @@ local function AchievementStyle()
 			end
 		end
 	end)
+	--JV - 21060921 - Fix for Non moving frame (mouse was disabled on the frame but never re-enabled)
+	--AchievementFrameHeader:EnableMouse(true)
 end
 --[[
 ##########################################################
diff --git a/SVUI_Skins/components/blizzard/auctionhouse.lua b/SVUI_Skins/components/blizzard/auctionhouse.lua
index 88b758d..d363ff4 100644
--- a/SVUI_Skins/components/blizzard/auctionhouse.lua
+++ b/SVUI_Skins/components/blizzard/auctionhouse.lua
@@ -198,7 +198,7 @@ local function AuctionStyle()
 	hooksecurefunc("FilterButton_SetType", _hook_FilterButton_SetType)

 	for _,field in pairs(AuctionTextFields) do
-		_G[field]:RemoveTextures()
+		--_G[field]:RemoveTextures()
 		_G[field]:SetStyle("Editbox", 2, 2)
 		_G[field]:SetTextInsets(-1, -1, -2, -2)
 	end
diff --git a/SVUI_Skins/components/blizzard/lfd.lua b/SVUI_Skins/components/blizzard/lfd.lua
index 2806caf..d217bc5 100644
--- a/SVUI_Skins/components/blizzard/lfd.lua
+++ b/SVUI_Skins/components/blizzard/lfd.lua
@@ -452,7 +452,7 @@ local function LFDFrameStyle()
       LFRBrowseFrameRefreshButton:SetStyle("Button")
       LFRBrowseFrameInviteButton:SetStyle("Button")
       LFRBrowseFrameSendMessageButton:SetStyle("Button")
-      LFRQueueFrameSpecificListScrollFrame.styled = true
+      LFRQueueFrameSpecificListScrollFrameScrollBar.styled = true
     end
   end)

@@ -520,6 +520,8 @@ local function LFDFrameStyle()

   SV.API:Set("!_EditBox", LFGListFrame.SearchPanel.SearchBox, false, false, -2, -1)
   SV.API:Set("ScrollBar", LFGListSearchPanelScrollFrame)
+  --JV - 21060921 - Fix for Non moving frame (mouse was disabled on the frame but never re-enabled)
+  PVEFrame:EnableMouse(true)
 end
 --[[
 ##########################################################
diff --git a/SVUI_Skins/components/blizzard/misc.lua b/SVUI_Skins/components/blizzard/misc.lua
index 725bb5c..dc4f120 100644
--- a/SVUI_Skins/components/blizzard/misc.lua
+++ b/SVUI_Skins/components/blizzard/misc.lua
@@ -342,11 +342,12 @@ local function MiscStyles()

 		hooksecurefunc("MasterLooterFrame_Show", _hook_MasterLootFrame_OnShow)

-		BonusRollFrame:RemoveTextures()
-		SV.API:Set("Alert", BonusRollFrame)
-		BonusRollFrame.PromptFrame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
-		BonusRollFrame.PromptFrame.Timer.Bar:SetTexture(SV.media.statusbar.default)
-		BonusRollFrame.PromptFrame.Timer.Bar:SetVertexColor(0.1, 1, 0.1)
+		-- JV - 20161002: This is causing BonusRoll Frame not to show. Removed until I can figure out what's going wrong.
+		-- BonusRollFrame:RemoveTextures()
+		-- SV.API:Set("Alert", BonusRollFrame)
+		-- BonusRollFrame.PromptFrame.Icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
+		-- BonusRollFrame.PromptFrame.Timer.Bar:SetTexture(SV.media.statusbar.default)
+		-- BonusRollFrame.PromptFrame.Timer.Bar:SetVertexColor(0.1, 1, 0.1)
 	end

 	if(SV.db.Skins.blizzard.losscontrol) then
diff --git a/SVUI_Skins/components/blizzard/petjournal.lua b/SVUI_Skins/components/blizzard/petjournal.lua
deleted file mode 100644
index d6f0146..0000000
--- a/SVUI_Skins/components/blizzard/petjournal.lua
+++ /dev/null
@@ -1,333 +0,0 @@
---[[
-##############################################################################
-S V U I   By: Failcoder
-##############################################################################
---]]
---[[ GLOBALS ]]--
-local _G = _G;
-local unpack  = _G.unpack;
-local select  = _G.select;
---[[ ADDON ]]--
-local SV = _G['SVUI'];
-local L = SV.L;
-local MOD = SV.Skins;
-local Schema = MOD.Schema;
---[[
-##########################################################
-HELPERS
-##########################################################
-]]--
-local FAV_ICON = SV.media.icon.star
-local NORMAL_COLOR = {r = 1, g = 1, b = 1}
-local SELECTED_COLOR = {r = 1, g = 1, b = 0}
-
-local function PetJournal_UpdateMounts()
-	for b = 1, #MountJournal.ListScrollFrame.buttons do
-		local d = _G["MountJournalListScrollFrameButton"..b]
-		local e = _G["MountJournalListScrollFrameButton"..b.."Name"]
-		if d.selectedTexture:IsShown() then
-			if(e) then e:SetTextColor(1, 1, 0) end
-			if d.Panel then
-				d:SetBackdropBorderColor(1, 1, 0)
-			end
-			if d.IconShadow then
-				d.IconShadow:SetBackdropBorderColor(1, 1, 0)
-			end
-		else
-			if(e) then e:SetTextColor(1, 1, 1) end
-			if d.Panel then
-				d:SetBackdropBorderColor(0,0,0,1)
-			end
-			if d.IconShadow then
-				d.IconShadow:SetBackdropBorderColor(0,0,0,1)
-			end
-		end
-	end
-end
-
-local function PetJournal_UpdatePets()
-	local u = PetJournal.listScroll.buttons;
-	local isWild = PetJournal.isWild;
-	for b = 1, #u do
-		local v = u[b].index;
-		if not v then
-			break
-		end
-		local d = _G["PetJournalListScrollFrameButton"..b]
-		local e = _G["PetJournalListScrollFrameButton"..b.."Name"]
-		local levelText = _G["PetJournalListScrollFrameButton"..b.."Level"]
-		local w, x, y, z, level, favorite, A, B, C, D, E, F, G, H, I = C_PetJournal.GetPetInfoByIndex(v, isWild)
-		if w ~= nil then
-			local J, K, L, M, N = C_PetJournal.GetPetStats(w)
-			local color = NORMAL_COLOR
-			if(N) then
-				color = ITEM_QUALITY_COLORS[N-1]
-			end
-			d:SetBackdropBorderColor(0,0,0,1)
-			if(d.selectedTexture:IsShown() and d.Panel) then
-				d:SetBackdropBorderColor(1,1,0,1)
-				if d.IconShadow then
-					d.IconShadow:SetBackdropBorderColor(1,1,0)
-				end
-			else
-				if d.IconShadow then
-					d.IconShadow:SetBackdropBorderColor(color.r, color.g, color.b)
-				end
-			end
-
-			e:SetTextColor(color.r, color.g, color.b)
-		end
-	end
-end
---[[
-##########################################################
-FRAME MODR
-##########################################################
-]]--
-local function CollectionsJournalStyle()
-	if SV.db.Skins.blizzard.enable ~= true or SV.db.Skins.blizzard.mounts ~= true then return end
-
-	SV.API:Set("Window", CollectionsJournal)
-
-	CollectionsJournalPortrait:Hide()
-	SV.API:Set("Tab", CollectionsJournalTab1)
-	SV.API:Set("Tab", CollectionsJournalTab2)
-	SV.API:Set("CloseButton", CollectionsJournalCloseButton)
-
-	MountJournal:RemoveTextures()
-	MountJournal.LeftInset:RemoveTextures()
-	MountJournal.RightInset:RemoveTextures()
-	MountJournal.MountDisplay:RemoveTextures()
-	MountJournal.MountDisplay.ShadowOverlay:RemoveTextures()
-	MountJournal.MountCount:RemoveTextures()
-	MountJournalListScrollFrame:RemoveTextures()
-	MountJournalMountButton:RemoveTextures()
-	MountJournalMountButton:SetStyle("Button")
-	MountJournalSearchBox:SetStyle("Editbox")
-
-	SV.API:Set("ScrollBar", MountJournalListScrollFrame)
-	MountJournal.MountDisplay:SetStyle("!_Frame", "Model")
-
-	local buttons = MountJournal.ListScrollFrame.buttons
-	for i = 1, #buttons do
-		local button = buttons[i]
-		if(button) then
-			SV.API:Set("ItemButton", button)
-			local bar = _G["SVUI_MountSelectBar"..i]
-			if(bar) then bar:SetParent(button.Panel) end
-			if(button.favorite) then
-				local fg = CreateFrame("Frame", nil, button)
-				fg:SetAllPoints(favorite)
-				fg:SetFrameLevel(button:GetFrameLevel() + 30)
-				button.favorite:SetParent(fg)
-				button.favorite:SetTexture(SV.media.icon.star)
-			end
-		end
-	end
-
-	hooksecurefunc("MountJournal_UpdateMountList", PetJournal_UpdateMounts)
-	MountJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdateMounts)
-	MountJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdateMounts)
-	PetJournalSummonButton:RemoveTextures()
-	PetJournalFindBattle:RemoveTextures()
-	PetJournalSummonButton:SetStyle("Button")
-	PetJournalFindBattle:SetStyle("Button")
-	PetJournalRightInset:RemoveTextures()
-	PetJournalLeftInset:RemoveTextures()
-
-	for i = 1, 3 do
-		local button = _G["PetJournalLoadoutPet" .. i .. "HelpFrame"]
-		button:RemoveTextures()
-	end
-
-	PetJournalTutorialButton:Die()
-	PetJournal.PetCount:RemoveTextures()
-	PetJournalSearchBox:SetStyle("Editbox")
-	PetJournalFilterButton:RemoveTextures(true)
-	PetJournalFilterButton:SetStyle("Button")
-	PetJournalListScrollFrame:RemoveTextures()
-	SV.API:Set("ScrollBar", PetJournalListScrollFrame)
-
-	for i = 1, #PetJournal.listScroll.buttons do
-		local button = _G["PetJournalListScrollFrameButton" .. i]
-		local favorite = _G["PetJournalListScrollFrameButton" .. i .. "Favorite"]
-		SV.API:Set("ItemButton", button)
-		if(not button.Riser) then
-			local fg = CreateFrame("Frame", nil, button)
-			fg:SetAllPoints(button)
-			fg:SetFrameLevel(button:GetFrameLevel() + 30)
-			button.Riser = fg
-		end
-		if(favorite) then
-			favorite:SetParent(button.Riser)
-			button.dragButton.favorite:SetParent(button.Riser)
-			favorite:SetTexture(SV.media.icon.star)
-			favorite:SetTexCoord(0,1,0,1)
-		end
-
-		button.dragButton.levelBG:SetAlpha(0)
-		button.dragButton.level:SetParent(button.Riser)
-		--button.dragButton.level:SetDrawLayer("OVERLAY", 7)
-		button.petTypeIcon:SetParent(button.Panel)
-	end
-
-	hooksecurefunc('PetJournal_UpdatePetList', PetJournal_UpdatePets)
-	PetJournalListScrollFrame:HookScript("OnVerticalScroll", PetJournal_UpdatePets)
-	PetJournalListScrollFrame:HookScript("OnMouseWheel", PetJournal_UpdatePets)
-	PetJournalAchievementStatus:DisableDrawLayer('BACKGROUND')
-	SV.API:Set("!_ItemButton", PetJournalHealPetButton)
-	PetJournalHealPetButton.texture:SetTexture([[Interface\Icons\spell_magic_polymorphrabbit]])
-	PetJournalLoadoutBorder:RemoveTextures()
-
-	for b = 1, 3 do
-		local pjPet = _G['PetJournalLoadoutPet'..b]
-		pjPet:RemoveTextures()
-		pjPet.petTypeIcon:SetPoint('BOTTOMLEFT', 2, 2)
-		pjPet.dragButton:WrapPoints(_G['PetJournalLoadoutPet'..b..'Icon'])
-		pjPet.hover = true;
-		pjPet.pushed = true;
-		pjPet.checked = true;
-		SV.API:Set("ItemButton", pjPet, true)
-		pjPet.setButton:RemoveTextures()
-		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:RemoveTextures()
-		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStyle("Frame", 'Default')
-		_G['PetJournalLoadoutPet'..b..'HealthFrame'].healthBar:SetStatusBarTexture(SV.media.statusbar.default)
-		_G['PetJournalLoadoutPet'..b..'XPBar']:RemoveTextures()
-		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStyle("Frame", 'Default')
-		_G['PetJournalLoadoutPet'..b..'XPBar']:SetStatusBarTexture(SV.media.statusbar.default)
-		_G['PetJournalLoadoutPet'..b..'XPBar']:SetFrameLevel(_G['PetJournalLoadoutPet'..b..'XPBar']:GetFrameLevel()+2)
-		for v = 1, 3 do
-			local s = _G['PetJournalLoadoutPet'..b..'Spell'..v]
-			SV.API:Set("ItemButton", s)
-			s.FlyoutArrow:SetTexture([[Interface\Buttons\ActionBarFlyoutButton]])
-			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:InsetPoints(s)
-			s.Panel:SetFrameLevel(s:GetFrameLevel() + 1)
-			_G['PetJournalLoadoutPet'..b..'Spell'..v..'Icon']:SetParent(s.Panel)
-		end
-	end
-
-	PetJournalSpellSelect:RemoveTextures()
-
-	for b = 1, 2 do
-		local Q = _G['PetJournalSpellSelectSpell'..b]
-		SV.API:Set("ItemButton", Q)
-		_G['PetJournalSpellSelectSpell'..b..'Icon']:InsetPoints(Q)
-		_G['PetJournalSpellSelectSpell'..b..'Icon']:SetDrawLayer('BORDER')
-	end
-
-	PetJournalPetCard:RemoveTextures()
-	SV.API:Set("ItemButton", PetJournalPetCard, true)
-	PetJournalPetCardInset:RemoveTextures()
-	PetJournalPetCardPetInfo.levelBG:SetAlpha(0)
-	PetJournalPetCardPetInfoIcon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
-	SV.API:Set("ItemButton", PetJournalPetCardPetInfo, true)
-
-	local fg = CreateFrame("Frame", nil, PetJournalPetCardPetInfo)
-	fg:SetSize(40,40)
-	fg:SetPoint("TOPLEFT", PetJournalPetCardPetInfo, "TOPLEFT", -1, 1)
-	fg:SetFrameLevel(PetJournalPetCardPetInfo:GetFrameLevel() + 30)
-
-	PetJournalPetCardPetInfo.favorite:SetParent(fg)
-	PetJournalPetCardPetInfo.Panel:WrapPoints(PetJournalPetCardPetInfoIcon)
-	PetJournalPetCardPetInfoIcon:SetParent(PetJournalPetCardPetInfo.Panel)
-
-	local R = PetJournalPrimaryAbilityTooltip;
-	R.Background:SetTexture("")
-	if R.Delimiter1 then
-		R.Delimiter1:SetTexture("")
-		R.Delimiter2:SetTexture("")
-	end
-
-	R.BorderTop:SetTexture("")
-	R.BorderTopLeft:SetTexture("")
-	R.BorderTopRight:SetTexture("")
-	R.BorderLeft:SetTexture("")
-	R.BorderRight:SetTexture("")
-	R.BorderBottom:SetTexture("")
-	R.BorderBottomRight:SetTexture("")
-	R.BorderBottomLeft:SetTexture("")
-	R:SetStyle("!_Frame", "Transparent", true)
-
-	for b = 1, 6 do
-		local S = _G['PetJournalPetCardSpell'..b]
-		S:SetFrameLevel(S:GetFrameLevel() + 2)
-		S:DisableDrawLayer('BACKGROUND')
-		S:SetStyle("Frame", 'Transparent')
-		S.Panel:SetAllPoints()
-		S.icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
-		S.icon:InsetPoints(S.Panel)
-	end
-
-	PetJournalPetCardHealthFrame.healthBar:RemoveTextures()
-	PetJournalPetCardHealthFrame.healthBar:SetStyle("Frame", 'Default')
-	PetJournalPetCardHealthFrame.healthBar:SetStatusBarTexture(SV.media.statusbar.default)
-	PetJournalPetCardXPBar:RemoveTextures()
-	PetJournalPetCardXPBar:SetStyle("Frame", 'Default')
-	PetJournalPetCardXPBar:SetStatusBarTexture(SV.media.statusbar.default)
-
-	SV.API:Set("Tab", CollectionsJournalTab3)
-	SV.API:Set("Tab", CollectionsJournalTab4)
-
-	ToyBox:RemoveTextures()
-	ToyBox.searchBox:SetStyle("Editbox")
-	ToyBoxFilterButton:RemoveTextures(true)
-	ToyBoxFilterButton:SetStyle("Button")
-	ToyBox.iconsFrame:RemoveTextures()
-	ToyBox.iconsFrame:SetStyle("!_Frame", 'Model')
-	ToyBox.progressBar:RemoveTextures()
-	ToyBox.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
-	ToyBox.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
-	SV.API:Set("PageButton", ToyBox.navigationFrame.prevPageButton, false, true)
-	SV.API:Set("PageButton", ToyBox.navigationFrame.nextPageButton)
-
-	HeirloomsJournal:RemoveTextures()
-	HeirloomsJournal.SearchBox:SetStyle("Editbox")
-	HeirloomsJournalFilterButton:RemoveTextures(true)
-	HeirloomsJournalFilterButton:SetStyle("Button")
-	HeirloomsJournal.iconsFrame:RemoveTextures()
-	HeirloomsJournal.iconsFrame:SetStyle("!_Frame", 'Model')
-
-	HeirloomsJournal.progressBar:RemoveTextures()
-	HeirloomsJournal.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
-	HeirloomsJournal.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
-	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.prevPageButton, false, true)
-	SV.API:Set("PageButton", HeirloomsJournal.navigationFrame.nextPageButton)
-
-	SV.API:Set("DropDown", HeirloomsJournalClassDropDown)
-
-	MountJournalFilterButton:RemoveTextures(true)
-	MountJournalFilterButton:SetStyle("Button")
-
-	MountJournal.SummonRandomFavoriteButton:RemoveTextures()
-	MountJournal.SummonRandomFavoriteButton:SetStyle("ActionSlot")
-	MountJournal.SummonRandomFavoriteButton.texture:SetTexture([[Interface\ICONS\ACHIEVEMENT_GUILDPERK_MOUNTUP]])
-	MountJournal.SummonRandomFavoriteButton.texture:SetTexCoord(unpack(_G.SVUI_ICON_COORDS))
-
-	for i = 1, 18 do
-		local gName = ("ToySpellButton%d"):format(i)
-		local button = _G[gName]
-		if(button) then
-			button:SetStyle("Button")
-		end
-	end
-
-	SV.API:Set("Tab", CollectionsJournalTab5)
-	WardrobeCollectionFrame:RemoveTextures()
-	WardrobeCollectionFrameSearchBox:SetStyle("Editbox")
-	WardrobeCollectionFrame.FilterButton:RemoveTextures(true)
-	WardrobeCollectionFrame.FilterButton:SetStyle("Button")
-	WardrobeCollectionFrame.ModelsFrame:RemoveTextures()
-	WardrobeCollectionFrame.ModelsFrame:SetStyle("!_Frame", 'Model')
-
-	WardrobeCollectionFrame.progressBar:RemoveTextures()
-	WardrobeCollectionFrame.progressBar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
-	WardrobeCollectionFrame.progressBar:SetStyle("Frame", "Bar", true, 2, 2, 2)
-	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.PrevPageButton, false, true)
-	SV.API:Set("PageButton", WardrobeCollectionFrame.NavigationFrame.NextPageButton)
-end
---[[
-##########################################################
-MOD LOADING
-##########################################################
-]]--
-MOD:SaveBlizzardStyle("Blizzard_Collections", CollectionsJournalStyle)
\ No newline at end of file
diff --git a/SVUI_Skins/components/blizzard/worldmap.lua b/SVUI_Skins/components/blizzard/worldmap.lua
index 6da4d84..7e9397b 100644
--- a/SVUI_Skins/components/blizzard/worldmap.lua
+++ b/SVUI_Skins/components/blizzard/worldmap.lua
@@ -111,12 +111,15 @@ local function WorldMap_OnShow()
     WorldMap_SmallView()
   end
   -- WorldMap_SmallView()
-  if not SV.db.Maps.tinyWorldMap then
+
+  -- JV - 20160918 Fix error around expectation that SV.db.Maps exists which might not be so if SVUI_Maps is not be true if it's not loaded/installed
+  if ((SV.Maps and SV.db.Maps) and not SV.db.Maps.tinyWorldMap) then
     BlackoutWorld:SetColorTexture(0,0,0,1)
   else
     BlackoutWorld:SetTexture("")
   end

+
   WorldMapFrameAreaLabel:SetShadowOffset(2, -2)
   WorldMapFrameAreaLabel:SetTextColor(0.90, 0.8294, 0.6407)
   WorldMapFrameAreaDescription:SetShadowOffset(2, -2)
diff --git a/SVUI_Tooltip/LICENSE.txt b/SVUI_Tooltip/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_Tooltip/LICENSE.txt
+++ b/SVUI_Tooltip/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_Tooltip/SVUI_Tooltip.lua b/SVUI_Tooltip/SVUI_Tooltip.lua
index 526c34c..ac020f5 100644
--- a/SVUI_Tooltip/SVUI_Tooltip.lua
+++ b/SVUI_Tooltip/SVUI_Tooltip.lua
@@ -84,6 +84,8 @@ local tooltips = {
 	ItemSocketingDescription
 };

+local INSPECT_CACHE_DURATION = 600 -- how long something lives in the inspect cache.
+
 -- local ignored_tooltips = {
 -- 	FrameStackTooltip
 -- };
@@ -273,13 +275,15 @@ local function ShowInspectInfo(this, unit, unitLevel, r, g, b, iteration)
 	local inspectable = CanInspect(unit)
 	if((not inspectable) or (unitLevel < 10) or (iteration > 2)) then return end
 	local GUID = UnitGUID(unit)
+
 	if(GUID == playerGUID) then
+		local total,equipped = GetAverageItemLevel()
 		this:AddDoubleLine(L["Talent Specialization:"], GetTalentSpec(unit, true), nil, nil, nil, r, g, b)
-		this:AddDoubleLine(L["Item Level:"], floor(select(2, GetAverageItemLevel())), nil, nil, nil, 1, 1, 1)
+		this:AddDoubleLine(L["Item Level:"], floor(equipped), nil, nil, nil, 1, 1, 1)
 	elseif(inspectCache[GUID]) then
 		local talent = inspectCache[GUID].talent;
 		local itemLevel = inspectCache[GUID].itemLevel;
-		if(((GetTime() - inspectCache[GUID].time) > 900) or not talent or not itemLevel) then
+		if(((GetTime() - inspectCache[GUID].time) > INSPECT_CACHE_DURATION) or not talent or not itemLevel) then
 			inspectCache[GUID] = nil;
 			return ShowInspectInfo(this,unit,unitLevel,r,g,b,iteration+1)
 		end
diff --git a/SVUI_TrackOMatic/License.txt b/SVUI_TrackOMatic/License.txt
index 69d4d04..18ddca3 100644
--- a/SVUI_TrackOMatic/License.txt
+++ b/SVUI_TrackOMatic/License.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_TrackOMatic/components/triangulate.lua b/SVUI_TrackOMatic/components/triangulate.lua
index 87d8c0e..52a1147 100644
--- a/SVUI_TrackOMatic/components/triangulate.lua
+++ b/SVUI_TrackOMatic/components/triangulate.lua
@@ -146,7 +146,13 @@ do
         local map = {}
         local mapName = GetMapInfo();
         local id = GetCurrentMapAreaID();
-        local numFloors = GetNumDungeonMapLevels();
+        -- JV: GetNumDungeonMapLevels now returns a list of ids for floors instead of count.
+        local numFloors = 0
+        local dungeonLevels = { GetNumDungeonMapLevels() };
+        for id, floorNum in ipairs(dungeonLevels) do
+            numFloors = numFloors + 1
+        end
+
         map.mapName = mapName;
         map.cont = (GetCurrentMapContinent()) or -100;
         map.zone = (GetCurrentMapZone()) or -100;
diff --git a/SVUI_UnitFrames/LICENSE.txt b/SVUI_UnitFrames/LICENSE.txt
index 05ceba8..c907acb 100644
--- a/SVUI_UnitFrames/LICENSE.txt
+++ b/SVUI_UnitFrames/LICENSE.txt
@@ -1,7 +1,7 @@

 The MIT License

-Copyright (c) 2010, Failcoder (Steve Jackson)
+Copyright (c) 2010-2016, Failcoder (Steve Jackson), Joe Vaughan.

 Permission is hereby granted, free of charge, to any person obtaining a
 copy
diff --git a/SVUI_UnitFrames/Loader.lua b/SVUI_UnitFrames/Loader.lua
index d17e592..528a3c6 100644
--- a/SVUI_UnitFrames/Loader.lua
+++ b/SVUI_UnitFrames/Loader.lua
@@ -118,7 +118,8 @@ SV.defaults[Schema] = {
 	["auraBarShield"] = true,
 	["castClassColor"] = false,
 	["xrayFocus"] = true,
-	["resolveBar"] = false,
+	-- JV - 20160919 : Resolve mechanic is now gone as of Legion.
+	--["resolveBar"] = false,
 	["player"] = {
 		["enable"] = true,
 		["width"] = 215,
diff --git a/SVUI_UnitFrames/SVUI_UnitFrames.lua b/SVUI_UnitFrames/SVUI_UnitFrames.lua
index 519e8b4..3964dba 100644
--- a/SVUI_UnitFrames/SVUI_UnitFrames.lua
+++ b/SVUI_UnitFrames/SVUI_UnitFrames.lua
@@ -1376,7 +1376,18 @@ function MOD:Load()

 	if(SV.db.UnitFrames.disableBlizzard) then
 		self:KillBlizzardRaidFrames()
-		hooksecurefunc("CompactUnitFrame_RegisterEvents", CompactUnitFrame_UnregisterEvents)
+		-- This doesn't work as intended any more: Nameplates are now UnitFrames based on CompactUnitFrame and just unhooking RegisterEvent
+		-- means that the nameplates can't register events and therefore can't update (e.g. bars don't update)
+		-- hooksecurefunc("CompactUnitFrame_RegisterEvents", CompactUnitFrame_UnregisterEvents)
+		oUF_SVUI:DisableBlizzard("player")
+		oUF_SVUI:DisableBlizzard("pet")
+		oUF_SVUI:DisableBlizzard("pettarget")
+		oUF_SVUI:DisableBlizzard("target")
+		oUF_SVUI:DisableBlizzard("targettarget")
+		oUF_SVUI:DisableBlizzard("focus")
+		oUF_SVUI:DisableBlizzard("focustarget")
+		oUF_SVUI:DisableBlizzard("boss")
+
 		hooksecurefunc("UnitFrameThreatIndicator_Initialize", UnitFrameThreatIndicator_Hook)

 		--[[
diff --git a/SVUI_UnitFrames/class_resources/druid.lua b/SVUI_UnitFrames/class_resources/druid.lua
index 3ef3480..58707d2 100644
--- a/SVUI_UnitFrames/class_resources/druid.lua
+++ b/SVUI_UnitFrames/class_resources/druid.lua
@@ -146,14 +146,16 @@ local Reposition = function(self)
 	local cat = bar.Cat;
 	local size = (height - 4)
 	for i = 1, max do
-		cat[i]:ClearAllPoints()
-		cat[i]:SetSize(size, size)
-		cat[i].Icon:ClearAllPoints()
-		cat[i].Icon:SetAllPoints(cat[i])
-		if i==1 then
-			cat[i]:SetPoint("LEFT", cat)
-		else
-			cat[i]:SetPoint("LEFT", cat[i - 1], "RIGHT", -2, 0)
+		if cat[i] then
+			cat[i]:ClearAllPoints()
+			cat[i]:SetSize(size, size)
+			cat[i].Icon:ClearAllPoints()
+			cat[i].Icon:SetAllPoints(cat[i])
+			if i==1 then
+				cat[i]:SetPoint("LEFT", cat)
+			else
+				cat[i]:SetPoint("LEFT", cat[i - 1], "RIGHT", -2, 0)
+			end
 		end
 	end
 end
@@ -322,17 +324,19 @@ function MOD:CreateClassBar(playerFrame)
 	local max = MAX_COMBO_POINTS;
 	local size = 20
 	for i = 1, max do
-		local cpoint = CreateFrame('Frame',nil,cat)
-		cpoint:SetSize(size,size)
-
-		local icon = cpoint:CreateTexture(nil,"OVERLAY",nil,1)
-		icon:SetSize(size,size)
-		icon:SetPoint("CENTER")
-		icon:SetBlendMode("BLEND")
-		icon:SetTexture(comboTextures[random(1,3)])
-		cpoint.Icon = icon
-
-		cat[i] = cpoint
+		if cat[i] then
+			local cpoint = CreateFrame('Frame',nil,cat)
+			cpoint:SetSize(size,size)
+
+			local icon = cpoint:CreateTexture(nil,"OVERLAY",nil,1)
+			icon:SetSize(size,size)
+			icon:SetPoint("CENTER")
+			icon:SetBlendMode("BLEND")
+			icon:SetTexture(comboTextures[random(1,3)])
+			cpoint.Icon = icon
+
+			cat[i] = cpoint
+		end
 	end
 	cat.PointShow = ShowPoint;
 	cat.PointHide = HidePoint;
diff --git a/SVUI_UnitFrames/class_resources/rogue.lua b/SVUI_UnitFrames/class_resources/rogue.lua
index 0a81bec..7abaa28 100644
--- a/SVUI_UnitFrames/class_resources/rogue.lua
+++ b/SVUI_UnitFrames/class_resources/rogue.lua
@@ -121,17 +121,19 @@ local Reposition = function(self)
 		bar.PointHide = HidePoint;
 	else
 		for i = 1, max do
-			points[i].FX:SetAlpha(1)
-			points[i]:ClearAllPoints()
-			points[i]:SetSize(height, height)
-			points[i].Icon:SetTexture(EMPTY_TEXTURE)
-			if(points[i].Blood) then
-				points[i].Blood:SetTexture(EMPTY_TEXTURE)
-			end
-			if i==1 then
-				points[i]:SetPoint("LEFT", points)
-			else
-				points[i]:SetPoint("LEFT", points[i - 1], "RIGHT", -8, 0)
+			if points[i] then
+				points[i].FX:SetAlpha(1)
+				points[i]:ClearAllPoints()
+				points[i]:SetSize(height, height)
+				points[i].Icon:SetTexture(EMPTY_TEXTURE)
+				if(points[i].Blood) then
+					points[i].Blood:SetTexture(EMPTY_TEXTURE)
+				end
+				if i==1 then
+					points[i]:SetPoint("LEFT", points)
+				else
+					points[i]:SetPoint("LEFT", points[i - 1], "RIGHT", -8, 0)
+				end
 			end
 		end
 		bar.PointShow = ShowPoint;
diff --git a/SVUI_UnitFrames/elements/essentials.lua b/SVUI_UnitFrames/elements/essentials.lua
index e1ea157..4eac790 100644
--- a/SVUI_UnitFrames/elements/essentials.lua
+++ b/SVUI_UnitFrames/elements/essentials.lua
@@ -559,6 +559,28 @@ end
 HEALTH
 ##########################################################
 ]]--
+local function CreateAbsorbBar(parent, unit)
+	local absorbBar = CreateFrame("StatusBar", nil, parent)
+	absorbBar:SetFrameStrata("LOW")
+	absorbBar:SetFrameLevel(3)
+	absorbBar:SetStatusBarTexture(SV.media.statusbar.default);
+	absorbBar:SetMinMaxValues(0, 100)
+	absorbBar:SetAllPoints(parent)
+	absorbBar:SetScript("OnUpdate", function(self)
+		if unit then
+			local hpMax = UnitHealthMax(unit)
+			local currentHP = UnitHealth(unit)
+			local absorb = UnitGetTotalAbsorbs(unit)
+			local effectiveHP = absorb + currentHP
+
+			if effectiveHP > hpMax then effectiveHP = hpMax end
+			self:SetMinMaxValues(0, hpMax)
+			self:SetValue(effectiveHP)
+		end
+	end)
+	return absorbBar
+end
+
 local OverlayHealthUpdate = function(health, unit, min, max)
 	local disconnected = not UnitIsConnected(unit)
 	health:SetMinMaxValues(-max, 0)
@@ -606,6 +628,13 @@ local OverlayHealthUpdate = function(health, unit, min, max)
 end

 local RefreshHealthBar = function(self, overlay)
+	local db = SV.db.UnitFrames[self.unit]
+	local absorbBarEnabled = false
+
+	if db and db.health.absorbsBar then
+		absorbBarEnabled = true
+	end
+
 	if(overlay) then
 		self.Health.bg:SetVertexColor(0, 0, 0, 0)
 		self.Health.PreUpdate = OverlayHealthUpdate;
@@ -613,16 +642,51 @@ local RefreshHealthBar = function(self, overlay)
 		self.Health.bg:SetVertexColor(0.4, 0.1, 0.1, 0.8)
 		self.Health.PreUpdate = nil;
 	end
+
+	if absorbBarEnabled then
+		local absorbBar
+			if self.Health.absorbBar then
+				absorbBar = self.Health.absorbBar
+			else
+				absorbBar = CreateAbsorbBar(self.Health, self.unit)
+			end
+
+		self.Health.bg:SetParent(absorbBar)
+		absorbBar:Show()
+	else
+		self.Health.bg:SetParent(self.Health)
+		if self.Health.absorbBar then
+			self.Health.absorbBar:Hide()
+		end
+	end
 end

 function MOD:CreateHealthBar(frame, hasbg)
+	local db = SV.db.UnitFrames[frame.unit]
+	local enableAbsorbsBar = false
+
+	if db and db.health.absorbsBar then
+		enableAbsorbsBar = true
+	end
+
+
+
 	local healthBar = CreateFrame("StatusBar", nil, frame)
 	healthBar:SetFrameStrata("LOW")
 	healthBar:SetFrameLevel(4)
 	healthBar:SetStatusBarTexture(SV.media.statusbar.default);

+	if enableAbsorbsBar then
+		local absorbBar = CreateAbsorbBar(healthBar, frame.unit)
+		healthBar.absorbBar = absorbBar
+	end
+
 	if hasbg then
-		healthBar.bg = healthBar:CreateTexture(nil, "BORDER")
+		if not enableAbsorbsBar then
+			healthBar.bg = healthBar:CreateTexture(nil, "BORDER")
+		else
+			healthBar.bg = healthBar.absorbBar:CreateTexture(nil, "BORDER")
+		end
 		healthBar.bg:SetAllPoints()
 		healthBar.bg:SetTexture(SV.media.statusbar.gradient)
 		healthBar.bg:SetVertexColor(0.4, 0.1, 0.1)
diff --git a/SVUI_UnitFrames/elements/misc.lua b/SVUI_UnitFrames/elements/misc.lua
index 97cfb87..256e634 100644
--- a/SVUI_UnitFrames/elements/misc.lua
+++ b/SVUI_UnitFrames/elements/misc.lua
@@ -526,121 +526,133 @@ function MOD:CreateHealPrediction(frame, fullSet)

 	return healPrediction
 end
+
+-- JV - 20160919 : Resolve mechanic is now gone as of Legion.
 --[[
 ##########################################################
 RESOLVE
 ##########################################################
 ]]--
-local cached_resolve;
-local RESOLVE_ID = 158300;
-
-local function Short(value)
-	local fmt
-	if value >= 10000 then
-		fmt = "%.0fk"
-		value = value / 1000
-	elseif value >= 1000 then
-		fmt = "%.1fk"
-		value = value / 1000
-	else
-		fmt = "%d"
-	end
-	return fmt:format(value)
-end
-
-local function IsTank()
-	local _, playerclass = UnitClass("player")
-	local masteryIndex
-	local tank = false
-	if playerclass == "DEATHKNIGHT" then
-		masteryIndex = GetSpecialization()
-		if masteryIndex and masteryIndex == 1 then
-			tank = true
-		end
-	elseif playerclass == "DRUID" then
-		masteryIndex = GetSpecialization()
-		if masteryIndex and masteryIndex == 3 then
-			tank = true
-		end
-	elseif playerclass == "MONK" then
-		masteryIndex = GetSpecialization()
-		if masteryIndex and masteryIndex == 1 then
-			tank = true
-		end
-	elseif playerclass == "PALADIN" then
-		masteryIndex = GetSpecialization()
-		if masteryIndex and masteryIndex == 2 then
-			tank = true
-		end
-	elseif playerclass == "WARRIOR" then
-		masteryIndex = GetSpecialization()
-		if masteryIndex and masteryIndex == 3 then
-			tank = true
-		end
-	end
-	return tank
-end
-
-local ResolveBar_OnEvent = function(self, event, unit)
-	if(SV.db.UnitFrames.resolveBar) then
-		if(event == 'UNIT_AURA') then
-			for index = 1, 30 do
-				local _, _, _, _, _, _, _, _, _, _, spellID, _, _, _, value, amount = UnitBuff('player', index)
-				if((spellID == RESOLVE_ID) and (amount and (cached_resolve ~= amount))) then
-					if(value) then
-						self.bar:SetValue(value)
-					end
-					self.bar.text:SetText(Short(amount))
-					self:FadeIn()
-					cached_resolve = amount
-				end
-			end
-		else
-			if IsTank() then
-				if(not self.bar:IsShown()) then
-					self:RegisterUnitEvent("UNIT_AURA", "player")
-					self.bar:Show()
-				end
-			else
-				if(self.bar:IsShown()) then
-					self:UnregisterEvent("UNIT_AURA")
-					self.bar:Hide()
-				end
-			end
-		end
-	end
-	if(self.bar:IsShown()) then
-		if(self.bar.text:GetText() == "0") then
-			self.bar.text:SetText("")
-			self:FadeOut()
-		end
-	end
-end
-
-function MOD:CreateResolveBar(frame)
-	local resolve = CreateFrame("Frame", nil, frame)
-	resolve:SetPoint("TOPLEFT", frame.Health, "TOPLEFT", 0, 0)
-	resolve:SetPoint("TOPRIGHT", frame.Health, "TOPRIGHT", 0, 0)
-	resolve:SetHeight(8)
-
-	local bar = CreateFrame('StatusBar', nil, resolve)
-	bar:InsetPoints(resolve)
-	bar:SetStyle("Frame", "Bar")
-	bar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
-	bar:SetStatusBarColor(0.15, 0.7, 0.05, 0.9)
-	bar:SetMinMaxValues(0, 100)
-	bar.text = bar:CreateFontString(nil, "OVERLAY")
-	bar.text:SetPoint("LEFT")
-	bar.text:SetFontObject(SVUI_Font_Pixel)
-	bar.text:SetJustifyH('LEFT')
-	bar.text:SetTextColor(0.8, 0.42, 0.09)
-	bar:Hide()
-	resolve.bar = bar;
-
-	resolve:RegisterEvent("PLAYER_TALENT_UPDATE")
-	resolve:RegisterEvent("PLAYER_ENTERING_WORLD")
-	resolve:SetScript('OnEvent', ResolveBar_OnEvent)
-
-	ResolveBar_OnEvent(resolve)
-	return resolve
-end
+-- local cached_resolve;
+-- local RESOLVE_ID = 158300;
+
+-- local function Short(value)
+-- 	local fmt
+-- 	if value >= 10000 then
+-- 		fmt = "%.0fk"
+-- 		value = value / 1000
+-- 	elseif value >= 1000 then
+-- 		fmt = "%.1fk"
+-- 		value = value / 1000
+-- 	else
+-- 		fmt = "%d"
+-- 	end
+-- 	return fmt:format(value)
+-- end
+
+-- local function IsTank()
+-- 	local _, playerclass = UnitClass("player")
+-- 	local masteryIndex
+-- 	local tank = false
+-- 	if playerclass == "DEATHKNIGHT" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 1 then
+-- 			tank = true
+-- 		end
+-- 	elseif playerclass == "DRUID" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 3 then
+-- 			tank = true
+-- 		end
+-- 	elseif playerclass == "MONK" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 1 then
+-- 			tank = true
+-- 		end
+-- 	elseif playerclass == "PALADIN" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 2 then
+-- 			tank = true
+-- 		end
+-- 	elseif playerclass == "WARRIOR" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 3 then
+-- 			tank = true
+-- 		end
+-- 	elseif playerclass == "DEMONHUNTER" then
+-- 		masteryIndex = GetSpecialization()
+-- 		if masteryIndex and masteryIndex == 2 then
+-- 			tank = true
+-- 		end
+-- 	end
+-- 	return tank
+-- end
+
+-- local ResolveBar_OnEvent = function(self, event, unit)
+-- 	if(SV.db.UnitFrames.resolveBar) then
+-- 		if(event == 'UNIT_AURA') then
+-- 			for index = 1, 30 do
+-- 				local _, _, _, _, _, _, _, _, _, _, spellID, _, _, _, value, amount = UnitBuff('player', index)
+-- 				if((spellID == RESOLVE_ID) and (amount and (cached_resolve ~= amount))) then
+-- 					if(value) then
+-- 						self.bar:SetValue(value)
+-- 					end
+-- 					self.bar.text:SetText(Short(amount))
+-- 					self:FadeIn()
+-- 					cached_resolve = amount
+-- 				end
+-- 			end
+-- 		else
+-- 			if IsTank() then
+-- 				if(not self.bar:IsShown()) then
+-- 					self:RegisterUnitEvent("UNIT_AURA", "player")
+-- 					self.bar:Show()
+-- 				end
+-- 			else
+-- 				if(self.bar:IsShown()) then
+-- 					self:UnregisterEvent("UNIT_AURA")
+-- 					self.bar:Hide()
+-- 				end
+-- 			end
+-- 		end
+-- 	else
+-- 		if(self.bar:IsShown()) then
+-- 			self:UnregisterEvent("UNIT_AURA")
+-- 			self.bar:Hide()
+-- 		end
+-- 	end
+-- 	if(self.bar:IsShown()) then
+-- 		if(self.bar.text:GetText() == "0") then
+-- 			self.bar.text:SetText("")
+-- 			self:FadeOut()
+-- 		end
+-- 	end
+-- end
+
+-- function MOD:CreateResolveBar(frame)
+-- 	local resolve = CreateFrame("Frame", nil, frame)
+-- 	resolve:SetPoint("TOPLEFT", frame.Health, "TOPLEFT", 0, 0)
+-- 	resolve:SetPoint("TOPRIGHT", frame.Health, "TOPRIGHT", 0, 0)
+-- 	resolve:SetHeight(8)
+
+-- 	local bar = CreateFrame('StatusBar', nil, resolve)
+-- 	bar:InsetPoints(resolve)
+-- 	bar:SetStyle("Frame", "Bar")
+-- 	bar:SetStatusBarTexture([[Interface\BUTTONS\WHITE8X8]])
+-- 	bar:SetStatusBarColor(0.15, 0.7, 0.05, 0.9)
+-- 	bar:SetMinMaxValues(0, 100)
+-- 	bar.text = bar:CreateFontString(nil, "OVERLAY")
+-- 	bar.text:SetPoint("LEFT")
+-- 	bar.text:SetFontObject(SVUI_Font_Pixel)
+-- 	bar.text:SetJustifyH('LEFT')
+-- 	bar.text:SetTextColor(0.8, 0.42, 0.09)
+-- 	bar:Hide()
+-- 	resolve.bar = bar;
+
+-- 	resolve:RegisterEvent("PLAYER_TALENT_UPDATE")
+-- 	resolve:RegisterEvent("PLAYER_ENTERING_WORLD")
+-- 	resolve:SetScript('OnEvent', ResolveBar_OnEvent)
+
+-- 	ResolveBar_OnEvent(resolve)
+-- 	return resolve
+-- end
diff --git a/SVUI_UnitFrames/frames.lua b/SVUI_UnitFrames/frames.lua
index 4b86c96..72fb337 100644
--- a/SVUI_UnitFrames/frames.lua
+++ b/SVUI_UnitFrames/frames.lua
@@ -307,7 +307,8 @@ CONSTRUCTORS["player"] = function(self, unit)
     self.PvPText:SetFontObject(SpellFont_Small)
     self.Afflicted = MOD:CreateAfflicted(self)
     self.HealPrediction = MOD:CreateHealPrediction(self, true)
-    self.ResolveBar = MOD:CreateResolveBar(self)
+    -- JV - 20160919 : Resolve mechanic is now gone as of Legion.
+    --self.ResolveBar = MOD:CreateResolveBar(self)
     self.CombatFade = false;
     self:SetPoint("BOTTOMRIGHT", SV.Screen, "BOTTOM", -80, 182)
     SV:NewAnchor(self, L["Player Frame"])
diff --git a/SVUI_UnitFrames/groups.lua b/SVUI_UnitFrames/groups.lua
index 9ba6120..35de164 100644
--- a/SVUI_UnitFrames/groups.lua
+++ b/SVUI_UnitFrames/groups.lua
@@ -109,7 +109,7 @@ local groupTagPoints = {

 local GroupDistributor = {
     ["CLASS"] = function(x)
-        x:SetAttribute("groupingOrder","DEATHKNIGHT,DRUID,HUNTER,MAGE,PALADIN,PRIEST,SHAMAN,WARLOCK,WARRIOR,MONK,DEMONHUNTER")
+        x:SetAttribute("groupingOrder","DEATHKNIGHT,DRUID,HUNTER,MAGE,PALADIN,PRIEST,SHAMAN,WARLOCK,WARRIOR,MONK")
         x:SetAttribute("sortMethod","NAME")
         x:SetAttribute("groupBy","CLASS")
     end,
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
index 7a536b4..14ae669 100644
--- a/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_AuraWatch/oUF_AuraWatch.toc
@@ -1,10 +1,10 @@
 ## Interface: 30300
 ## Title: oUF AuraWatch
 ## Author: Astromech
-## Version: 1.3.58-6
+## Version: 1.3.28-6
 ## Notes: Adds aura timers to oUF
 ## OptionalDeps: oUF
 ## X-oUF: oUF


-oUF_AuraWatch.lua
\ No newline at end of file
+oUF_AuraWatch.lua
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
index 0c9b3d9..cbb8c14 100644
--- a/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_Druidness/oUF_Druidness.lua
@@ -48,6 +48,12 @@ local TextColors = {
 	[4]={0.5,1,0.1},
 	[5]={0.1,1,0.1}
 };
+local Debug
+if AdiDebug then
+	Debug = AdiDebug:GetSink("oUF_Druidness")
+else
+	Debug = function() end
+end

 local ProxyShow = function(self)
 	if(not self.isEnabled) then return end
@@ -155,16 +161,21 @@ local UpdateComboPoints = function(self, event, unit)

 	if(cpoints) then
 		local MAX_COMBO_POINTS = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
+		Debug("max combo points/current: ", MAX_COMBO_POINTS,current)
 		for i=1, MAX_COMBO_POINTS do
 			if(i <= current) then
-				cpoints[i]:Show()
-				if(bar.PointShow) then
-					bar.PointShow(cpoints[i])
+				if cpoints[i] then
+					cpoints[i]:Show()
+					if(bar.PointShow) then
+						bar.PointShow(cpoints[i])
+					end
 				end
 			else
-				cpoints[i]:Hide()
-				if(bar.PointHide) then
-					bar.PointHide(cpoints[i], i)
+				if cpoints[i] then
+					cpoints[i]:Hide()
+					if(bar.PointHide) then
+						bar.PointHide(cpoints[i], i)
+					end
 				end
 			end
 		end
diff --git a/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua b/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
index 007e596..38fc73b 100644
--- a/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
+++ b/SVUI_UnitFrames/libs/Plugins/oUF_HyperCombo/oUF_HyperCombo.lua
@@ -63,14 +63,18 @@ local Update = function(self, event, unit)
 		local MAX_COMBO_POINTS = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
 		for i=1, MAX_COMBO_POINTS do
 			if(i <= current) then
-				cpoints[i]:Show()
-				if(bar.PointShow) then
-					bar.PointShow(cpoints[i])
+				if (cpoints[i]) then
+					cpoints[i]:Show()
+					if(bar.PointShow) then
+						bar.PointShow(cpoints[i])
+					end
 				end
 			else
-				cpoints[i]:Hide()
-				if(bar.PointHide) then
-					bar.PointHide(cpoints[i], i)
+				if (cpoints[i]) then
+					cpoints[i]:Hide()
+					if(bar.PointHide) then
+						bar.PointHide(cpoints[i], i)
+					end
 				end
 			end
 		end
@@ -108,7 +112,7 @@ local Enable = function(self)
 			local maxComboPoints = UnitPowerMax("player", SPELL_POWER_COMBO_POINTS);
 			for index = 1, maxComboPoints do
 				local cpoint = cpoints[index]
-				if(cpoint:IsObjectType'Texture' and not cpoint:GetTexture()) then
+				if(cpoint and cpoint:IsObjectType'Texture' and not cpoint:GetTexture()) then
 					cpoint:SetTexture[[Interface\ComboFrame\ComboPoint]]
 					cpoint:SetTexCoord(0, 0.375, 0, 1)
 				end
@@ -125,7 +129,7 @@ local Disable = function(self)
 		if(cpoints) then
 			local maxComboPoints = UnitPowerMax(self.unit, SPELL_POWER_COMBO_POINTS);
 			for index = 1, maxComboPoints do
-				cpoints[index]:Hide()
+				if (cpoints[index]) then cpoints[index]:Hide() end
 			end
 		end
 		self:UnregisterEvent('PLAYER_ENTERING_WORLD', Path)