Quantcast

Major Library Changes

Xruptor [08-21-16 - 18:39]
Major Library Changes
-I've in the process of restructuring a lot of how BagSync is setup.  To that end I'm moving lots of the libraries as submodules so they are always updated.
-It's been a long time coming, but I've gone ahead and updated the LibItemSearch library to version 1.2 since BagSync has been using the old 1.0 for quite some time.
-Added the extra libraries that are needed for LibItemSearch-1.2 to work.  Special thanks to jailborc for all his work on the fork of Tuller's original code.
-Updated the class filter for the Search window to support the new LibItemSearch-1.2.  It still doesn't come with the library so I have to force the implementation of the filter.
-Some more cleaning here and there.
Filename
.gitmodules
BagSync.toc
libs/CustomSearch-1.0
libs/LibDataBroker-1.1
libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
libs/LibDataBroker-1.1/README.textile
libs/LibItemSearch-1.0/LibItemSearch-1.0.lua
libs/LibItemSearch-1.2
libs/Unfit-1.0
modules/minimap.lua
modules/search.lua
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..615f9e4
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "libs/CustomSearch-1.0"]
+	path = libs/CustomSearch-1.0
+	url = git://github.com/Jaliborc/CustomSearch-1.0.git
+[submodule "libs/LibItemSearch-1.2"]
+	path = libs/LibItemSearch-1.2
+	url = git://github.com/Jaliborc/LibItemSearch-1.2.git
+[submodule "libs/LibDataBroker-1.1"]
+	path = libs/LibDataBroker-1.1
+	url = git://github.com/tekkub/libdatabroker-1-1.git
+[submodule "libs/Unfit-1.0"]
+	path = libs/Unfit-1.0
+	url = git://github.com/Jaliborc/Unfit-1.0.git
diff --git a/BagSync.toc b/BagSync.toc
index a50ceda..9a7df90 100644
--- a/BagSync.toc
+++ b/BagSync.toc
@@ -9,7 +9,9 @@
 localization\localization.lua
 libs\LibStub\LibStub.lua
 libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
-libs\LibItemSearch-1.0\LibItemSearch-1.0.lua
+libs\Unfit-1.0\Unfit-1.0.lua
+libs\CustomSearch-1.0\CustomSearch-1.0.lua
+libs\LibItemSearch-1.2\LibItemSearch-1.2.lua
 libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
 libs\LibSimpleOptions-1.0\LibSimpleOptions-1.0.lua
 libs\tekKonfigScroll.lua
diff --git a/libs/CustomSearch-1.0 b/libs/CustomSearch-1.0
new file mode 160000
index 0000000..fe0d78b
--- /dev/null
+++ b/libs/CustomSearch-1.0
@@ -0,0 +1 @@
+Subproject commit fe0d78b4249eab4b2338126deb443777533831de
diff --git a/libs/LibDataBroker-1.1 b/libs/LibDataBroker-1.1
new file mode 160000
index 0000000..1a63ede
--- /dev/null
+++ b/libs/LibDataBroker-1.1
@@ -0,0 +1 @@
+Subproject commit 1a63ede0248c11aa1ee415187c1f9c9489ce3e02
diff --git a/libs/LibDataBroker-1.1/LibDataBroker-1.1.lua b/libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
deleted file mode 100644
index f47c0cd..0000000
--- a/libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
+++ /dev/null
@@ -1,90 +0,0 @@
-
-assert(LibStub, "LibDataBroker-1.1 requires LibStub")
-assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
-
-local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
-if not lib then return end
-oldminor = oldminor or 0
-
-
-lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
-lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
-local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
-
-if oldminor < 2 then
-	lib.domt = {
-		__metatable = "access denied",
-		__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
-	}
-end
-
-if oldminor < 3 then
-	lib.domt.__newindex = function(self, key, value)
-		if not attributestorage[self] then attributestorage[self] = {} end
-		if attributestorage[self][key] == value then return end
-		attributestorage[self][key] = value
-		local name = namestorage[self]
-		if not name then return end
-		callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
-		callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
-		callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
-		callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
-	end
-end
-
-if oldminor < 2 then
-	function lib:NewDataObject(name, dataobj)
-		if self.proxystorage[name] then return end
-
-		if dataobj then
-			assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
-			self.attributestorage[dataobj] = {}
-			for i,v in pairs(dataobj) do
-				self.attributestorage[dataobj][i] = v
-				dataobj[i] = nil
-			end
-		end
-		dataobj = setmetatable(dataobj or {}, self.domt)
-		self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
-		self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
-		return dataobj
-	end
-end
-
-if oldminor < 1 then
-	function lib:DataObjectIterator()
-		return pairs(self.proxystorage)
-	end
-
-	function lib:GetDataObjectByName(dataobjectname)
-		return self.proxystorage[dataobjectname]
-	end
-
-	function lib:GetNameByDataObject(dataobject)
-		return self.namestorage[dataobject]
-	end
-end
-
-if oldminor < 4 then
-	local next = pairs(attributestorage)
-	function lib:pairs(dataobject_or_name)
-		local t = type(dataobject_or_name)
-		assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
-
-		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
-		assert(attributestorage[dataobj], "Data object not found")
-
-		return next, attributestorage[dataobj], nil
-	end
-
-	local ipairs_iter = ipairs(attributestorage)
-	function lib:ipairs(dataobject_or_name)
-		local t = type(dataobject_or_name)
-		assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
-
-		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
-		assert(attributestorage[dataobj], "Data object not found")
-
-		return ipairs_iter, attributestorage[dataobj], 0
-	end
-end
diff --git a/libs/LibDataBroker-1.1/README.textile b/libs/LibDataBroker-1.1/README.textile
deleted file mode 100644
index ef16fed..0000000
--- a/libs/LibDataBroker-1.1/README.textile
+++ /dev/null
@@ -1,13 +0,0 @@
-LibDataBroker is a small WoW addon library designed to provide a "MVC":http://en.wikipedia.org/wiki/Model-view-controller interface for use in various addons.
-LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon.
-Plugins can provide data into a simple table, and display addons can receive callbacks to refresh their display of this data.
-LDB also provides a place for addons to register "quicklaunch" functions, removing the need for authors to embed many large libraries to create minimap buttons.
-Users who do not wish to be "plagued" by these buttons simply do not install an addon to render them.
-
-Due to it's simple generic design, LDB can be used for any design where you wish to have an addon notified of changes to a table.
-
-h2. Links
-
-* "API documentation":http://github.com/tekkub/libdatabroker-1-1/wikis/api
-* "Data specifications":http://github.com/tekkub/libdatabroker-1-1/wikis/data-specifications
-* "Addons using LDB":http://github.com/tekkub/libdatabroker-1-1/wikis/addons-using-ldb
diff --git a/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua b/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua
deleted file mode 100644
index ab83398..0000000
--- a/libs/LibItemSearch-1.0/LibItemSearch-1.0.lua
+++ /dev/null
@@ -1,480 +0,0 @@
---[[
-	ItemSearch
-		An item text search engine of some sort
-
-	Grammar:
-		<search> 			:=	<intersect search>
-		<intersect search> 	:=	<union search> & <union search> ; <union search>
-		<union search>		:=	<negatable search>  | <negatable search> ; <negatable search>
-		<negatable search> 	:=	!<primitive search> ; <primitive search>
-		<primitive search>	:=	<tooltip search> ; <quality search> ; <type search> ; <text search>
-		<tooltip search>	:=  bop ; boa ; bou ; boe ; quest
-		<quality search>	:=	q<op><text> ; q<op><digit>
-		<ilvl search>		:=	ilvl<op><number>
-		<type search>		:=	t:<text>
-		<text search>		:=	<text>
-		<item set search>	:=	s:<setname> (setname can be * for all sets)
-		<op>				:=  : | = | == | != | ~= | < | > | <= | >=
---]]
-
-local Lib = LibStub:NewLibrary('LibItemSearch-1.0', 9)
-if not Lib then
-  return
-else
-  Lib.searchTypes = Lib.searchTypes or {}
-end
-
-
---[[ Locals ]]--
-
-local tonumber, select, split = tonumber, select, strsplit
-local function useful(a) -- check if the search has a decent size
-  return a and #a >= 1
-end
-
-local function compare(op, a, b)
-  if op == '<=' then
-    return a <= b
-  end
-
-  if op == '<' then
-    return a < b
-  end
-
-  if op == '>' then
-    return a > b
-  end
-
-  if op == '>=' then
-    return a >= b
-  end
-
-  return a == b
-end
-
-local function match(search, ...)
-  for i = 1, select('#', ...) do
-    local text = select(i, ...)
-    if text and text:lower():find(search) then
-      return true
-    end
-  end
-  return false
-end
-
-
---[[ User API ]]--
-
-function Lib:Find(itemLink, search)
-	if not useful(search) then
-		return true
-	end
-
-	if not itemLink then
-		return false
-	end
-
-  return self:FindUnionSearch(itemLink, split('\124', search:lower()))
-end
-
-
---[[ Top-Layer Processing ]]--
-
--- union search: <search>&<search>
-function Lib:FindUnionSearch(item, ...)
-	for i = 1, select('#', ...) do
-		local search = select(i, ...)
-		if useful(search) and self:FindIntersectSearch(item, split('\038', search)) then
-      		return true
-		end
-	end
-end
-
-
--- intersect search: <search>|<search>
-function Lib:FindIntersectSearch(item, ...)
-	for i = 1, select('#', ...) do
-		local search = select(i, ...)
-		if useful(search) and not self:FindNegatableSearch(item, search) then
-        	return false
-		end
-	end
-	return true
-end
-
-
--- negated search: !<search>
-function Lib:FindNegatableSearch(item, search)
-  local negatedSearch = search:match('^[!~][%s]*(.+)$')
-  if negatedSearch then
-    return not self:FindTypedSearch(item, negatedSearch)
-  end
-  return self:FindTypedSearch(item, search, true)
-end
-
-
---[[
-     Search Types:
-      easly defined search types
-
-      A typed search object should look like the following:
-        {
-          string id
-            unique identifier for the search type,
-
-          string searchCapture = function canSearch(self, search)
-            returns a capture if the given search matches this typed search
-
-          bool isMatch = function findItem(self, itemLink, searchCapture)
-            returns true if <itemLink> is in the search defined by <searchCapture>
-          }
---]]
-
-function Lib:RegisterTypedSearch(object)
-	self.searchTypes[object.id] = object
-end
-
-function Lib:GetTypedSearches()
-	return pairs(self.searchTypes)
-end
-
-function Lib:GetTypedSearch(id)
-	return self.searchTypes[id]
-end
-
-function Lib:FindTypedSearch(item, search, default)
-  if not useful(search) then
-    return default
-  end
-
-  local tag, rest = search:match('^[%s]*(%w+):(.*)$')
-  if tag then
-    if useful(rest) then
-      search = rest
-    else
-      return default
-    end
-  end
-
-  local operator, search = search:match('^[%s]*([%>%<%=]*)[%s]*(.*)$')
-  if useful(search) then
-    operator = useful(operator) and operator
-  else
-    return default
-  end
-
-  if tag then
-    tag = '^' .. tag
-    for id, searchType in self:GetTypedSearches() do
-      if searchType.tags then
-        for _, value in pairs(searchType.tags) do
-          if value:find(tag) then
-            return self:UseTypedSearch(searchType, item, operator, search)
-          end
-        end
-      end
-    end
-  else
-    for id, searchType in self:GetTypedSearches() do
-      if not searchType.onlyTags and self:UseTypedSearch(searchType, item, operator, search) then
-        return true
-      end
-    end
-    return false
-  end
-
-  return default
-end
-
-function Lib:UseTypedSearch(searchType, item, operator, search)
-  local capture1, capture2, capture3 = searchType:canSearch(operator, search)
-  if capture1 then
-    if searchType:findItem(item, operator, capture1, capture2, capture3) then
-      return true
-    end
-  end
-end
-
-
---[[ Item name ]]--
-
-Lib:RegisterTypedSearch{
-  id = 'itemName',
-  tags = {'n', 'name'},
-
-	canSearch = function(self, operator, search)
-		return not operator and search
-	end,
-
-	findItem = function(self, item, _, search)
-		local name = item:match('%[(.-)%]')
-		return match(search, name)
-	end
-}
-
-
---[[ Item type, subtype and equiploc ]]--
-
-Lib:RegisterTypedSearch{
-	id = 'itemType',
-	tags = {'t', 'type', 'slot'},
-
-	canSearch = function(self, operator, search)
-		return not operator and search
-	end,
-
-	findItem = function(self, item, _, search)
-		local type, subType, _, equipSlot = select(6, GetItemInfo(item))
-		return match(search, type, subType, _G[equipSlot])
-	end
-}
-
-
---[[ Item quality ]]--
-
-local qualities = {}
-for i = 0, #ITEM_QUALITY_COLORS do
-  qualities[i] = _G['ITEM_QUALITY' .. i .. '_DESC']:lower()
-end
-
-Lib:RegisterTypedSearch{
-	id = 'itemQuality',
-	tags = {'q', 'quality'},
-
-	canSearch = function(self, _, search)
-		for i, name in pairs(qualities) do
-		  if name:find(search) then
-			return i
-		  end
-		end
-	end,
-
-	findItem = function(self, link, operator, num)
-		local quality = select(3, GetItemInfo(link))
-		return compare(operator, quality, num)
-	end,
-}
-
-
---[[ Item level ]]--
-
-Lib:RegisterTypedSearch{
-	id = 'itemLevel',
-	tags = {'l', 'level', 'lvl'},
-
-	canSearch = function(self, _, search)
-		return tonumber(search)
-	end,
-
-	findItem = function(self, link, operator, num)
-		local lvl = select(4, GetItemInfo(link))
-		if lvl then
-			return compare(operator, lvl, num)
-		end
-	end,
-}
-
-
---[[ Tooltip searches ]]--
-
-local tooltipCache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end})
-local tooltipScanner = _G['LibItemSearchTooltipScanner'] or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate')
-
-local function link_FindSearchInTooltip(itemLink, search)
-	local itemID = itemLink:match('item:(%d+)')
-	if not itemID then
-		return
-	end
-
-	local cachedResult = tooltipCache[search][itemID]
-	if cachedResult ~= nil then
-		return cachedResult
-	end
-
-	tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE')
-	tooltipScanner:SetHyperlink(itemLink)
-
-	local result = false
-	if tooltipScanner:NumLines() > 1 and _G[tooltipScanner:GetName() .. 'TextLeft2']:GetText() == search then
-		result = true
-	elseif tooltipScanner:NumLines() > 2 and _G[tooltipScanner:GetName() .. 'TextLeft3']:GetText() == search then
-		result = true
-	end
-
-	tooltipCache[search][itemID] = result
-	return result
-end
-
-
-Lib:RegisterTypedSearch{
-	id = 'bindType',
-
-	canSearch = function(self, _, search)
-		return self.keywords[search]
-	end,
-
-	findItem = function(self, itemLink, _, search)
-		return search and link_FindSearchInTooltip(itemLink, search)
-	end,
-
-	keywords = {
-    		['soulbound'] = ITEM_BIND_ON_PICKUP,
-    		['bound'] = ITEM_BIND_ON_PICKUP,
-		['boe'] = ITEM_BIND_ON_EQUIP,
-		['bop'] = ITEM_BIND_ON_PICKUP,
-		['bou'] = ITEM_BIND_ON_USE,
-		['quest'] = ITEM_BIND_QUEST,
-		['boa'] = ITEM_BIND_TO_BNETACCOUNT
-	}
-}
-
-Lib:RegisterTypedSearch{
-	id = 'tooltip',
-	tags = {'tt', 'tip', 'tooltip'},
-	onlyTags = true,
-
-	canSearch = function(self, _, search)
-		return search
-	end,
-
-	findItem = function(self, link, _, search)
-		tooltipScanner:SetOwner(UIParent, 'ANCHOR_NONE')
-		tooltipScanner:SetHyperlink(link)
-
-		for i = 1, tooltipScanner:NumLines() do
-			local text =  _G[tooltipScanner:GetName() .. 'TextLeft' .. i]:GetText():lower()
-
-			if text:find(search) then
-				return true
-			end
-		end
-
-		return false
-	end,
-}
-
-
---[[ Equipment sets ]]--
-
---Placeholder variables; will be replaced with references to the addon-appropriate handlers at runtime
-local ES_FindSets, ES_CheckItem
-
---Helper: Global Pattern Matching Function (matches ANY set name if search is *, or the EXACT set name if exactMatch is true, or any set name STARTING with the provided search terms if exactMatch is false (this means it will not match in middle of strings). all equipment set searches below use this function to FIRST try to find a set with the EXACT name entered, and if that fails they'll look for all sets that START with the search term, using recursive calls.
-local function ES_TrySetName(setName, search, exactMatch)
-	return (search == '*') or (exactMatch and setName:lower() == search) or (not exactMatch and setName:lower():sub(1,strlen(search)) == search)
-end
-
---Addon Support: ItemRack
-if IsAddOnLoaded('ItemRack') then
-	function ES_FindSets(setList, search, exactMatch)
-		for setName, _ in pairs(ItemRackUser.Sets) do
-			if ES_TrySetName(setName, search, exactMatch) then
-				if (search ~= '*') or (search == '*' and setName:sub(1,1) ~= '~') then --note: this additional tilde check skips internal ItemRack sets when doing a global set search (internal sets are prefixed with tilde, such as ~Unequip, and they contain temporary data that should not be part of a global search)
-					table.insert(setList, setName)
-				end
-			end
-		end
-		if (search ~= '*') and exactMatch and #setList == 0 then --if we just finished an exact, non-global (not "*"), name match search and still have no results, try one more time with partial ("starts with") set name matching instead
-			ES_FindSets(setList, search, false)
-		end
-	end
-
-	local irSameID = (ItemRack and ItemRack.SameID or nil) --set up local reference for speed if they're an ItemRack user
-	function ES_CheckItem(itemLink, setList)
-		local itemID = string.match(itemLink or '','item:(%-?%d+)') or 0 --grab the baseID of the item we are searching for (we don't need the full itemString, since we'll only be doing a loose baseID comparison below)
-
-		for _, setName in pairs(setList) do
-			for _, irItemData in pairs(ItemRackUser.Sets[setName].equip) do --note: do not change this to ipairs() or it will abort scanning at empty slots in a set
-				--[[ commented out due to libItemSearch lacking a "best match before generic match" priority matching system, so we'll have to go for "generic match" only (below), which matches items that have the same base ItemID as items from the set, as ItemRack cannot guarantee that the stored ItemString will be valid anymore (if the user has modified the item since last saving the set)
-				if itemString == irItemData then -- strict match: perform a strict match to check if this is the *exact* same item (same gems, enchants, etc)
-					return true
-				end]]--
-
-				if irSameID(itemID, irItemData) then --loose match: use ItemRack's built-in "Base ItemID" comparison function to allow us to match any items that have the same base itemID (disregarding strict matching of gems, enchants, etc); due to libItemSearch limitations it's the best compromise and guarantees to always highlight the correct items even if we may catch some extras/duplicates that weren't part of the set
-					return true
-				end
-			end
-		end
-
-		return false
-	end
-
---Addon Support: Wardrobe
-elseif IsAddOnLoaded('Wardrobe') then
-	function ES_FindSets(setList, search, exactMatch)
-		for _, waOutfit in ipairs(Wardrobe.CurrentConfig.Outfit) do
-			if ES_TrySetName(waOutfit.OutfitName, search, exactMatch) then
-				table.insert(setList, waOutfit) --insert an actual reference to the matching set's data table, instead of just storing the /name/ of the set. we do this due to how Wardrobe works (all sets are in a numerically indexed table and storing the table offset would therefore be unreliable)
-			end
-		end
-		if (search ~= '*') and exactMatch and #setList == 0 then --if we just finished an exact, non-global (not "*"), name match search and still have no results, try one more time with partial ("starts with") set name matching instead
-			ES_FindSets(setList, search, false)
-		end
-	end
-
-	function ES_CheckItem(itemLink, setList)
-		local itemID = tonumber(string.match(itemLink or '','item:(%-?%d+)') or 0) --grab the baseID of the item we are searching for (we don't need the full itemString, since we'll only be doing a loose baseID comparison below)
-
-		for _, waOutfit in pairs(setList) do
-			for _, waItemData in pairs(waOutfit.Item) do
-				if (waItemData.IsSlotUsed == 1) and (waItemData.ItemID == itemID) then --loose match: compare the current item's baseID to the baseID of the set item
-					return true
-				end
-			end
-		end
-
-		return false
-	end
-
---Last Resort: Blizzard Equipment Manager
-else
-	function ES_FindSets(setList, search, exactMatch)
-		for i = 1, GetNumEquipmentSets() do
-			local setName = GetEquipmentSetInfo(i)
-			if ES_TrySetName(setName, search, exactMatch) then
-				table.insert(setList, setName)
-			end
-		end
-		if (search ~= '*') and exactMatch and #setList == 0 then --if we just finished an exact, non-global (not "*"), name match search and still have no results, try one more time with partial ("starts with") set name matching instead
-			ES_FindSets(setList, search, false)
-		end
-	end
-
-	function ES_CheckItem(itemLink, setList)
-		local itemID = tonumber(string.match(itemLink or '','item:(%-?%d+)') or 0) --grab the baseID of the item we are searching for (we don't need the full itemString, since we'll only be doing a loose baseID comparison below)
-
-		for _, setName in pairs(setList) do
-			local bzSetItemIDs = GetEquipmentSetItemIDs(setName)
-			for _, bzItemID in pairs(bzSetItemIDs) do --note: do not change this to ipairs() or it will abort scanning at empty slots in a set
-				if itemID == bzItemID then --loose match: compare the current item's baseID to the baseID of the set item
-					return true
-				end
-			end
-		end
-
-		return false
-	end
-end
-
-Lib:RegisterTypedSearch{
-	id = 'equipmentSet',
-	tags = {'s', 'set'},
-
-	canSearch = function(self, operator, search)
-		return not operator and search
-	end,
-
-	findItem = function(self, itemLink, _, search)
-		--this is an item-set search and we know that the only items that can possibly match will be *equippable* items, so we'll short-circuit the response for non-equippable items to speed up searches.
-		if not IsEquippableItem(itemLink) then return false end
-
-		--default to matching *all* equipment sets if no set name has been provided yet
-		if search == '' then search = '*' end
-
-		--generate a list of all equipment sets whose names begin with the search term (or a single set if an exact set name match is found), then look for our item in those equipment sets
-		local setList = {}
-		ES_FindSets(setList, search, true)
-		if #setList == 0 then return false end
-		return ES_CheckItem(itemLink, setList)
-	end,
-}
\ No newline at end of file
diff --git a/libs/LibItemSearch-1.2 b/libs/LibItemSearch-1.2
new file mode 160000
index 0000000..50231da
--- /dev/null
+++ b/libs/LibItemSearch-1.2
@@ -0,0 +1 @@
+Subproject commit 50231da80984e21f894f3ced0bea4480907f632f
diff --git a/libs/Unfit-1.0 b/libs/Unfit-1.0
new file mode 160000
index 0000000..d769a30
--- /dev/null
+++ b/libs/Unfit-1.0
@@ -0,0 +1 @@
+Subproject commit d769a3050a9c2c2f84a88a4cf12cb0135993df52
diff --git a/modules/minimap.lua b/modules/minimap.lua
index 9da8a1e..ba2383d 100644
--- a/modules/minimap.lua
+++ b/modules/minimap.lua
@@ -1,5 +1,4 @@
 --Minimap Button for BagSync
---So people can stop PESTERING me about a dang button, why can't they just use DataBroker sheesh

 local L = BAGSYNC_L

diff --git a/modules/search.lua b/modules/search.lua
index 48e3d2a..4bc30b7 100644
--- a/modules/search.lua
+++ b/modules/search.lua
@@ -5,53 +5,36 @@ local currentRealm = select(2, UnitFullName("player"))
 local GetItemInfo = _G["GetItemInfo"]
 local currentPlayer = UnitName("player")

-local ItemSearch = LibStub("LibItemSearch-1.0")
+local ItemSearch = LibStub("LibItemSearch-1.2")
 local bgSearch = CreateFrame("Frame","BagSync_SearchFrame", UIParent)

---add class search
-local tooltipScanner = _G["LibItemSearchTooltipScanner"] or CreateFrame("GameTooltip", "LibItemSearchTooltipScanner", UIParent, "GameTooltipTemplate")
-local tooltipCache = setmetatable({}, {__index = function(t, k) local v = {} t[k] = v return v end})
+local scanner = LibItemSearchTooltipScanner or CreateFrame('GameTooltip', 'LibItemSearchTooltipScanner', UIParent, 'GameTooltipTemplate')
+
+--add classes to the LibItemSearch-1.2
+ItemSearch.Filters.class = {
+	tags = {'c', 'class'},

-ItemSearch:RegisterTypedSearch{
-	id = "classRestriction",
-	tags = {"c", "class"},
-
 	canSearch = function(self, _, search)
 		return search
 	end,
-
-	findItem = function(self, link, _, search)
-		if link:find("battlepet") then return false end
-
-		local itemID = link:match("item:(%d+)")
-		if not itemID then
-			return
-		end
-
-		local cachedResult = tooltipCache[search][itemID]
-		if cachedResult ~= nil then
-			return cachedResult
-		end
-
-		tooltipScanner:SetOwner(UIParent, "ANCHOR_NONE")
-		tooltipScanner:SetHyperlink(link)
-
-		local result = false
-
-		local pattern = string.gsub(ITEM_CLASSES_ALLOWED:lower(), "%%s", "(.+)")
-
-		for i = 1, tooltipScanner:NumLines() do
-			local text =  _G[tooltipScanner:GetName() .. "TextLeft" .. i]:GetText():lower()
-			local textChk = string.find(text, pattern)

-			if textChk and tostring(text):find(search) then
-				result = true
+	match = function(self, link, _, search)
+		if link:find('item:') then
+			scanner:SetOwner(UIParent, 'ANCHOR_NONE')
+			scanner:SetHyperlink(link)
+
+			local pattern = string.gsub(ITEM_CLASSES_ALLOWED:lower(), "%%s", "(.+)")
+
+			for i = 1, scanner:NumLines() do
+				local text =  _G[scanner:GetName() .. 'TextLeft' .. i]:GetText():lower()
+				local textChk = string.find(text, pattern)
+
+				if textChk and Search:Find(search, _G[scanner:GetName() .. 'TextLeft' .. i]:GetText()) then
+					return true
+				end
 			end
 		end
-
-		tooltipCache[search][itemID] = result
-		return result
-	end,
+	end
 }

 local function LoadSlider()
@@ -224,7 +207,7 @@ local function DoSearch()
 												tempList[dblink] = dName
 												count = count + 1
 											--we found a match
-											elseif not playerSearch and not tempList[dblink] and ItemSearch:Find(dItemLink, searchStr) then
+											elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
 												table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity } )
 												tempList[dblink] = dName
 												count = count + 1
@@ -258,7 +241,7 @@ local function DoSearch()
 											tempList[dblink] = dName
 											count = count + 1
 										--we found a match
-										elseif not playerSearch and not tempList[dblink] and ItemSearch:Find(dItemLink, searchStr) then
+										elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
 											table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity } )
 											tempList[dblink] = dName
 											count = count + 1