Updated LibSort

CrazyDutchGuy [06-28-14 - 14:21]
Updated LibSort
Filename
Libs/LibSort-1.0/LibSort-1.0.lua
Libs/LibSort/LibSort-1.0.lua
Libs/LibSort/README.md
MrPlow.lua
MrPlow.txt
diff --git a/Libs/LibSort-1.0/LibSort-1.0.lua b/Libs/LibSort-1.0/LibSort-1.0.lua
new file mode 100644
index 0000000..9fdeede
--- /dev/null
+++ b/Libs/LibSort-1.0/LibSort-1.0.lua
@@ -0,0 +1,175 @@
+local MAJOR, MINOR = "LibSort-1.0", 3
+local LibSort, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not LibSort then return end	--the same or newer version of this lib is already loaded into memory
+
+LibSort.sortKeys = ZO_Inventory_GetDefaultHeaderSortKeys()
+
+-- Lookup Tables ---
+local defaultType = {["isNumeric"] = 0, ["isBoolean"] = false, ["isString"] = ""}
+local inventoryTypes =
+{
+	[INVENTORY_BACKPACK] = ZO_PlayerInventoryBackpack,
+	[INVENTORY_BANK] = ZO_PlayerBankBackpack,
+	[INVENTORY_GUILD_BANK] = ZO_GuildBankBackpack
+}
+
+--- Utility functions ---
+
+local function removeSpaces(name)
+	return name:gsub(" ","")
+end
+
+local function makePrefix(name)
+	return removeSpaces(name) .. "_"
+end
+
+function LibSort:Debug(msg)
+	if LibSort.isDebugging then
+		d("[LibSort]: "..msg)
+	end
+end
+
+--- Arrow generation ---
+function LibSort:SetupArrows()
+	LibSort.ItemSortBank = WINDOW_MANAGER:CreateControlFromVirtual("ItemSortBank", ZO_PlayerBankSortBy, "ZO_SortHeaderIcon")
+	LibSort.ItemSortBank:SetDimensions(16, 32)
+	LibSort.ItemSortBank:SetAnchor(RIGHT, ZO_PlayerBankSortByName, LEFT, -15)
+	ZO_SortHeader_SetTooltip(LibSort.ItemSortBank, "Sort", BOTTOMRIGHT, 0, 32)
+    ZO_SortHeader_InitializeArrowHeader(LibSort.ItemSortBank, "age", ZO_SORT_ORDER_DOWN)
+
+    PLAYER_INVENTORY.inventories[INVENTORY_BANK].sortHeaders:AddHeader(ItemSortBank)
+
+    LibSort.ItemSortGuild = WINDOW_MANAGER:CreateControlFromVirtual("ItemSortGuild", ZO_GuildBankSortBy, "ZO_SortHeaderIcon")
+	LibSort.ItemSortGuild:SetDimensions(16, 32)
+	LibSort.ItemSortGuild:SetAnchor(RIGHT, ZO_GuildBankSortByName, LEFT, -15)
+	ZO_SortHeader_SetTooltip(LibSort.ItemSortGuild, "Sort", BOTTOMRIGHT, 0, 32)
+    ZO_SortHeader_InitializeArrowHeader(LibSort.ItemSortGuild, "age", ZO_SORT_ORDER_DOWN)
+
+    PLAYER_INVENTORY.inventories[INVENTORY_GUILD_BANK].sortHeaders:AddHeader(ItemSortGuild)
+end
+
+--- Main functions ---
+function LibSort:InjectKeys()
+	for addon, callbacks in pairs(self.RegisteredCallbacks) do
+		for name, data in pairs(callbacks) do
+			if not self.sortKeys[data.key] then
+				self.sortKeys[data.key] = {}
+				self.sortKeys[data.key][data.dataType] = true
+			end
+		end
+	end
+	self:ReOrderKeys()
+end
+
+function LibSort:ReOrderKeys()
+	local first
+	local previous
+	for i, addonName in ipairs(self.AddonOrder) do
+		if self.DefaultOrdersLow[addonName] then
+			for _, name in ipairs(self.DefaultOrdersLow[addonName]) do
+				local data = self.RegisteredCallbacks[addonName][name]
+				if data then -- we skip the ones we haven't registered yet
+					first, previous = self:SetKeyOrder(first, previous, data)
+				end
+			end
+		end
+	end
+	for i, addonName in ipairs(self.AddonOrder) do
+		if self.DefaultOrdersHigh[addonName] then
+			for _, name in ipairs(self.DefaultOrdersHigh[addonName]) do
+				local data = self.RegisteredCallbacks[addonName][name]
+				if data then -- we skip the ones we haven't registered yet
+					first, previous = self:SetKeyOrder(first, previous, data)
+				end
+			end
+		end
+	end
+	self.sortKeys[previous].tiebreaker = "name"
+	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_BACKPACK, true)
+	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_BANK, true)
+	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_GUILD_BANK, true)
+end
+
+function LibSort:SetKeyOrder(first, previous, data)
+	if not first then
+		first = true
+		self.sortKeys["age"].tiebreaker = data.key
+		self.sortKeys["age"].reverseTiebreakerSortOrder = nil
+	else
+		if previous then
+			self.sortKeys[previous].tiebreaker = data.key
+		end
+	end
+	return first, data.key
+end
+
+function LibSort:ProcessInventory(inventoryType)
+	local container = inventoryTypes[inventoryType]
+	if not container then return end
+	for i, slot in ipairs(container.data) do
+		local slotType, bag, index = slot.data.slotType, slot.data.bagId, slot.data.slotIndex
+		for addon, callbacks in pairs(self.RegisteredCallbacks) do
+			for name, data in pairs(callbacks) do
+				if not slot.data[data.key] then
+					slot.data[data.key] = data.func(slotType, bag, index) or defaultType[data.dataType]
+				end
+			end
+		end
+	end
+end
+
+ZO_PreHook(PLAYER_INVENTORY, "ApplySort", function(self, inventoryType) LibSort:ProcessInventory(inventoryType) end)
+LibSort:SetupArrows()
+--------- API ---------
+
+function LibSort:Unregister(addonName, name)
+	if not name then
+		self.RegisteredCallbacks[addonName] = nil
+		self.DefaultOrdersHigh[addonName] = nil
+		self.DefaultOrdersLow[addonName] = nil
+		return
+	end
+
+	if self.RegisteredCallbacks[addonName] then
+		self.RegisteredCallbacks[addonName][name] = nil
+	end
+end
+
+function LibSort:Register(addonName, name, desc, key, func, dataType)
+	if not dataType then dataType = "isNumeric" end
+
+	if not self.RegisteredCallbacks then self.RegisteredCallbacks = {} end
+	if not self.AddonOrder then self.AddonOrder = {} end
+	if not self.DefaultOrdersHigh then self.DefaultOrdersHigh = {} end
+	if not self.DefaultOrdersLow then self.DefaultOrdersLow = {} end
+
+	if not self.RegisteredCallbacks[addonName] then
+		self.RegisteredCallbacks[addonName] = {}
+		table.insert(self.AddonOrder, addonName)
+	end
+
+	self.RegisteredCallbacks[addonName][name] = {key = makePrefix(addonName)..key, func = func, desc = desc, dataType = dataType}
+
+	if not self.DefaultOrdersHigh[addonName] then self.DefaultOrdersHigh[addonName] = {} end
+
+	table.insert(self.DefaultOrdersHigh[addonName], name)
+	self:InjectKeys()
+end
+
+function LibSort:RegisterNumeric(addonName, name, desc, key, func)
+	self:Register(addonName, name, desc, key, func, "isNumeric")
+end
+
+function LibSort:RegisterBoolean(addonName, name, desc, key, func)
+	self:Register(addonName, name, desc, key, func, "isBoolean")
+end
+
+function LibSort:RegisterString(addonName, name, desc, key, func)
+	self:Register(addonName, name, desc, key, func, "isString")
+end
+
+function LibSort:RegisterDefaultOrder(addonName, keyTableLow, keyTableHigh)
+	self.DefaultOrdersHigh[addonName] = keyTableHigh
+	self.DefaultOrdersLow[addonName] = keyTableLow
+	self:ReOrderKeys()
+end
diff --git a/Libs/LibSort/LibSort-1.0.lua b/Libs/LibSort/LibSort-1.0.lua
deleted file mode 100644
index bb29c6c..0000000
--- a/Libs/LibSort/LibSort-1.0.lua
+++ /dev/null
@@ -1,184 +0,0 @@
-local MAJOR, MINOR = "LibSort-1.0", 2
-local LibSort, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
-if not LibSort then return end	--the same or newer version of this lib is already loaded into memory
-
-LIBSORT = LibSort
-
--- Lookup Tables ---
-local wm = WINDOW_MANAGER
-local defaultType = {["isNumeric"] = 0, ["isBoolean"] = false, ["isString"] = ""}
-local inventoryTypes = {[INVENTORY_BACKPACK] = ZO_PlayerInventoryBackpack, [INVENTORY_BANK] = ZO_PlayerBankBackpack, [INVENTORY_GUILD_BANK] = ZO_GuildBankBackpack}
-
-
---- Utility functions ---
-
-local function removeSpaces(name)
-	return name:gsub(" ","")
-end
-
-local function makePrefix(name)
-	return removeSpaces(name) .. "_"
-end
-
-function LibSort:Debug(msg)
-	if LibSort.isDebugging then	d("[LibSort]: "..msg) 	end
-end
-
---- Storage variables ---
-LibSort.RegisteredCallbacks = {}
-LibSort.AddonOrder = {}
-LibSort.DefaultOrdersLow = {}
-LibSort.DefaultOrdersHigh = {}
-
---- Arrow generation ---
-
-function LibSort:SetupArrows()
-	LibSort.ItemSortBank = wm:CreateControlFromVirtual("ItemSortBank", ZO_PlayerBankSortBy, "ZO_SortHeaderIcon")
-	LibSort.ItemSortBank:SetDimensions(16, 32)
-	LibSort.ItemSortBank:SetAnchor(RIGHT, ZO_PlayerBankSortByName, LEFT, -15)
-	ZO_SortHeader_SetTooltip(LibSort.ItemSortBank, "Sort", BOTTOMRIGHT, 0, 32)
-    ZO_SortHeader_InitializeArrowHeader(LibSort.ItemSortBank, "age", ZO_SORT_ORDER_DOWN)
-
-    PLAYER_INVENTORY.inventories[INVENTORY_BANK].sortHeaders:AddHeader(ItemSortBank)
-
-    LibSort.ItemSortGuild = wm:CreateControlFromVirtual("ItemSortGuild", ZO_GuildBankSortBy, "ZO_SortHeaderIcon")
-	LibSort.ItemSortGuild:SetDimensions(16, 32)
-	LibSort.ItemSortGuild:SetAnchor(RIGHT, ZO_GuildBankSortByName, LEFT, -15)
-	ZO_SortHeader_SetTooltip(LibSort.ItemSortGuild, "Sort", BOTTOMRIGHT, 0, 32)
-    ZO_SortHeader_InitializeArrowHeader(LibSort.ItemSortGuild, "age", ZO_SORT_ORDER_DOWN)
-
-    PLAYER_INVENTORY.inventories[INVENTORY_GUILD_BANK].sortHeaders:AddHeader(ItemSortGuild)
-end
-
-
-
---- Main functions ---
-
-LibSort.sortKeys = ZO_Inventory_GetDefaultHeaderSortKeys()
-
-function LibSort:InjectKeys()
-	for addon, callbacks in pairs(self.RegisteredCallbacks) do
-		for name, data in pairs(callbacks) do
-			if not self.sortKeys[data.key] then
-				self.sortKeys[data.key] = {}
-				self.sortKeys[data.key][data.dataType] = true
-			end
-		end
-	end
-	self:ReOrderKeys()
-end
-
-function LibSort:ReOrderKeys()
-	local first
-	local previous
-	for i, addonName in ipairs(self.AddonOrder) do
-		if self.DefaultOrdersLow[addonName] then
-			for _, name in ipairs(self.DefaultOrdersLow[addonName]) do
-				local data = self.RegisteredCallbacks[addonName][name]
-				if data then -- we skip the ones we haven't registered yet
-					first, previous = self:SetKeyOrder(first, previous, data)
-				end
-			end
-		end
-	end
-	for i, addonName in ipairs(self.AddonOrder) do
-		if self.DefaultOrdersHigh[addonName] then
-			for _, name in ipairs(self.DefaultOrdersHigh[addonName]) do
-				local data = self.RegisteredCallbacks[addonName][name]
-				if data then -- we skip the ones we haven't registered yet
-					first, previous = self:SetKeyOrder(first, previous, data)
-				end
-			end
-		end
-	end
-	self.sortKeys[previous].tiebreaker = "name"
-	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_BACKPACK, true)
-	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_BANK, true)
-	PLAYER_INVENTORY:ChangeSort("age", INVENTORY_GUILD_BANK, true)
-end
-
-function LibSort:SetKeyOrder(first, previous, data)
-	if not first then
-		first = true
-		self.sortKeys["age"].tiebreaker = data.key
-		self.sortKeys["age"].reverseTiebreakerSortOrder = nil
-	else
-		if previous then
-			self.sortKeys[previous].tiebreaker = data.key
-		end
-	end
-	return first, data.key
-end
-
-function LibSort:ProcessInventory(inventoryType)
-	local container = inventoryTypes[inventoryType]
-	if not container then return end
-	for i, slot in ipairs(container.data) do
-		local slotType, bag, index = slot.data.slotType, slot.data.bagId, slot.data.slotIndex
-		for addon, callbacks in pairs(self.RegisteredCallbacks) do
-			for name, data in pairs(callbacks) do
-				if not slot.data[data.key] then
-					slot.data[data.key] = data.func(slotType, bag, index) or defaultType[data.dataType]
-				end
-			end
-		end
-	end
-end
-
-function LibSort:Loaded(event, name)
-    if name ~= "ZO_Ingame" then return end
-
-    self.savedVars = ZO_SavedVars:New("ZO_Ingame_SavedVariables", 1, "LibSort")
-    EVENT_MANAGER:UnregisterForEvent("LibSortLoaded", EVENT_ADD_ON_LOADED)
-
-	ZO_PreHook(PLAYER_INVENTORY, "ApplySort", function(self, inventoryType) LibSort:ProcessInventory(inventoryType) end)
-	zo_callLater(function() LIBSORT:SetupArrows() end, 3000)
-end
-
-EVENT_MANAGER:RegisterForEvent("LibSortLoaded", EVENT_ADD_ON_LOADED, function(...) LibSort:Loaded(...) end)
-
---------- API ---------
-
-function LibSort:Unregister(addonName, name)
-	if not name then
-		self.RegisteredCallbacks[addonName] = nil
-		self.DefaultOrdersHigh[addonName] = nil
-		self.DefaultOrdersLow[addonName] = nil
-		return
-	end
-
-	if self.RegisteredCallbacks[addonName] then
-		self.RegisteredCallbacks[addonName][name] = nil
-	end
-end
-
-function LibSort:Register(addonName, name, desc, key, func, dataType)
-	if not dataType then dataType = "isNumeric" end
-	if not self.RegisteredCallbacks[addonName] then self.RegisteredCallbacks[addonName] = {} table.insert(self.AddonOrder, addonName) end
-	self.RegisteredCallbacks[addonName][name] = {key = makePrefix(addonName)..key, func = func, desc = desc, dataType = dataType}
-	if not self.DefaultOrdersHigh[addonName] then self.DefaultOrdersHigh[addonName] = {} end
-	table.insert(self.DefaultOrdersHigh[addonName], name)
-	self:InjectKeys()
-end
-
-function LibSort:RegisterNumeric(addonName, name, desc, key, func)
-	self:Register(addonName, name, desc, key, func, "isNumeric")
-end
-
-function LibSort:RegisterBoolean(addonName, name, desc, key, func)
-	self:Register(addonName, name, desc, key, func, "isBoolean")
-end
-
-function LibSort:RegisterString(addonName, name, desc, key, func)
-	self:Register(addonName, name, desc, key, func, "isString")
-end
-
-function LibSort:RegisterDefaultOrder(addonName, keyTableLow, keyTableHigh)
-	self.DefaultOrdersHigh[addonName] = keyTableHigh
-	self.DefaultOrdersLow[addonName] = keyTableLow
-	self:ReOrderKeys()
-end
-
-function LibSort:SetDebugging(flag)
-	self.isDebugging = flag
-end
diff --git a/Libs/LibSort/README.md b/Libs/LibSort/README.md
deleted file mode 100644
index f1fb4ef..0000000
--- a/Libs/LibSort/README.md
+++ /dev/null
@@ -1,133 +0,0 @@
-#LibSort 1.0
-
-**Table of Contents**
-- [Rationale](#user-content-rationale)
-    - [API](#user-content-api)
-        - [Register](#user-content-register)
-        - [RegisterNumeric](#user-content-registernumeric)
-        - [RegisterBoolean](#user-content-registerboolean)
-        - [RegisterString](#user-content-registerstring)
-        - [Unregister](#user-content-unregister)
-        - [RegisterDefaultOrder](#user-content-registerdefaultorder)
-
-##Rationale
-
-Currently, the way ESO sorts items is essentially by column, you have a data point for each item, eg, **name** and you sort the list of objects by that data point.
-
-One thing that this default sorting mechanism offers, however, is a tiebreaker option. If we're sorting by **name** and a tiebreaker is required, because we are comparing two items with the same name, it falls to the tiebreaker datapoint to determine order of result, eg **stackSize**
-
-Now the general sorting of items in the real world doesn't just fall to a single data point, or two. It generally requires a series of different datapoints to sort by, and we can take advantage of this 'tiebreaker' to
-chain together lists of different datapoints to sort by. So we can sort by **Name**, then by **StackSize**, then by **SlotId**.
-
-That's well and fine for what's existing in the current set of datapoints, however we have access to a lot more information about the item than is currently being stored.
-
-To do this, however, we need to inject the required datapoints into the list object so that it has the required information to process the sort order as ascertained by our adjustment of how the tiebreakers chain together.
-
-First we prehook ChangeSort. This will allow us to pick out the inventory being looked at, process the entries in there to inject the appropriate information, and then pass back to the original ChangeSort for the actual sorting.
-
-We now have information about the item, where it's from (*slotType*) and where it is (*bag* and *index*)
-
-And thanks to the new API, we have two new functions that will return information about the item in regards to what sort of weapon or armour it is.
-
-So as an example, we'll use the new Weapon info function to inject data to allow the game to sort by weapontype
-
-	GetItemWeaponType(link)
-
-is the function we're using to obtain the information required.
-
-Or at least through
-
-	local link = GetItemLink(bag, index)
-	local weaponType = GetItemWeaponType(link)
-
-If we then inject this information into the data object
-
-	control:GetParent().dataEntry.data.weaponType = weaponType
-
-we can then include another entry into the sortKeys for default header
-
-	local sortKeys = ZO_Inventory_GetDefaultHeaderSortKeys()
-	sortKeys["weaponType"] = {isNumeric = true, tiebreaker = "name"}
-
-and we will end up sorting by the type of weapon returned by that function. (Note that as it's a pure number, and not necessarily in the order you may want, you'll have to actually adjust the real value of the datapoint to something more suitable)
-
----
-
-In any case, now that we know what we need to do, this library should do most of the heavy lifting for you. Chances are I'll have to give it it's own Settings panel so people can reorder the sort order as they wish, but you should be able to register your addon to allow data injection and process the index/bag combinations to store whatever datapoints you want.
-
----
-##API
-
-###Register
-This will register a numeric sortKey
-
-    LibSort:Register(addonName, name, desc, key, func)
-
-(Note this is an alias for **RegisterNumeric** and will assume a numeric sortKey)
-- *addonName* - The name of the registering addon
-    + Example: "Item Sort"
-- *name* - A unique registration name
-    + Example: "ISWeaponSort"
-- *desc* - A description of how the sort applies
-    + Example: "Will sort by Weapon Type"
-- *key* - A unique key used to identify the datapoint
-    + Example: "weaponType"
-- *func* - The function to call to retrieve the sort value. Function signature **needs** to be (slotType, bag, index)
-    + Example: ItemSort.WeaponSort
-
-###RegisterNumeric
-This will register a numeric sortKey
-
-    LibSort:RegisterNumeric(addonName, name, desc, key, func)
-Arguments as above
-
-###RegisterBoolean
-This will register a boolean sortKey
-
-    LibSort:RegisterBoolean(addonName, name, desc, key, func)
-Arguments as above
-
-###RegisterString
-This will register a string sortKey
-
-    LibSort:RegisterString(addonName, name, desc, key, func)
-Arguments as above
-
-###Unregister
-This will unregister a sortKey registration
-
-    LibSort:Unregister(addonName, name)
-
-- *addonName* - The name of the registering addon
-    + Example: "Item Sort"
-- *name* - A unique registration name
-    + Example: "ISWeaponSort"
-
-###RegisterDefaultOrder
-Your addon may have multiple registrations, and this function will allow you to indicate what order you want them in as a block. Call this function *after* you have completed your registrations
-
-There are two tables you can pass in, for *low level* and *high level* keys.
-
-- Low level keys are values that are unique to certain types of items, like weaponType, and armourType.
-- High level keys are those linked to values that are common across larger swathes of items, like item level, or name.
-
-
-If you separate your keys in the two tables, LibSort will first chain all the low level keys before all high level keys, so that multiple addons can apply sort orders without getting cut off. (It's highly recommended that you split keys if you use high level definitions)
-
-Default behaviour, by not using this API call will be order of registration at a high level to avoid breaking other registrations, and thus may not work as you expect, so make sure you set it.
-
-    LibSort:RegisterDefaultOrder(addonName, keyTableLow, keyTableHigh)
-
-- *addonName* -The name of the registering addon
-    + Example: "Item Sort"
-- *keyTableLow* - A table indicating the order of low level sortKeys for this addon
-    + Example: {"weaponType", "armorEquipType", "armorType"}
-- *keyTableHigh* - **Optional** A table indicating of the order of high level sortKeys for this addon
-    + Example: {"subjectiveItemLevel"}
-
-###SetDebugging
-Set the debug flag for the library. Not actually used atm, but for future stuff.
-
-    LibSort:SetDebugging(flag)
-
-- *flag* - a boolean indicating if you wish to have debug messages
\ No newline at end of file
diff --git a/MrPlow.lua b/MrPlow.lua
index 8be46a9..2e37ac6 100644
--- a/MrPlow.lua
+++ b/MrPlow.lua
@@ -1,6 +1,6 @@
 MrPlow = {}

-local LibSort = LibStub:GetLibrary("LibSort-1.0")
+local LibSort, minor = LibStub:GetLibrary("LibSort-1.0")

 local watchedSlots = {[SLOT_TYPE_GUILD_BANK_ITEM] = true, [SLOT_TYPE_ITEM] = true, [SLOT_TYPE_BANK_ITEM] = true }

@@ -45,6 +45,7 @@ local ARMOUR_ORDER = {
 	[EQUIP_TYPE_TWO_HAND] = 13,
 	[EQUIP_TYPE_COSTUME] = 14,
 }
+
 local ITEM_TYPE_ORDER = {
 	[ITEMTYPE_WEAPON] = 					1,
 	[ITEMTYPE_ARMOR] = 						2,
@@ -107,58 +108,58 @@ local ENCHANTING_RUNE_ORDER = {
 }

 function MrPlow:Loaded(...)
-	local eventCode, addonName = ...
-	if addonName ~= "MrPlow" then return end
+   local eventCode, addonName = ...
+   if addonName ~= "MrPlow" then return end

-	LibSort:Register("Item Sort", "Item Type", "The type of item", "itemType", function(...) return MrPlow:ItemType(...) end)
-	LibSort:Register("Item Sort", "Weapon Type", "The type of weapon", "weaponType", function(...) return MrPlow:WeaponType(...) end)
-	LibSort:Register("Item Sort", "Armour Equip Type", "The type of armour", "armorEquipType", function(...) return MrPlow:ArmourEquipType(...) end)
-	LibSort:Register("Item Sort", "Armour Type", "The weight of armour", "armorType", function(...) return MrPlow:ArmorType(...) end)
-	LibSort:Register("Item Sort", "Crafting Type", "The crafting type of an item", "craftingType", function(...) return MrPlow:CraftingType(...) end)
+   LibSort:Register("Item Sort", "Item Type", "The type of item", "itemType", function(...) return MrPlow:ItemType(...) end)
+   LibSort:Register("Item Sort", "Weapon Type", "The type of weapon", "weaponType", function(...) return MrPlow:WeaponType(...) end)
+   LibSort:Register("Item Sort", "Armour Equip Type", "The type of armour", "armorEquipType", function(...) return MrPlow:ArmourEquipType(...) end)
+   LibSort:Register("Item Sort", "Armour Type", "The weight of armour", "armorType", function(...) return MrPlow:ArmorType(...) end)
+   LibSort:Register("Item Sort", "Crafting Type", "The crafting type of an item", "craftingType", function(...) return MrPlow:CraftingType(...) end)

-	LibSort:Register("Item Sort", "Subjective Level", "The calculated subjective level", "subjectiveLevel", function(slotType, bag, index) return GetItemLevel(bag, index) end)
+   LibSort:Register("Item Sort", "Subjective Level", "The calculated subjective level", "subjectiveLevel", function(slotType, bag, index) return GetItemLevel(bag, index) end)

-	LibSort:RegisterDefaultOrder("Item Sort", {"Item Type", "Weapon Type", "Armour Equip Type", "Armour Type", "Crafting Type"}, {"Subjective Level"})
+   LibSort:RegisterDefaultOrder("Item Sort", {"Item Type", "Weapon Type", "Armour Equip Type", "Armour Type", "Crafting Type"}, {"Subjective Level"})
 end

 function MrPlow:ItemType(slotType, bag, index)
-	if watchedSlots[slotType] then
-		return ITEM_TYPE_ORDER[GetItemType(bag, index)] or 100
-	end
+   if watchedSlots[slotType] then
+      return ITEM_TYPE_ORDER[GetItemType(bag, index)] or 100
+   end
 end

 function MrPlow:WeaponType(slotType, bag, index)
-	if watchedSlots[slotType] then
-		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
-		if equipType > 0 then
-			if IS_WEAPON[equipType] then
-				return WEAPON_ORDER[GetItemWeaponType(GetItemLink(bag, index))]
-			end
-		end
-	end
+   if watchedSlots[slotType] then
+      local _, _, _, _, _, equipType = GetItemInfo(bag, index)
+      if equipType > 0 then
+         if IS_WEAPON[equipType] then
+            return WEAPON_ORDER[GetItemWeaponType(GetItemLink(bag, index))]
+         end
+      end
+   end
 end

 function MrPlow:ArmorType(slotType, bag, index)
-	if watchedSlots[slotType] then
-		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
-		if equipType <= 9 and equipType > 0  then
-			return GetItemArmorType(GetItemLink(bag, index))
-		end
-	end
+   if watchedSlots[slotType] then
+      local _, _, _, _, _, equipType = GetItemInfo(bag, index)
+      if equipType <= 9 and equipType > 0  then
+         return GetItemArmorType(GetItemLink(bag, index))
+      end
+   end
 end

 function MrPlow:ArmourEquipType(slotType, bag, index)
-	if watchedSlots[slotType] then
-		local _, _, _, _, _, equipType = GetItemInfo(bag, index)
-		return ARMOUR_ORDER[equipType]
-	end
+   if watchedSlots[slotType] then
+      local _, _, _, _, _, equipType = GetItemInfo(bag, index)
+      return ARMOUR_ORDER[equipType]
+   end
 end

 function MrPlow:CraftingType(slotType, bag, index)
-	if watchedSlots[slotType] then
-		local _, _, extra1 = GetItemCraftingInfo(bag, index)
-		return ENCHANTING_RUNE_ORDER[extra1 or 4]
-	end
+   if watchedSlots[slotType] then
+      local _, _, extra1 = GetItemCraftingInfo(bag, index)
+      return ENCHANTING_RUNE_ORDER[extra1 or 4]
+   end
 end

-EVENT_MANAGER:RegisterForEvent("MrPlowLoaded", EVENT_ADD_ON_LOADED, function(...) MrPlow:Loaded(...) end)
+EVENT_MANAGER:RegisterForEvent("MrPlowLoaded", EVENT_ADD_ON_LOADED, function(...) MrPlow:Loaded(...) end)
\ No newline at end of file
diff --git a/MrPlow.txt b/MrPlow.txt
index 1f45687..2ad68d1 100644
--- a/MrPlow.txt
+++ b/MrPlow.txt
@@ -1,10 +1,10 @@
 ## Title: |cFFFFB0MrPlow|r by |c00C000Wobin & CrazyDutchGuy|r
 ## Author: Wobin & CrazyDutchGuy
 ## Version: @project-version@
-## APIVersion: 100004
-## OptionalDependsOn: LibStub LibSort-1.0
+## APIVersion: 100007
+## OptionalDependsOn: LibStub LibSort

 Libs/LibStub/LibStub.lua
-Libs/LibSort/LibSort-1.0.lua
+Libs/LibSort-1.0/LibSort-1.0.lua

 MrPlow.lua