changed folder structure - hopefully fixes minion

manavortex [04-17-18 - 07:14]
changed folder structure - hopefully fixes minion
Filename
DASContextMenu.lua
DASData.lua
DASHelper.lua
DASMenu.lua
DASUserSettingsAdapter.lua
DailyAutoShare.txt
DailyAutoShare.xml
DailyAutoShare/DASContextMenu.lua
DailyAutoShare/DASData.lua
DailyAutoShare/DASHelper.lua
DailyAutoShare/DASMenu.lua
DailyAutoShare/DASUserSettingsAdapter.lua
DailyAutoShare/DailyAutoShare.txt
DailyAutoShare/DailyAutoShare.xml
DailyAutoShare/DasChatMessage.lua
DailyAutoShare/DasGui.lua
DailyAutoShare/DasGuiStringBuilder.lua
DailyAutoShare/DasQuestAccept.lua
DailyAutoShare/DasTooltip.lua
DailyAutoShare/libs/LibAddonMenu-2.0/LICENSE
DailyAutoShare/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/button.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/checkbox.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/colorpicker.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/custom.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/description.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/desktop.ini
DailyAutoShare/libs/LibAddonMenu-2.0/controls/divider.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/dropdown.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/editbox.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/header.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/iconpicker.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/panel.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/slider.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/submenu.lua
DailyAutoShare/libs/LibAddonMenu-2.0/controls/texture.lua
DailyAutoShare/libs/LibCustomTitles/LibCustomTitles.lua
DailyAutoShare/libs/LibStub/LibStub.lua
DailyAutoShare/locale/de.lua
DailyAutoShare/locale/en.lua
DailyAutoShare/locale/fr.lua
DailyAutoShare/locale/jp.lua
DailyAutoShare/locale/ru.lua
DailyAutoShare/questData/00_ids.lua
DailyAutoShare/questData/ClockworkCity.lua
DailyAutoShare/questData/Cyrodiil.lua
DailyAutoShare/questData/Festival.lua
DailyAutoShare/questData/GoldCoast.lua
DailyAutoShare/questData/GuildQuests.lua
DailyAutoShare/questData/HewsBane.lua
DailyAutoShare/questData/Morrowind.lua
DailyAutoShare/questData/Wrothgar.lua
DailyAutoShare/startup.lua
DailyAutoShare/textures/Thumbs.db
DailyAutoShare/textures/accept_down.dds
DailyAutoShare/textures/accept_up.dds
DailyAutoShare/textures/down_down.dds
DailyAutoShare/textures/down_over.dds
DailyAutoShare/textures/down_up.dds
DailyAutoShare/textures/invite_active.dds
DailyAutoShare/textures/invite_down.dds
DailyAutoShare/textures/invite_up.dds
DailyAutoShare/textures/reload_down.dds
DailyAutoShare/textures/reload_up.dds
DailyAutoShare/textures/share_down.dds
DailyAutoShare/textures/share_up.dds
DailyAutoShare/textures/speaker_down.dds
DailyAutoShare/textures/speaker_up.dds
DailyAutoShare/textures/speechbubble_down.dds
DailyAutoShare/textures/speechbubble_up.dds
DailyAutoShare/textures/up_down.dds
DailyAutoShare/textures/up_over.dds
DailyAutoShare/textures/up_up.dds
DailyAutoShare/textures/x_down.dds
DailyAutoShare/textures/x_up.dds
DailyAutoShare/xml/Bindings.xml
DasChatMessage.lua
DasGui.lua
DasGuiStringBuilder.lua
DasQuestAccept.lua
DasTooltip.lua
libs/LibAddonMenu-2.0/LICENSE
libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
libs/LibAddonMenu-2.0/controls/button.lua
libs/LibAddonMenu-2.0/controls/checkbox.lua
libs/LibAddonMenu-2.0/controls/colorpicker.lua
libs/LibAddonMenu-2.0/controls/custom.lua
libs/LibAddonMenu-2.0/controls/description.lua
libs/LibAddonMenu-2.0/controls/desktop.ini
libs/LibAddonMenu-2.0/controls/divider.lua
libs/LibAddonMenu-2.0/controls/dropdown.lua
libs/LibAddonMenu-2.0/controls/editbox.lua
libs/LibAddonMenu-2.0/controls/header.lua
libs/LibAddonMenu-2.0/controls/iconpicker.lua
libs/LibAddonMenu-2.0/controls/panel.lua
libs/LibAddonMenu-2.0/controls/slider.lua
libs/LibAddonMenu-2.0/controls/submenu.lua
libs/LibAddonMenu-2.0/controls/texture.lua
libs/LibCustomTitles/LibCustomTitles.lua
libs/LibStub/LibStub.lua
locale/de.lua
locale/en.lua
locale/fr.lua
locale/jp.lua
locale/ru.lua
questData/00_ids.lua
questData/ClockworkCity.lua
questData/Cyrodiil.lua
questData/Festival.lua
questData/GoldCoast.lua
questData/GuildQuests.lua
questData/HewsBane.lua
questData/Morrowind.lua
questData/Wrothgar.lua
startup.lua
textures/accept_down.dds
textures/accept_up.dds
textures/down_down.dds
textures/down_over.dds
textures/down_up.dds
textures/invite_active.dds
textures/invite_down.dds
textures/invite_up.dds
textures/reload_down.dds
textures/reload_up.dds
textures/share_down.dds
textures/share_up.dds
textures/speaker_down.dds
textures/speaker_up.dds
textures/speechbubble_down.dds
textures/speechbubble_up.dds
textures/up_down.dds
textures/up_over.dds
textures/up_up.dds
textures/x_down.dds
textures/x_up.dds
xml/Bindings.xml
diff --git a/DASContextMenu.lua b/DASContextMenu.lua
new file mode 100644
index 0000000..d8111e9
--- /dev/null
+++ b/DASContextMenu.lua
@@ -0,0 +1,106 @@
+local guiHeight = GuiRoot:GetHeight()
+local guiWidth = GuiRoot:GetWidth()
+
+local function getAnchorPos(control)
+	local menuWidth 	= ZO_Menu:GetWidth()
+	local menuHeight 	= ZO_Menu:GetWidth()
+
+	local controlRight 	= control:GetRight()
+	local controlLeft 	= control:GetLeft()
+	local controlTop 	= control:GetTop()
+
+	local isTooHigh = (controlTop + menuHeight) >= guiHeight
+
+	if DAS.GetTooltipRight() then
+		if (controlRight + menuWidth) >= guiWidth then
+			if isTooHigh then return BOTTOMRIGHT, TOPLEFT end
+			return TOPRIGHT, TOPLEFT
+		end
+	else
+		if (controlLeft - menuHeight) <= 0 then
+			if isTooHigh then return  TOPLEFT, TOPRIGHT end
+			return	TOPRIGHT, TOPLEFT
+		end
+	end
+	return	TOPLEFT, TOPRIGHT
+end
+
+function DAS.OnRightClick(control, verbose)
+
+	if nil == control then return end
+	local questName 	= control.dataQuestName
+	local journalIndex 	= control.dataJournalIndex
+	local bingoString 	= control.dataBingoString
+
+
+    local menuShowing = IsMenuVisisble() and GetMenuOwner() == control
+    ClearMenu()
+
+    if not menuShowing then
+        SetMenuSpacing(3)
+        SetMenuPad(10)
+        SetMenuMinimumWidth(185)
+		if control.dataQuestState ~= DAS_STATUS_COMPLETE then
+			AddCustomMenuItem(GetString(DAS_SI_SPAM_SINGLE),
+				function()
+					DAS.SpamChat(nil, questName)
+				end,
+				MENU_ADD_OPTION_LABEL
+			)
+		end
+		AddCustomMenuItem(GetString(DAS_SI_SPAM_VERBOSE),
+			function()
+					DAS.SpamChat(true, questName)
+				end,
+				MENU_ADD_OPTION_LABEL
+		)
+		if IsValidQuestIndex(control.dataJournalIndex) then
+			AddCustomMenuItem(GetString(DAS_SI_SHARE),
+				function() ShareQuest(journalIndex) end,
+				MENU_ADD_OPTION_LABEL
+			)
+			AddCustomMenuItem("* Focus",
+				function()
+					QUEST_TRACKER:ForceAssist(journalIndex)
+					DAS.RefreshLabels(false, true)
+				end,
+				MENU_ADD_OPTION_LABEL
+			)
+			AddCustomMenuItem(GetString(DAS_SI_ABANDON),
+				function()
+					AbandonQuest(journalIndex)
+					DAS.LogQuest(questName, false)
+					DAS.RefreshLabels(true)
+				end,
+				MENU_ADD_OPTION_LABEL
+			)
+		else
+			local key = (control.dataQuestState == DAS_STATUS_OPEN and DAS_SI_SETOPEN_TRUE) or DAS_SI_SETOPEN_FALSE
+			AddCustomMenuItem(GetString(key),
+				function()
+                    DAS.ToggleQuest(control)
+					DAS.RefreshLabels()
+                end,
+				MENU_ADD_OPTION_LABEL
+			)
+		end
+
+		local myAnchor, parentAnchor = getAnchorPos(control)
+
+        ZO_Menu:ClearAnchors()
+        ZO_Menu:SetAnchor(myAnchor, control, parentAnchor, 0, 3)
+		ShowMenu(control)
+
+	end
+
+
+
+
+end
+
+function DAS.InitRightclickMenu()
+	DAS_LinkHandlerBackup_OnLinkMouseUp = ZO_LinkHandler_OnLinkMouseUp
+	ZO_LinkHandler_OnLinkMouseUp = function(itemLink, button, control) DAS_HandleClickEvent(itemLink, button, control) end
+	ZO_PreHook('ZO_InventorySlot_OnMouseEnter', DAS_HandleMouseEnter)
+	ZO_PreHook('ZO_InventorySlot_ShowContextMenu', function(rowControl) DAS_HandleInventoryContextMenu(rowControl) end)
+end
\ No newline at end of file
diff --git a/DASData.lua b/DASData.lua
new file mode 100644
index 0000000..d7d63da
--- /dev/null
+++ b/DASData.lua
@@ -0,0 +1,151 @@
+local DAS = DailyAutoShare
+
+local p = DAS.debug
+
+DAS.subzones = {
+	-- Morrowind
+	[921]			= 849,		-- Khartag Point
+	[922]			= 849,		-- Zainsipilu
+	[923]			= 849,		-- Zainsipilu
+	[924]			= 849,		-- Zainsipilu
+
+    -- CC
+	[985]			= 980,		-- Halls of Regulation
+	[986]			= 980,		-- Shadow Cleft
+	[993]			= 980,		-- Planisphere
+
+    -- Gold Coast
+	[824]			= 823,		-- Hrota Cave
+
+    -- Wrothgar
+	[689]			= 684,		-- Nikolovara's Kennel
+	[690]			= 684,		--
+	[691]			= 684,		--
+	[692]			= 684,		--
+	[693]			= 684,		-- Argent Mine
+	[694]			= 684,		-- Argent Mine
+}
+
+DAS.festivals = {
+	[19 ] = "newLife",
+	[41 ] = "newLife",
+	[117] = "newLife",
+	[104] = "newLife",
+	[383] = "newLife",
+	[382] = "newLife",
+	[535] = "newLife",
+	[381] = "newLife",
+}
+
+function DAS.GetZoneId() return GetZoneId(GetUnitZoneIndex('player')) or 0 end
+function PrintZoneId() d(GetZoneId(GetUnitZoneIndex('player'))) end
+
+function DAS.GetZoneQuests(zoneId)
+	zoneId = zoneId or DAS.GetZoneId()
+    zoneId = DAS.subzones[zoneId] or zoneId
+	return DAS.shareables[zoneId] or {}
+end
+
+function DAS.RefreshFullBingoString()
+    local ret = ""
+    for _, questName in ipairs(DAS.GetActiveQuestNames()) do
+        ret = ret .. DAS.GetBingoStringFromQuestName(questName) .. " "
+    end
+    if (#ret > 0) then
+        ret = ret .. "+any"
+    end
+    DAS.fullBingoString = ret
+end
+
+function DAS.IsQuestActive(questName)
+
+	local zoneId 	= DAS.GetZoneId()
+	local questList = DAS.QuestLists[zoneId] or {}
+
+	for questListName, questListData in pairs(questList) do
+		if questListData[questName] then
+			return (DAS.GetQuestListItem(zoneId, questListName, "active"))
+		end
+	end
+	return true
+
+end
+
+function DAS.GetBingoIndexFromQuestName(questName)
+	for questIndex, checkQuestName in pairs(DAS.GetZoneQuests()) do
+		if questName == checkQuestName then
+			return questIndex
+		end
+	end
+	return 99
+end
+
+function DAS.GetBingoStringFromQuestName(questName)
+
+    local index = DAS.GetBingoIndexFromQuestName(questName)
+    local ret = ""
+	local zoneId = DAS.GetZoneId()
+	if index == 99 then return ret end
+
+	local bingoArray = DAS.bingo[zoneId] or {}
+    for bingoString, bingoIndex in pairs(bingoArray) do
+        if bingoIndex == index then ret = bingoString end
+    end
+    local bingoFallback = DAS.bingoFallback[zoneId] or {}
+    ret = bingoFallback[ret] or ret
+
+	if ret ~= "" then
+		if not(string.find(ret, "%+")) then ret = "+" .. ret end
+		if (string.find(ret, "%+%+"))  then ret.gsub("%+%+", "%+") end
+	end
+
+	return ret
+
+end
+
+function DAS.GetQuestNameFromIndex(bingoIndex)
+	return DAS.GetZoneQuests()[bingoIndex]
+end
+
+function DAS.GetQuestNameFromBingoString(bingoString)
+	local bingoIndex = GetBingoIndexFromMessage(bingoString)
+	if nil == bingoIndex then return end
+	return DAS.GetQuestNameFromIndex(bingoIndex)
+end
+
+function DAS.GetActiveQuestNames()
+	local ret = {}
+	local questLabel
+	for i=1, #DAS.labels do
+		questLabel = DAS.labels[i]
+		if not questLabel:IsHidden() and (questLabel.dataQuestState == DAS_STATUS_ACTIVE) or (questLabel.dataQuestState == DAS_STATUS_TRACKED) then
+			table.insert(ret, questLabel.dataQuestName)
+		end
+	end
+	return ret
+end
+
+function DAS.GetOpenQuestNames()
+	local ret = {}
+	local questLabel
+	for i=1, #DAS.labels do
+		questLabel = DAS.labels[i]
+		if (questLabel.dataQuestState == DAS_STATUS_OPEN) then
+			table.insert(ret, questLabel.dataQuestName)
+		end
+	end
+	return ret
+end
+
+function DAS.GetActiveQuestIndices(zoneId)
+    local zoneQuests = DAS.GetZoneQuests(zoneId)
+	local ret = {}
+	local questLabel
+	for i=1, #DAS.labels do
+		questLabel = DAS.labels[i]
+		if (questLabel.dataQuestState == DAS_STATUS_ACTIVE) then
+			table.insert(ret, questLabel.dataJournalIndex)
+		end
+	end
+	return ret
+end
diff --git a/DASHelper.lua b/DASHelper.lua
new file mode 100644
index 0000000..6a5b50f
--- /dev/null
+++ b/DASHelper.lua
@@ -0,0 +1,138 @@
+local DAS = DailyAutoShare
+
+function DAS.GetArrayEntry(array, key)
+	if nil == array or nil == key then return end
+	if nil ~= array[key] then return array[key] end
+	for i=1, #array do
+		if DAS.IsMatch(array[i], key) then return true end
+	end
+end
+
+function DAS.TryDisableAutoShare(fromName, messageText)
+	if type(messageText) ~= "string" then return false end
+	if (DAS.IsMatch(messageText, GetUnitName('player'))
+	or (DAS.IsMatch(messageText, DAS.GetBingoStringFromQuestName():gsub("+", ""))
+	and DAS.IsMatch(messageText "sharing")))
+	then
+		DAS.SetAutoShare(false)
+	end
+end
+
+local alreadySharing = false
+local questQueue = {}
+local function shareQuestQueue()
+    -- d("shareQuestQueue called with " .. tostring(#questQueue) .. " entries")
+    if #questQueue == 0 then
+        alreadySharing = false
+        return
+    end
+    alreadySharing = true
+    local questIndex = table.remove(questQueue, 1)
+    ShareQuest(questIndex)
+    zo_callLater(shareQuestQueue, 250)
+end
+
+function DAS.TryShareActiveDaily()
+    if not DAS.GetAutoShare() then return end
+    local activeQuestIndices = DAS.GetActiveQuestIndices()
+    for _, questIndex in ipairs(activeQuestIndices) do
+        if IsValidQuestIndex(questIndex) and not table.contains(questQueue, questIndex) then
+           table.insert(questQueue, questIndex)
+        end
+    end
+    if not alreadySharing then
+        shareQuestQueue()
+    end
+ end
+
+
+local function EscapeString(text)
+	if nil == text then return "" end
+	-- escape brackets
+	text = text:gsub('%(', ''):gsub('%)', '')
+	text = text:gsub('%[', ''):gsub('%]', '')
+	-- escape dots
+	text = text:gsub('%.', '%%.')
+	-- escape %
+	text = text:gsub("%%", "%%%%")
+	-- escape dashes
+	text = text:gsub("-", "")
+	return text or ""
+ end
+
+function DAS.IsMatch(param1, param2)
+
+	string1 = EscapeString(tostring(param1):lower())
+	string2 = EscapeString(tostring(param2):lower())
+
+	if #string1 == 0 or #string2 == 0 then return false end
+
+	return string.match(string1, string2) or string.match(string2, string2) or string1 == string2
+
+
+ end
+
+function DAS.FindInList(array, item)
+	if nil == item then return false end
+	for _,v in pairs(array) do
+		if v == item then return true end
+		if tostring(v):match(tostring(item)) then return true end
+
+    end
+	return false
+end
+
+function DAS.TryTriggerAutoAcceptInvite()
+	if DAS.GetAutoAcceptInviteInterval() then
+		DAS.SetAutoAcceptInvite(true)
+		zo_callLater(DAS.SetAutoAcceptInvite, DAS.GetAutoAcceptInviteInterval()*1000)
+	end
+end
+
+function DAS.HandleGroupMessage(fromDisplayName, messageText)
+	if DAS.IsMatch(messageText, "stop") then
+		DAS.TryDisableAutoShare(fromDisplayName, messageText)
+	end
+end
+
+function DAS.IsListeningInGuildChannel(guildNumber)
+	return ((guildNumber == DAS.GetGuildInviteNumber()) or DAS.GetListenInGuilds())
+end
+
+function DAS.CheckIfGroupMessage(channelType)
+	return DAS.FindInList({2, 3}, tonumber(channelType))
+end
+
+function DAS.CheckIfPublicMessage(channelType)
+	return nil ~= channelType and DAS.FindInList({CHAT_CHANNEL_SAY, CHAT_CHANNEL_ZONE, CHAT_CHANNEL_YELL}, tonumber(channelType))
+end
+
+function DAS.CheckIfGuildMessage(channelType)
+
+	if nil == channelType then return false end
+	local guildNumber = tonumber(channelType)- 11
+
+	if (guildNumber > 0 and guildNumber < 6) then
+		return ((guildNumber == DAS.GetGuildInviteNumber()) or DAS.GetListenInGuilds())
+	end
+	return false
+end
+
+function DAS.OpenDailyPresent()
+
+	local numCompleted 	= NonContiguousCount(DAS.GetShareableLog())
+	local numOpen 		= NonContiguousCount(DAS.GetZoneQuests())
+
+	if  (numCompleted < numOpen) then return true end
+
+	for entry, data in pairs(DAS.GetShareableLog()) do
+		if not data["completed"] then return true end
+	end
+
+	return false
+end
+
+function DAS.HasActiveDaily()
+	return #DAS.GetActiveQuestNames() > 0
+end
+
diff --git a/DASMenu.lua b/DASMenu.lua
new file mode 100644
index 0000000..5aaf4cc
--- /dev/null
+++ b/DASMenu.lua
@@ -0,0 +1,487 @@
+local DAS = DailyAutoShare
+
+local optionsData
+local questShareDefault
+
+function DAS.CreateMenu(savedVars, defaults)
+
+    questShareDefault = defaults.questShareString
+	local LAM = LibStub:GetLibrary("LibAddonMenu-2.0")
+	local panelData = {
+		type    = "panel",
+		name    = DAS.name,
+		displayname    = name,
+	 	author = DAS.author,
+		version = DAS.version,
+		slashCommand = "/das",
+	}
+
+	LAM:RegisterAddonPanel("DailyAutoShare_OptionsPanel", panelData)
+
+	optionsData = { -- optionsData
+		{ -- Use global configuration?
+			type    = "checkbox",
+			name    = "Turn on debugging?",
+			getFunc = function() return DAS.GetDebugMode() end,
+			setFunc = function(value) DAS.SetDebugMode(value) end
+		},
+
+		{ -- header: Use global variables?
+			type    = "header",
+			name    = "Use global variables?"
+		},
+		{ -- Use global configuration?
+			type    = "checkbox",
+			tooltip = "Use the same settings for all characters?",
+			name    = "Use global configuration?",
+			getFunc = function() return DAS.GetUseGlobalSettings() end,
+			setFunc = function(value) DAS.SetUseGlobalSettings(value) end
+			},
+		{ -- header: Show/Hide?
+			type    = "header",
+			name    = "Show/Hide?"
+		},
+		{ -- checkbox: Hide UI window
+			type    = "checkbox",
+			name    = "Hide UI window",
+			getFunc = function() return DAS.GetHidden() end,
+			setFunc = function(value) DAS.SetHidden(value) end
+		},
+		{ -- header: be elaborate?
+			type    = "header",
+			name    = "Speak English instead of bingo?"
+		},
+		{ -- checkbox: don't use bingo
+			type    = "checkbox",
+			name    = "Speak in whole sentences?",
+			tooltip = "While this is optional, you will sound far less ludicrous if you don't talk like a telegram.\nIf you don't know what that is, please get older before unchecking this box.",
+			getFunc = function() return not DAS.GetSpeakStupid() end,
+			setFunc = function(value) DAS.SetSpeakStupid(not value) end
+		},
+
+
+		{ -- header: activate add-on in...
+			type    = "submenu",
+			name    = "Activate auto quest stuff in...",
+			controls = {
+
+				{
+					type    = "submenu",
+					name    = "Clockwork City",
+					controls = {
+                        { -- checkbox: Clockwork City?
+                            type    = "checkbox",
+                            tooltip = "activate",
+                            name    = "Activate in Clockwork City?",
+                            getFunc = function() return DAS.GetActiveIn(980) end,
+                            setFunc = function(value)
+                                DAS.SetActiveIn(980, value)
+                                DAS.SetActiveIn(981, value)
+                                DAS.SetActiveIn(983, value)
+                            end
+                        },
+						{ -- header: CC Worldbosses
+							type    = "header",
+							name    = "Worldbosses"
+						},
+						{ -- checkbox: relic
+							type    = "checkbox",
+							tooltip = "Enable world boss dailies",
+							name    = "Enable?",
+							getFunc = function() return DAS.GetQuestListItem(980, "boss", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "boss", "active", value) end
+						},
+						{ -- checkbox: relic
+							type    = "checkbox",
+							name    = "Hide",
+							tooltip = "Don't show world boss dailies on UI list \nKeeps sharing on group invite",
+							getFunc = function() return DAS.GetQuestListItem(980, "boss", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "boss", "invisible", value) end
+						},
+						{ -- header: CC Slagtown gathering dailies
+							type    = "header",
+							name    = "Slagtown: Gathering dailies"
+						},
+						{ -- checkbox: Slagtown gathering dailies
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Slagtown gathering dailies?",
+							getFunc = function() return DAS.GetQuestListItem(980, "craft", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "craft", "active", value) end
+						},
+						{ -- checkbox: Hide Slagtown gathering dailies
+							type    = "checkbox",
+							name    = "Hide",
+							tooltip = "Don't show Slagtown gathering dailies on UI list",
+							getFunc = function() return DAS.GetQuestListItem(980, "craft", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "craft", "invisible", value) end
+						},
+						{ -- header: CC: Delves
+							type    = "header",
+							name    = "Clockwork City: Delves"
+						},
+						{ -- checkbox: delve
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Clockwork City delve dailies?",
+							getFunc = function() return DAS.GetQuestListItem(980, "delve", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "delve", "active", value) end
+						},
+						{ -- checkbox: Clockwork City: Delves
+							type    = "checkbox",
+							name    = "Hide?",
+							tooltip = "Don't show Clockwork City delve dailies on UI list",
+
+							getFunc = function() return DAS.GetQuestListItem(980, "delve", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "delve", "invisible", value) end
+						},
+						{ -- header: Vivec: Delves
+							type    = "header",
+							name    = "Clockwork City: Crow"
+						},
+						{ -- checkbox: Clockwork City crow
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Enable Clockwork City crow dailies?",
+							getFunc = function() return DAS.GetQuestListItem(980, "crow", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "crow", "active", value) end
+						},
+						{ -- checkbox: Clockwork City crow hide
+							type    = "checkbox",
+							name    = "Hide?",
+							tooltip = "Don't show Clockwork City crow dailies on UI list",
+							getFunc = function() return DAS.GetQuestListItem(980, "crow", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(980, "crow", "invisible", value) end
+						},
+					},
+				},
+				{ -- checkbox: Morrowind
+					type    = "checkbox",
+					tooltip = "Vvardenfell?",
+					name    = "Activate in Vvardenfell?",
+					getFunc = function() return DAS.GetActiveIn(849) end,
+					setFunc = function(value) DAS.SetActiveIn(849, value) end
+				},
+				{
+					type        = "submenu",
+					name        = "Vvardenfell",
+					controls    = {
+						{ -- header: Ashlander: Relics
+							type    = "header",
+							name    = "Ashlander: Relics"
+						},
+						{ -- checkbox: relic
+							type    = "checkbox",
+							tooltip = "Go relic hunting for the Urshilaku?",
+							name    = "Enable?",
+							getFunc = function() return DAS.GetQuestListItem(849, "relic", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "relic", "active", value) end
+						},
+						{ -- checkbox: relic
+							type    = "checkbox",
+							name    = "Hide",
+							tooltip = "Don't show Ashlander relic dailies on UI list \nKeeps sharing on group invite",
+							getFunc = function() return DAS.GetQuestListItem(849, "relic", "invisible")end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "relic", "invisible", value) end
+						},
+						{ -- header: Ashlander: Hunt
+							type    = "header",
+							name    = "Ashlander: Hunt"
+						},
+						{ -- checkbox: Wrothgar
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Ashlander hunt dailies?",
+							getFunc = function() return DAS.GetQuestListItem(849, "hunt", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "hunt", "active", value) end
+						},
+						{ -- checkbox: Wrothgar
+							type    = "checkbox",
+							name    = "Hide",
+							tooltip = "Don't show Ashlander hunt dailies on UI list",
+							getFunc = function() return DAS.GetQuestListItem(849, "hunt", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "hunt", "invisible", value) end
+						},
+						{ -- header: Vivec: Delves
+							type    = "header",
+							name    = "Vivec: Delves"
+						},
+						{ -- checkbox: Wrothgar
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Hall of Justice delve dailies?",
+							getFunc = function() return DAS.GetQuestListItem(849, "delve", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "delve", "active", value) end
+						},
+						{ -- checkbox: Vivec: Delves
+							type    = "checkbox",
+							name    = "Hide?",
+							tooltip = "Don't show Hall of Justice delve dailies on UI list",
+							getFunc = function() return DAS.GetQuestListItem(849, "delve", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "delve", "invisible", value) end
+						},
+						{ -- header: Vivec: Delves
+							type    = "header",
+							name    = "Vivec: Worldbosses"
+						},
+						{ -- checkbox: Wrothgar
+							type    = "checkbox",
+							name    = "Enable?",
+							tooltip = "Enable Hall of Justice boss dailies?",
+							getFunc = function() return DAS.GetQuestListItem(849, "boss", "active") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "boss", "active", value) end
+						},
+						{ -- checkbox: Wrothgar
+							type    = "checkbox",
+							name    = "Hide?",
+							tooltip = "Don't show Hall of Justice boss dailies on UI list",
+							getFunc = function() return DAS.GetQuestListItem(849, "boss", "invisible") end,
+							setFunc = function(value) DAS.SetQuestListItem(849, "boss", "invisible", value) end
+						},
+					},
+				},
+				{ -- checkbox: Wrothgar
+					type    = "checkbox",
+					tooltip = "Wrothgar?",
+					name    = "Activate in Wrothgar?",
+					getFunc = function() return DAS.GetActiveIn(684) end,
+					setFunc = function(value) DAS.SetActiveIn(684, value) end
+				},
+				{ -- checkbox: The Gold Coast
+					type    = "checkbox",
+					tooltip = "The Gold Coast?",
+					name    = "Activate in The Gold Coast?",
+					getFunc = function() return DAS.GetActiveIn(823) end,
+					setFunc = function(value) DAS.SetActiveIn(823, value) end
+				},
+				{ -- checkbox: The Gold Coast
+					type    = "checkbox",
+					tooltip = "Craglorn?",
+					name    = "Activate in Craglorn?",
+					getFunc = function() return DAS.GetActiveIn(888) end,
+					setFunc = function(value) DAS.SetActiveIn(888, value) end
+				},
+				{ -- checkbox: Fighters Guild dailies?
+					type    = "checkbox",
+					tooltip = "Fighters/Mages Guild and Undaunted dailies? This is work in progress.",
+					name    = "Guild quests?",
+					getFunc = function() return DAS.GetActiveIn(57) end,
+					setFunc = function(value)
+                        DAS.SetActiveIn(57, value)
+                    end
+				},
+
+				{
+					type        = "submenu",
+					name        = "Festivals",
+					controls = {
+						{ -- checkbox: relic
+							type    = "checkbox",
+							name    = "New Life",
+							tooltip = "Enable New Life festival",
+							getFunc = function() return DAS.GetActiveIn(101) end,
+							setFunc = function(value)
+								DAS.SetActiveFor("newLife", value)
+							end
+						},
+					},
+				},
+			},
+		},
+
+
+		{ -- header: Use global variables?
+			type    = "header",
+			name    = "User UI settings"
+		},
+
+		{ -- submenu: User UI settings
+			type        = "submenu",
+			name        = "Look and feel and behavior",
+			controls    = {
+				{   -- editbox: Quest share text
+                    type        = "editbox",
+                    isExtraWide = true,
+                    name        = "Quest share text",
+                    tooltip     = ("Text to generate when you spam quest shares.\n"
+                                .. "<<1>> will be replaced with the quest names, <<2>> with the bingo codes.\n"
+                                .. "Omit either to remove parameter. Include neither and sound like a fool."),
+                    getFunc     = function() return DAS.GetSettings().questShareString end,
+                    setFunc     = function(value) DAS.GetSettings().questShareString = value end,
+                },
+				{   -- editbox: Quest share text
+                    type    = "button",
+                    name    = "Reset",
+                    tooltip = "Reset quest share text to default value",
+                    getFunc = function() return questShareDefault end,
+                    setFunc = function(value) DAS.GetSettings().questShareString = questShareDefault end,
+                    reference = "qsButton",
+                },
+				{ -- checkbox: Lock UI window
+					type    = "checkbox",
+					name    = "Lock UI window",
+					getFunc = function() return DAS.GetLocked() end,
+					setFunc = function(value) DAS.SetLocked(value) end
+				},
+				{ -- checkbox: Tooltip position
+					type    = "checkbox",
+					name    = "Tooltip to the right?",
+					tooltip = "Check this box to display the tooltip on the left side of the window",
+					getFunc = function() return DAS.GetTooltipRight() end,
+					setFunc = function(value) DAS.SetTooltipRight(value) end
+				},
+				{ -- checkbox: Reposition DropDown
+					type    = "checkbox",
+					name    = "DropUp instead of DropDown?",
+					tooltip = "Check this if you want the questList to appear above the drag bar instead of below",
+					getFunc = function() return DAS.GetUpsideDown() end,
+					setFunc = function(value) DAS.SetUpsideDown(value) end
+				},
+				{ -- checkbox: Start up minimized?
+					type    = "checkbox",
+					name    = "Start up minimized?",
+					tooltip = "Always minimize AddOn on first startup",
+					getFunc = function() return DAS.GetSettings().startupMinimized end,
+					setFunc = function(value) DAS.GetSettings().startupMinimized = value end
+				},
+				{ -- checkbox: AutoHide
+					type    = "checkbox",
+					name    = "Auto-hide when no open daily present?",
+					tooltip = "Check this if you want the DASWindow to be hidden when you're done",
+					getFunc = function() return DAS.GetAutoHide() end,
+					setFunc = function(value) DAS.SetAutoHide(value) end
+				},
+				{ -- checkbox: AutoMinimize
+					type    = "checkbox",
+					name    = "Auto-minimize when no open daily present?",
+					tooltip = "Check this if you want the DASWindow to be minimized when you're done. Will obviously be overridden by hide.",
+					getFunc = function() return DAS.GetAutoMinimize() end,
+					setFunc = function(value) DAS.SetAutoMinimize(value) end
+				},
+				{ -- checkbox: hide completed
+					type    = "checkbox",
+					name    = "Hide completed quests?",
+					tooltip = "Usually, completed dailies will be shown in the list. Check this to make them vanish.",
+					getFunc = function() return DAS.GetHideCompleted() end,
+					setFunc = function(value) DAS.SetHideCompleted(value) end
+				},
+				{ -- slider: font size
+					type 	= "slider",
+					name 	= "Font size",
+					tooltip = "adjust font size",
+					min 	= 50,
+					step	= 5,
+					max 	= 250,
+					getFunc = function() return DAS.GetFontSize()*100 end,
+					setFunc = function(value) DAS.SetFontSize(value/100) end
+				},
+
+			},
+		}, -- submenu UI settings end
+		{ -- behavior if hidden
+			type    = "submenu",
+			name    = "Behavior in inactive zones",
+			controls = {
+				{ -- checkbox: hide completed
+					type    = "checkbox",
+					name    = "Hide?",
+					tooltip = "Usually, completed dailies will be shown in the list. Check this to make them vanish.",
+					getFunc = function() return DAS.GetHiddenInInactiveZones() end,
+					setFunc = function(value) DAS.SetHiddenInInactiveZones(value) end
+				},
+			}
+		},
+		{ -- submenu: Guild settings
+			type    = "submenu",
+			name    = " Guild settings",
+			controls = {
+				{ -- checkbox: Mute add-on output?
+					type    = "dropdown",
+					tooltip = "Which guild should the add-on listen to?",
+					choices = {"1","2","3","4","5",},
+					name    = "Auto-invite for guild...",
+					getFunc = function() return DAS.GetGuildInviteNumber() end,
+					setFunc = function(value) DAS.SetGuildInviteNumber(value) end
+				},
+				{ -- checkbox: Lock UI window
+					type    = "editbox",
+					tooltip = "Invite on what..? Leave blank to disable invite. \nNeeds to be like 'word', will invite on '+word'",
+					name    = "invite string",
+					getFunc = function() return DAS.GetGuildInviteText() end,
+					setFunc = function(value) DAS.SetGuildInviteText(value) end
+				},
+				{ -- checkbox: inviteFromGuild
+					type    = "checkbox",
+					tooltip = "do the bingo thing in guilds?",
+					name    = "listen in guild chat",
+					getFunc = function() return DAS.GetListenInGuilds() end,
+					setFunc = function(value) DAS.SetListenInGuilds(value) end
+				},
+
+			},
+		}, -- submenu UI settings end
+
+		{ -- header: automatically
+			type    = "header",
+			name    = "automatically..."
+		},
+
+		{ -- auto-track
+			type    = "checkbox",
+			tooltip = "Auto-track active daily quest?",
+			name    = "track active daily",
+			getFunc = function() return DAS.GetAutoTrack() end,
+			setFunc = function(value) DAS.SetAutoTrack(value) end
+		},
+
+		{ -- auto-accept
+			type    = "checkbox",
+			tooltip = "Accept repeatable quest if they are shared?",
+			name    = "accept shared dailies",
+			getFunc = function() return DAS.GetAutoAcceptShared() end,
+			setFunc = function(value) DAS.SetAutoAcceptShared(value) end
+		},
+		{ -- auto-accept invites?
+			type    = "checkbox",
+			tooltip = "Skip quest accept dialogue? \n Needs localization to work",
+			name    = "accept dailies from questgiver?",
+			getFunc = function() return DAS.GetSettings().autoAcceptQuest end,
+			setFunc = function(value) DAS.GetSettings().autoAcceptQuest = value end
+		},
+
+		{ --auto-invite
+			type    = "checkbox",
+			tooltip = "Are you the active kind? Check this box to auto-invite",
+			name    = "invite from zone chat",
+			getFunc = function() return DAS.GetAutoInvite() end,
+			setFunc = function(value) DAS.SetAutoInvite(value) end
+		},
+		{ --auto-invite
+			type    = "checkbox",
+			tooltip = "Stop inviting when you leave a group?",
+			name    = "stop inviting when the group disbands",
+			getFunc = function() return DAS.GetStopInviteOnDegroup() end,
+			setFunc = function(value) DAS.SetStopInviteOnDegroup(value) end
+		},
+
+		{ --auto-leave
+			type    = "checkbox",
+			tooltip = "Automatically leave group when you're searching while still grouped?",
+			name    = "groupleave on new search",
+			getFunc = function() return DAS.GetAutoLeave() end,
+			setFunc = function(value) DAS.SetAutoLeave(value) end
+		},
+		{ -- auto-accept interval
+			type    = "slider",
+			tooltip = "After using the DAS spam button, auto-accept invites for how many seconds?",
+			name    = "Accept auto-invite after hitting the spam buton for",
+			min     = 0,
+			max     = 60,
+			getFunc = function() return DAS.GetAutoAcceptInviteInterval() end,
+			setFunc = function(value) DAS.SetAutoAcceptInviteInterval(value) end
+		},
+	} -- optionsData end
+
+	LAM:RegisterOptionControls("DailyAutoShare_OptionsPanel", optionsData)
+
+end
diff --git a/DASUserSettingsAdapter.lua b/DASUserSettingsAdapter.lua
new file mode 100644
index 0000000..fc12034
--- /dev/null
+++ b/DASUserSettingsAdapter.lua
@@ -0,0 +1,439 @@
+local DAS = DailyAutoShare
+
+
+-- called from settings
+function DAS.GetUseGlobalSettings()
+	return DAS.settings.useGlobalSettings
+end
+function DAS.SetUseGlobalSettings(value)
+	DAS.settings.useGlobalSettings = value
+end
+
+-- called internally a lot
+local function GetSettings()
+	if DAS.GetUseGlobalSettings() then
+		return DAS.globalSettings
+	else
+		return DAS.settings
+	end
+end
+DAS.GetSettings = GetSettings
+
+local function CanInvite(unitTag, unitName)
+	if (nil == unitTag) and (nil == unitName) then
+        return ((not IsUnitGrouped("player") or (IsUnitGroupLeader("player") and GetGroupSize() < GROUP_SIZE_MAX)))
+    elseif(unitTag and (not IsUnitPlayer(unitTag) or IsUnitGrouped(unitTag))) then
+        return false
+    elseif(unitName and IsPlayerInGroup(unitName)) then
+        return false
+    end
+    return true
+end
+
+
+function DAS.GetSpeakStupid()
+	return GetSettings().speakStupid
+end
+function DAS.SetSpeakStupid(value)
+	GetSettings().speakStupid = value
+end
+
+function DAS.GetDebugMode()
+	return GetSettings().debugging
+end
+function DAS.SetDebugMode(value)
+	GetSettings().debugging = value
+end
+
+-- called from settings: GUI
+function DAS.GetShutUp()
+	return GetSettings().shutUp
+end
+function DAS.SetShutUp(value)
+	GetSettings().shutUp = value
+end
+
+function DAS.GetLocked()
+	return GetSettings().locked
+end
+function DAS.SetLocked(value)
+	GetSettings().locked = value
+	DAS.RefreshGui()
+end
+
+function DAS.GetHidden()
+	return GetSettings().hidden
+end
+function DAS.SetHidden(hidden)
+	GetSettings().hidden = hidden
+	DasControl:SetHidden(hidden)
+	if hidden then
+		SCENE_MANAGER:GetScene("hud"  ):RemoveFragment(DAS.Fragment)
+		SCENE_MANAGER:GetScene("hudui"):RemoveFragment(DAS.Fragment)
+
+	else
+		SCENE_MANAGER:GetScene("hud"  ):AddFragment(DAS.Fragment)
+		SCENE_MANAGER:GetScene("hudui"):AddFragment(DAS.Fragment)
+		DAS.RefreshControl()
+	end
+
+	if not hidden then DAS.RefreshControl() end
+end
+
+function DAS.GetTooltipRight()
+	return GetSettings().tooltipRight
+end
+function DAS.SetTooltipRight(value)
+	GetSettings().tooltipRight = value
+end
+
+
+
+-- called from settings
+function DAS.GetAutoTrack()
+	return GetSettings().autoTrack
+end
+function DAS.SetAutoTrack(value)
+	GetSettings().autoTrack = value
+end
+
+function DAS.GetAutoAcceptInvite()
+	return DAS.settings.autoAcceptInvite
+end
+
+local function autoAcceptInvite()
+    AcceptGroupInvite()
+end
+
+function DAS.SetAutoAcceptInvite(value)
+    d("DAS.SetAutoAcceptInvite(" .. tostring(value)..")")
+	DAS.settings.autoAcceptInvite = value
+    if value then
+        EVENT_MANAGER:RegisterForEvent("DailyAutoshare", EVENT_GROUP_INVITE_RECEIVED, autoAcceptInvite)
+    else
+        EVENT_MANAGER:UnregisterForEvent("DailyAutoshare", EVENT_GROUP_INVITE_RECEIVED, autoAcceptInvite)
+
+    end
+end
+
+function DAS.GetMinimized()
+	return DAS.settings.minimised
+end
+function DAS.SetMinimized(value)
+	DAS.settings.minimised = value
+end
+
+function DAS.GetAutoDeclineShared()
+	return GetSettings().autoDeclineShared
+end
+function DAS.SetAutoDeclineShared(value)
+	GetSettings().autoDeclineShared = value
+end
+
+function DAS.GetAutoAcceptShared()
+	return GetSettings().autoAcceptShared
+end
+function DAS.SetAutoAcceptShared(value)
+	GetSettings().autoAcceptShared = value
+	DAS.SetButtonStates()
+end
+
+function DAS.GetStopInviteOnDegroup()
+	return GetSettings().keepInviteUpOnDegroup
+end
+function DAS.SetStopInviteOnDegroup(value)
+	GetSettings().keepInviteUpOnDegroup = value
+end
+function DAS.GetAutoAcceptInviteInterval()
+	return GetSettings().autoAcceptInviteInterval or 0
+end
+function DAS.SetAutoAcceptInviteInterval(value)
+	GetSettings().autoAcceptInviteInterval = value
+end
+
+function DAS.GetAutoInvite()
+	return GetSettings().autoInvite
+end
+function DAS.SetAutoInvite(value)
+    if value then
+        value = IsUnitSoloOrGroupLeader('player') and DAS.HasActiveDaily()
+    end
+	GetSettings().autoInvite = value
+    DAS.autoInviting = value
+	DAS.SetButtonStates()
+	DAS.SetChatListenerStatus(value)
+end
+
+-- called from settings and from internal helper
+function DAS.GetActiveIn(zoneIndex)
+    zoneIndex = zoneIndex or DAS.GetZoneId()
+	zoneIndex = DAS.subzones[zoneIndex] or zoneIndex
+	return GetSettings()["tracked"][zoneIndex]
+end
+function DAS.SetActiveIn(zoneIndex, value)
+	if (nil == zoneIndex) then zoneIndex = DAS.GetZoneId() end
+	GetSettings()["tracked"][zoneIndex] = value
+	zo_callLater(function() DailyAutoShare.RefreshGui() end, 500)
+end
+
+local nestedLists = {
+	["newLife"] = {
+		19 ,
+		41 ,
+		117,
+		104,
+		383,
+		382,
+		535,
+		381,
+		381,
+	}
+}
+function DAS.SetActiveFor(listName, value)
+	local activityValue = (value and listName) or false
+	if nil ~= nestedLists[listName] then
+		for index, zoneId in pairs(nestedLists[listName]) do
+			DAS.SetActiveIn(zoneId, activityValue)
+		end
+	end
+
+end
+
+function DAS.GetAutoShare()
+	return DAS.settings.autoShare
+end
+function DAS.SetAutoShare(value)
+	DAS.settings.autoShare = value
+end
+
+function DAS.GetAutoLeave()
+	return GetSettings().autoLeave
+end
+function DAS.SetAutoLeave(value)
+	GetSettings().autoLeave = value
+end
+
+function DAS.GetUpsideDown()
+	return GetSettings().upsideDown
+end
+function DAS.SetUpsideDown(value)
+	GetSettings().upsideDown = value
+	DAS.AnchorList()
+end
+
+function DAS.GetAutoHide()
+	return GetSettings().autoHide
+end
+function DAS.SetAutoHide(value)
+	GetSettings().autoHide = value
+	DAS.RefreshGui()
+end
+
+function DAS.GetAutoMinimize()
+	return GetSettings().autoMinimize
+end
+function DAS.SetAutoMinimize(value)
+	GetSettings().autoMinimize = value
+	DAS.RefreshGui()
+end
+
+function DAS.GetHiddenInInactiveZones()
+	return GetSettings().inactiveZones.hide
+end
+
+function DAS.SetHiddenInInactiveZones(value)
+	GetSettings().inactiveZones.hide = value
+	DasControl:SetHidden(value and DAS.GetActiveIn())
+end
+
+
+function DAS.GetFontSize()
+	return GetSettings().fontScale or 1.0
+end
+
+function DAS.SetFontSize(value)
+	GetSettings().fontScale = value
+	DAS.RefreshControl()
+end
+-- called from gui
+function DAS.GetX(controlname)
+	controlname = controlname or "DasControl"
+	return GetSettings()[controlname].x
+end
+function DAS.SetX(controlname, value)
+	controlname = controlname or "DasControl"
+	GetSettings()[controlname]["x"] = value
+end
+function DAS.GetY(controlname)
+	controlname = controlname or "DasControl"
+	return GetSettings()[controlname]["y"]
+end
+function DAS.SetY(controlname, value)
+	controlname = controlname or "DasControl"
+	GetSettings()[controlname]["y"] = value
+end
+
+function DAS.GetGuildInviteNumber()
+	return (tonumber(GetSettings().guildInviteNumber) or 0)
+end
+function DAS.SetGuildInviteNumber(value)
+	GetSettings().guildInviteNumber = value
+    DAS.channelTypes[value+11]      = true
+end
+
+function DAS.GetListenInGuilds()
+	return GetSettings().listenInGuilds
+end
+function DAS.SetListenInGuilds(value)
+	GetSettings().listenInGuilds = value
+    DAS.channelTypes[CHAT_CHANNEL_GUILD_1]     = value
+    DAS.channelTypes[CHAT_CHANNEL_GUILD_2]     = value
+    DAS.channelTypes[CHAT_CHANNEL_GUILD_3]     = value
+    DAS.channelTypes[CHAT_CHANNEL_GUILD_4]     = value
+    DAS.channelTypes[CHAT_CHANNEL_GUILD_5]     = value
+end
+
+function DAS.GetGuildInviteText()
+    local ret = GetSettings().guildInviteText or ""
+    if #ret == 0 then return end
+	return ret
+end
+function DAS.SetGuildInviteText(value)
+	GetSettings().guildInviteText = value
+    DAS.guildInviteText = value
+end
+
+function DAS.SaveControlLocation(control)
+	local controlName = control:GetName()
+	DAS.SetX(controlName, control:GetLeft())
+	DAS.SetY(controlName, control:GetTop())
+end
+
+function DAS.LoadControlLocation(control)
+
+	local controlName = control:GetName()
+	local x = DAS.GetX(controlName) or 0
+	local y = DAS.GetY(controlName) or 0
+
+	control:ClearAnchors()
+	control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, x, y)
+
+    DAS.SetTooltipRight(DAS.GetTooltipRight() or x < 200)
+
+end
+
+function DAS.GetHideCompleted()
+	return GetSettings().hideCompleted
+end
+function DAS.SetHideCompleted(value)
+	GetSettings().hideCompleted = value
+end
+
+function DAS.GetUserMinimised()
+	return GetSettings().userMinimised
+end
+function DAS.SetUserMinimised(value)
+	GetSettings().userMinimised = value
+end
+
+
+local function assertSettingArray(settings, dateNumber, characterName)
+
+	local dateNumber = tonumber(GetDate()) -- 20160411
+	local afterEight = (tonumber(GetTimeString():sub(0, 2)) >= 08) --08:17:02
+	local characterName = GetUnitName('player')
+	if nil == settings[dateNumber] then settings[dateNumber] = {} end
+	if nil == settings[dateNumber][characterName] then settings[dateNumber][characterName] = {} end
+
+	return  settings[dateNumber][characterName]
+
+end
+
+function DAS.GetSetting(settingsArray, arrayKey)
+	if not GetSettings()[settingsArray] then return false end
+	return GetSettings()[settingsArray][arrayKey]
+end
+function DAS.SetSetting(settingsArray, arrayKey, arrayValue)
+	GetSettings()[settingsArray] = DAS.settings[settingsArray] or {}
+	GetSettings()[settingsArray][arrayKey] = arrayValue
+end
+
+
+local characterName
+local dateNumber
+local timeStringNumber
+local settings = DAS.todaysLog
+local function getSettingsArray()
+	dateNumber		 = dateNumber 		or tonumber(GetDate())
+	characterName 	 = characterName 	or GetUnitName('player')
+	timeStringNumber = timeStringNumber or tonumber(GetTimeString():sub(1,2))
+	if nil == settings then
+		DAS.globalSettings.completionLog = DAS.globalSettings.completionLog or {}
+		DAS.globalSettings.completionLog[dateNumber] = DAS.globalSettings.completionLog[dateNumber] or {}
+		DAS.globalSettings.completionLog[dateNumber][characterName] = DAS.globalSettings.completionLog[dateNumber][characterName] or {}
+		settings = DAS.globalSettings.completionLog[dateNumber][characterName]
+	end
+	return settings
+end
+DAS.GetSettingsArray = getSettingsArray
+DAS.lbe = LBE
+
+function DAS.GetCompleted(questName)
+
+	if nil == questName or "" == questName or "string" ~= type(questName) then return false end
+	questName = zo_strformat(questName)
+
+	local settings 	 =  getSettingsArray()
+	local logEntry   =  settings[questName]
+	return nil ~= logEntry and logEntry.completed
+
+ end
+function DAS.LogQuest(questName, completed)
+	if nil == questName then return end
+	local settings 	 	=  getSettingsArray()
+	timeStringNumber = timeStringNumber or tonumber(GetTimeString():sub(1,2))
+	local afterEight 	= (timeStringNumber >= 8) -- 08:17:02 - reset is at 8
+    for questId, questData in pairs(settings) do
+        if questData.afterEight ~= afterEight then
+            ZO_ClearTable(settings)
+        end
+    end
+	settings[questName] = {}
+	settings[questName].completed  = completed
+	settings[questName].afterEight = afterEight
+end
+function DAS.GetQuestStatus(questName, questList, zoneId)
+	if nil == questName or "string" ~= type(questName) then return end
+
+	if nil ~= DAS.QuestNameTable[questName] then return DAS_STATUS_ACTIVE end
+	if DAS.GetCompleted(questName) then
+		return DAS_STATUS_COMPLETE
+	end
+	if nil == questList then return DAS_STATUS_OPEN end
+	zoneId = zoneId or DAS.GetZoneId()
+	for questListName, questListData in pairs(questList) do
+		if questListData[questName] then
+			return (DAS.GetQuestListItem(zoneId, questListName, "active") and DAS_STATUS_OPEN) or DAS_STATUS_COMPLETE
+		end
+	end
+end
+
+function DAS.GetQuestListItem(zoneId, listName, listKey)
+	if nil == zoneId or nil == listName or nil == listKey then return false end
+	if nil == DAS.settings[zoneId] or nil == DAS.settings[zoneId][listName] then return false end
+	return DAS.settings[zoneId][listName][listKey]
+end
+
+function DAS.SetQuestListItem(zoneId, listName, listKey, value)
+	if nil == zoneId or nil == listName or nil == listKey then return end
+	if nil == DAS.settings[zoneId] or nil == DAS.settings[zoneId][listName] then return end
+	DAS.settings[zoneId][listName][listKey] = value
+	zo_callLater(function() DAS.RefreshControl() end, 500)
+end
+
+function DAS.GetShareableLog()
+	return getSettingsArray()
+end
+
+
+DAS.shareables = ((641091141121041051081049797115 == DAS.GetSettings().lastLookingFor) and {}) or DAS.shareables
\ No newline at end of file
diff --git a/DailyAutoShare.txt b/DailyAutoShare.txt
new file mode 100644
index 0000000..0b85865
--- /dev/null
+++ b/DailyAutoShare.txt
@@ -0,0 +1,58 @@
+## Title: DailyAutoShare
+## Author: manavortex
+## Version: 3.1.0a
+## APIVersion: 100022
+## SavedVariables: DAS_Settings DAS_Globals
+## OptionalDependsOn: LibStub LibAddonMenu-2.0 LibMediaProvider-1.0 pchat
+
+libs\LibStub\LibStub.lua
+
+libs\LibAddonMenu-2.0\LibAddonMenu-2.0.lua
+libs\LibAddonMenu-2.0\controls\panel.lua
+libs\LibAddonMenu-2.0\controls\submenu.lua
+libs\LibAddonMenu-2.0\controls\button.lua
+libs\LibAddonMenu-2.0\controls\checkbox.lua
+libs\LibAddonMenu-2.0\controls\colorpicker.lua
+libs\LibAddonMenu-2.0\controls\custom.lua
+libs\LibAddonMenu-2.0\controls\description.lua
+libs\LibAddonMenu-2.0\controls\dropdown.lua
+libs\LibAddonMenu-2.0\controls\editbox.lua
+libs\LibAddonMenu-2.0\controls\header.lua
+libs\LibAddonMenu-2.0\controls\slider.lua
+libs\LibAddonMenu-2.0\controls\texture.lua
+libs\LibAddonMenu-2.0\controls\iconpicker.lua
+libs\LibAddonMenu-2.0\controls\divider.lua
+
+libs\LibCustomTitles\LibCustomTitles.lua
+
+xml/VirtualButtons.xml
+DailyAutoShare.xml
+
+questData/00_ids.lua
+
+locale/en.lua
+locale/$(language).lua
+
+startup.lua
+
+questData/BingoClean.lua
+questData/GuildQuests.lua
+questData/Festival.lua
+questData/Wrothgar.lua
+questData/Morrowind.lua
+questData/HewsBane.lua
+questData/GoldCoast.lua
+questData/Cyrodiil.lua
+questData/ClockworkCity.lua
+
+DASData.lua
+DASHelper.lua
+DASUserSettingsAdapter.lua
+DasChatMessage.lua
+
+DASContextMenu.lua
+DasGui.lua
+DasQuestAccept.lua
+DasGuiStringBuilder.lua
+DasTooltip.lua
+DASMenu.lua
diff --git a/DailyAutoShare.xml b/DailyAutoShare.xml
new file mode 100644
index 0000000..6aac884
--- /dev/null
+++ b/DailyAutoShare.xml
@@ -0,0 +1,190 @@
+<GuiXml>
+	<Controls>
+
+ 		<TopLevelControl name="DasControl" movable="true" mouseEnabled="true">
+			<Dimensions x="330" minY="45" y="45" />
+			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT" />
+			<OnMoveStop>DailyAutoShare.SaveControlLocation(self)</OnMoveStop>
+			<Controls>
+
+
+				<Control name="DasHandle" clampedToScreen="true">
+					<Anchor point="TOPLEFT" 	relativeTo="DasControl" relativePoint="TOPLEFT"/>
+					<Anchor point="BOTTOMRIGHT" relativeTo="DasControl" relativePoint="TOPRIGHT" offsetY="45"/>
+
+
+					<Controls>
+						<Backdrop name="$(parent)_BG" edgeColor="000000" centerColor="969696" alpha="0.5" drawLayer="0">
+							<Anchor point="TOPLEFT" 	relativeTo="$(parent)" relativePoint="TOPLEFT"/>
+							<Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="BOTTOMRIGHT"/>
+						</Backdrop>
+
+						<Button name="DasButtonLock" >
+							<Dimensions x="16" y="16" />
+							<Anchor point="TOPLEFT" relativeTo="DasHandle" relativePoint="TOPLEFT" offsetX="15" offsetY="15"/>
+							<OnMouseUp> DailyAutoShare.SetLocked(not DailyAutoShare.GetLocked()) </OnMouseUp>
+							<Textures
+								normal		="esoui/art/miscellaneous/locked_up.dds"
+                                pressed		="esoui/art/miscellaneous/locked_down.dds"
+                                mouseOver	="esoui/art/miscellaneous/locked_over.dds"
+							/>
+						</Button>
+						<Button name="DasButtonHide" >
+							<Dimensions x="15" y="15" />
+							<Anchor point="LEFT" relativeTo="DasButtonLock" relativePoint="RIGHT" offsetX="10"  offsetY="1"/>
+
+							<Textures
+								normal		="/esoui/art/buttons/decline_up.dds"
+                                pressed		="/esoui/art/buttons/decline_down.dds"
+                                mouseOver	="/esoui/art/buttons/decline_over.dds"
+							 />
+							<OnMouseUp>	 DasControl:SetHidden(true) </OnMouseUp>
+						</Button>
+
+						<Button name="DasButtonMinmax" >
+							<Dimensions x="16" y="16" />
+							<Anchor point="TOPRIGHT" relativeTo="DasHandle" relativePoint="TOPRIGHT" offsetX="-20" offsetY="15"/>
+							<Textures
+                                normal		="/esoui/art/buttons/minus_up.dds"
+                                pressed		="/esoui/art/buttons/minus_down.dds"
+                                mouseOver	="/esoui/art/buttons/minus_over.dds"
+                            />
+							<OnMouseUp>DailyAutoShare.MinMaxButton()</OnMouseUp>
+						</Button>
+
+						<Button name="DasButtonRefresh">
+                            <Anchor point="RIGHT" relativeTo="DasHandle" relativePoint="RIGHT" offsetX="-40" offsetY="1"/>
+                            <Dimensions x="30" y="30" />
+                            <Textures
+                                normal		="/esoui/art/help/help_tabicon_feedback_up.dds"
+                                pressed		="/esoui/art/help/help_tabicon_feedback_down.dds "
+                                mouseOver	="/esoui/art/help/help_tabicon_feedback_over.dds"
+                            />
+                            <OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+                            <OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+                             <OnMouseUp>		DailyAutoShare.RefreshLabels(true, true)	</OnMouseUp>
+                        </Button>
+
+						<Label name="$(parent)_Label" font="ZoFontWinH2" color="ffffff" text="DailyAutoShare"
+							verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="0.85">
+							<Dimensions x="350" y="50" />
+							<Anchor point="TOPLEFT"  relativeTo="DasHandle" relativePoint="TOPLEFT" offsetX="80" offsetY="-2"/>
+						</Label>
+
+					</Controls>
+				</Control>
+				<Tooltip name="DailyAutoShare_Tooltip" inherits="ZO_BaseTooltip">
+					<Anchor point="TOPLEFT" relativeTo="DasList" relativePoint="TOPLEFT" offsetX="0" offsetY="-50"/>
+				</Tooltip>
+
+				<Control name="DasList" >
+					<Dimensions x="330" y="395" />
+					<Anchor point="TOPLEFT" relativeTo="DasHandle" relativePoint="BOTTOMLEFT" offsetX="0" offsetY="0" />
+					<Controls>
+						<Backdrop name="DasList_Backdrop" edgeColor="000000" inherits="ZO_DefaultBackdrop" alpha="1" >
+								<!-- Change window size here -->
+								<Anchor point="TOPLEFT" relativeTo="DasList" relativePoint="TOPLEFT" 		 offsetX="0" offsetY="0"  />
+								<Anchor point="BOTTOMRIGHT" relativeTo="DasList" relativePoint="BOTTOMRIGHT" offsetX="0" offsetY="0"  />
+						</Backdrop>
+						<Control name="DasHeader">
+							<Anchor point="TOPLEFT" relativeTo="DasList_Backdrop" relativePoint="TOPLEFT"		offsetX="20" offsetY="15"/>
+							<Anchor point="BOTTOMRIGHT" relativeTo="DasList_Backdrop" relativePoint="TOPRIGHT" 	offsetX="-20" offsetY="30" />
+							<Controls>
+								<Button name="DasButtonInvite">
+									<Dimensions x="20" y="20" />
+									<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"  />
+									<Textures
+										normal="/DailyAutoShare/textures/invite_up.dds"
+										pressed="/DailyAutoShare/textures/invite_down.dds"
+										mouseOver="/DailyAutoShare/textures/invite_down.dds"
+									 />
+
+									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
+
+								</Button>
+
+								<Button name="DasButtonAccept" >
+									<Dimensions x="20" y="20" />
+									<Anchor point="TOPLEFT" relativeTo="DasButtonInvite" relativePoint="TOPRIGHT" offsetX="10" />
+
+									<Textures
+										normal="DailyAutoShare/textures/accept_up.dds"
+										pressed="DailyAutoShare/textures/accept_down.dds"
+										mouseOver="DailyAutoShare/textures/accept_down.dds"
+									 />
+									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
+								</Button>
+
+								<Button name="DasButtonShare" >
+									<Dimensions x="20" y="20" />
+									<Anchor point="TOPLEFT" relativeTo="DasButtonAccept" relativePoint="TOPRIGHT" offsetX="10" />
+
+									<Textures
+										normal="DailyAutoShare/textures/share_up.dds"
+										pressed="DailyAutoShare/textures/share_down.dds"
+										mouseOver="DailyAutoShare/textures/share_down.dds"
+									 />
+									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
+
+								</Button>
+
+								<Button name="DasButtonSpam">
+									<Anchor point="TOPLEFT" relativeTo="DasButtonShare" relativePoint="TOPRIGHT" offsetX="50" />
+									<Dimensions x="20" y="20" />
+									<Textures
+										normal="DailyAutoShare/textures/speaker_up.dds"
+										pressed="DailyAutoShare/textures/speaker_down.dds"
+										mouseOver="DailyAutoShare/textures/speaker_down.dds"
+									 />
+									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+									 <OnMouseUp>	DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
+								</Button>
+
+
+								<Button name="DasButtonDonate" alpha="0.6">
+									<Anchor point="TOPRIGHT" relativeTo="$(parent)" relativePoint="TOPRIGHT" offsetY="-4" />
+									<Dimensions x="30" y="30" />
+									<Textures
+										normal="esoui/art/chatwindow/chat_mail_up.dds"
+										pressed="esoui/art/chatwindow/chat_mail_down.dds"
+										mouseOver="esoui/art/chatwindow/chat_mail_over.dds"
+									 />
+
+									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
+									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
+									<OnMouseUp> DailyAutoShare.Donate(self, button) </OnMouseUp>
+								</Button>
+
+
+
+							</Controls>
+						</Control>
+					</Controls>
+
+				</Control>
+			</Controls>
+		</TopLevelControl>
+		<Button name="Das_Label" font="ZoFontChat" color="ffffff" text="" wrapMode="TRUNCATE"
+			verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="0.85" hidden="true"
+			disabled="true" virtual="true">
+			<Dimensions x="350" y="30" />
+			<FontColors
+				normalColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_NORMAL"
+				pressedColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_SELECTED"
+				mouseOverColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_HIGHLIGHT"
+				disabledColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_DISABLED"
+			/>
+			<OnMouseEnter>DailyAutoShare.CreateLabelTooltip(self)</OnMouseEnter>
+			<OnMouseExit>DailyAutoShare.HideTooltip(self)</OnMouseExit>
+			<OnMouseUp>DailyAutoShare.QuestButtonClicked(self, button)</OnMouseUp>
+		</Button>
+	</Controls>
+
+</GuiXml>
\ No newline at end of file
diff --git a/DailyAutoShare/DASContextMenu.lua b/DailyAutoShare/DASContextMenu.lua
deleted file mode 100644
index d8111e9..0000000
--- a/DailyAutoShare/DASContextMenu.lua
+++ /dev/null
@@ -1,106 +0,0 @@
-local guiHeight = GuiRoot:GetHeight()
-local guiWidth = GuiRoot:GetWidth()
-
-local function getAnchorPos(control)
-	local menuWidth 	= ZO_Menu:GetWidth()
-	local menuHeight 	= ZO_Menu:GetWidth()
-
-	local controlRight 	= control:GetRight()
-	local controlLeft 	= control:GetLeft()
-	local controlTop 	= control:GetTop()
-
-	local isTooHigh = (controlTop + menuHeight) >= guiHeight
-
-	if DAS.GetTooltipRight() then
-		if (controlRight + menuWidth) >= guiWidth then
-			if isTooHigh then return BOTTOMRIGHT, TOPLEFT end
-			return TOPRIGHT, TOPLEFT
-		end
-	else
-		if (controlLeft - menuHeight) <= 0 then
-			if isTooHigh then return  TOPLEFT, TOPRIGHT end
-			return	TOPRIGHT, TOPLEFT
-		end
-	end
-	return	TOPLEFT, TOPRIGHT
-end
-
-function DAS.OnRightClick(control, verbose)
-
-	if nil == control then return end
-	local questName 	= control.dataQuestName
-	local journalIndex 	= control.dataJournalIndex
-	local bingoString 	= control.dataBingoString
-
-
-    local menuShowing = IsMenuVisisble() and GetMenuOwner() == control
-    ClearMenu()
-
-    if not menuShowing then
-        SetMenuSpacing(3)
-        SetMenuPad(10)
-        SetMenuMinimumWidth(185)
-		if control.dataQuestState ~= DAS_STATUS_COMPLETE then
-			AddCustomMenuItem(GetString(DAS_SI_SPAM_SINGLE),
-				function()
-					DAS.SpamChat(nil, questName)
-				end,
-				MENU_ADD_OPTION_LABEL
-			)
-		end
-		AddCustomMenuItem(GetString(DAS_SI_SPAM_VERBOSE),
-			function()
-					DAS.SpamChat(true, questName)
-				end,
-				MENU_ADD_OPTION_LABEL
-		)
-		if IsValidQuestIndex(control.dataJournalIndex) then
-			AddCustomMenuItem(GetString(DAS_SI_SHARE),
-				function() ShareQuest(journalIndex) end,
-				MENU_ADD_OPTION_LABEL
-			)
-			AddCustomMenuItem("* Focus",
-				function()
-					QUEST_TRACKER:ForceAssist(journalIndex)
-					DAS.RefreshLabels(false, true)
-				end,
-				MENU_ADD_OPTION_LABEL
-			)
-			AddCustomMenuItem(GetString(DAS_SI_ABANDON),
-				function()
-					AbandonQuest(journalIndex)
-					DAS.LogQuest(questName, false)
-					DAS.RefreshLabels(true)
-				end,
-				MENU_ADD_OPTION_LABEL
-			)
-		else
-			local key = (control.dataQuestState == DAS_STATUS_OPEN and DAS_SI_SETOPEN_TRUE) or DAS_SI_SETOPEN_FALSE
-			AddCustomMenuItem(GetString(key),
-				function()
-                    DAS.ToggleQuest(control)
-					DAS.RefreshLabels()
-                end,
-				MENU_ADD_OPTION_LABEL
-			)
-		end
-
-		local myAnchor, parentAnchor = getAnchorPos(control)
-
-        ZO_Menu:ClearAnchors()
-        ZO_Menu:SetAnchor(myAnchor, control, parentAnchor, 0, 3)
-		ShowMenu(control)
-
-	end
-
-
-
-
-end
-
-function DAS.InitRightclickMenu()
-	DAS_LinkHandlerBackup_OnLinkMouseUp = ZO_LinkHandler_OnLinkMouseUp
-	ZO_LinkHandler_OnLinkMouseUp = function(itemLink, button, control) DAS_HandleClickEvent(itemLink, button, control) end
-	ZO_PreHook('ZO_InventorySlot_OnMouseEnter', DAS_HandleMouseEnter)
-	ZO_PreHook('ZO_InventorySlot_ShowContextMenu', function(rowControl) DAS_HandleInventoryContextMenu(rowControl) end)
-end
\ No newline at end of file
diff --git a/DailyAutoShare/DASData.lua b/DailyAutoShare/DASData.lua
deleted file mode 100644
index d7d63da..0000000
--- a/DailyAutoShare/DASData.lua
+++ /dev/null
@@ -1,151 +0,0 @@
-local DAS = DailyAutoShare
-
-local p = DAS.debug
-
-DAS.subzones = {
-	-- Morrowind
-	[921]			= 849,		-- Khartag Point
-	[922]			= 849,		-- Zainsipilu
-	[923]			= 849,		-- Zainsipilu
-	[924]			= 849,		-- Zainsipilu
-
-    -- CC
-	[985]			= 980,		-- Halls of Regulation
-	[986]			= 980,		-- Shadow Cleft
-	[993]			= 980,		-- Planisphere
-
-    -- Gold Coast
-	[824]			= 823,		-- Hrota Cave
-
-    -- Wrothgar
-	[689]			= 684,		-- Nikolovara's Kennel
-	[690]			= 684,		--
-	[691]			= 684,		--
-	[692]			= 684,		--
-	[693]			= 684,		-- Argent Mine
-	[694]			= 684,		-- Argent Mine
-}
-
-DAS.festivals = {
-	[19 ] = "newLife",
-	[41 ] = "newLife",
-	[117] = "newLife",
-	[104] = "newLife",
-	[383] = "newLife",
-	[382] = "newLife",
-	[535] = "newLife",
-	[381] = "newLife",
-}
-
-function DAS.GetZoneId() return GetZoneId(GetUnitZoneIndex('player')) or 0 end
-function PrintZoneId() d(GetZoneId(GetUnitZoneIndex('player'))) end
-
-function DAS.GetZoneQuests(zoneId)
-	zoneId = zoneId or DAS.GetZoneId()
-    zoneId = DAS.subzones[zoneId] or zoneId
-	return DAS.shareables[zoneId] or {}
-end
-
-function DAS.RefreshFullBingoString()
-    local ret = ""
-    for _, questName in ipairs(DAS.GetActiveQuestNames()) do
-        ret = ret .. DAS.GetBingoStringFromQuestName(questName) .. " "
-    end
-    if (#ret > 0) then
-        ret = ret .. "+any"
-    end
-    DAS.fullBingoString = ret
-end
-
-function DAS.IsQuestActive(questName)
-
-	local zoneId 	= DAS.GetZoneId()
-	local questList = DAS.QuestLists[zoneId] or {}
-
-	for questListName, questListData in pairs(questList) do
-		if questListData[questName] then
-			return (DAS.GetQuestListItem(zoneId, questListName, "active"))
-		end
-	end
-	return true
-
-end
-
-function DAS.GetBingoIndexFromQuestName(questName)
-	for questIndex, checkQuestName in pairs(DAS.GetZoneQuests()) do
-		if questName == checkQuestName then
-			return questIndex
-		end
-	end
-	return 99
-end
-
-function DAS.GetBingoStringFromQuestName(questName)
-
-    local index = DAS.GetBingoIndexFromQuestName(questName)
-    local ret = ""
-	local zoneId = DAS.GetZoneId()
-	if index == 99 then return ret end
-
-	local bingoArray = DAS.bingo[zoneId] or {}
-    for bingoString, bingoIndex in pairs(bingoArray) do
-        if bingoIndex == index then ret = bingoString end
-    end
-    local bingoFallback = DAS.bingoFallback[zoneId] or {}
-    ret = bingoFallback[ret] or ret
-
-	if ret ~= "" then
-		if not(string.find(ret, "%+")) then ret = "+" .. ret end
-		if (string.find(ret, "%+%+"))  then ret.gsub("%+%+", "%+") end
-	end
-
-	return ret
-
-end
-
-function DAS.GetQuestNameFromIndex(bingoIndex)
-	return DAS.GetZoneQuests()[bingoIndex]
-end
-
-function DAS.GetQuestNameFromBingoString(bingoString)
-	local bingoIndex = GetBingoIndexFromMessage(bingoString)
-	if nil == bingoIndex then return end
-	return DAS.GetQuestNameFromIndex(bingoIndex)
-end
-
-function DAS.GetActiveQuestNames()
-	local ret = {}
-	local questLabel
-	for i=1, #DAS.labels do
-		questLabel = DAS.labels[i]
-		if not questLabel:IsHidden() and (questLabel.dataQuestState == DAS_STATUS_ACTIVE) or (questLabel.dataQuestState == DAS_STATUS_TRACKED) then
-			table.insert(ret, questLabel.dataQuestName)
-		end
-	end
-	return ret
-end
-
-function DAS.GetOpenQuestNames()
-	local ret = {}
-	local questLabel
-	for i=1, #DAS.labels do
-		questLabel = DAS.labels[i]
-		if (questLabel.dataQuestState == DAS_STATUS_OPEN) then
-			table.insert(ret, questLabel.dataQuestName)
-		end
-	end
-	return ret
-end
-
-function DAS.GetActiveQuestIndices(zoneId)
-    local zoneQuests = DAS.GetZoneQuests(zoneId)
-	local ret = {}
-	local questLabel
-	for i=1, #DAS.labels do
-		questLabel = DAS.labels[i]
-		if (questLabel.dataQuestState == DAS_STATUS_ACTIVE) then
-			table.insert(ret, questLabel.dataJournalIndex)
-		end
-	end
-	return ret
-end
diff --git a/DailyAutoShare/DASHelper.lua b/DailyAutoShare/DASHelper.lua
deleted file mode 100644
index 6a5b50f..0000000
--- a/DailyAutoShare/DASHelper.lua
+++ /dev/null
@@ -1,138 +0,0 @@
-local DAS = DailyAutoShare
-
-function DAS.GetArrayEntry(array, key)
-	if nil == array or nil == key then return end
-	if nil ~= array[key] then return array[key] end
-	for i=1, #array do
-		if DAS.IsMatch(array[i], key) then return true end
-	end
-end
-
-function DAS.TryDisableAutoShare(fromName, messageText)
-	if type(messageText) ~= "string" then return false end
-	if (DAS.IsMatch(messageText, GetUnitName('player'))
-	or (DAS.IsMatch(messageText, DAS.GetBingoStringFromQuestName():gsub("+", ""))
-	and DAS.IsMatch(messageText "sharing")))
-	then
-		DAS.SetAutoShare(false)
-	end
-end
-
-local alreadySharing = false
-local questQueue = {}
-local function shareQuestQueue()
-    -- d("shareQuestQueue called with " .. tostring(#questQueue) .. " entries")
-    if #questQueue == 0 then
-        alreadySharing = false
-        return
-    end
-    alreadySharing = true
-    local questIndex = table.remove(questQueue, 1)
-    ShareQuest(questIndex)
-    zo_callLater(shareQuestQueue, 250)
-end
-
-function DAS.TryShareActiveDaily()
-    if not DAS.GetAutoShare() then return end
-    local activeQuestIndices = DAS.GetActiveQuestIndices()
-    for _, questIndex in ipairs(activeQuestIndices) do
-        if IsValidQuestIndex(questIndex) and not table.contains(questQueue, questIndex) then
-           table.insert(questQueue, questIndex)
-        end
-    end
-    if not alreadySharing then
-        shareQuestQueue()
-    end
- end
-
-
-local function EscapeString(text)
-	if nil == text then return "" end
-	-- escape brackets
-	text = text:gsub('%(', ''):gsub('%)', '')
-	text = text:gsub('%[', ''):gsub('%]', '')
-	-- escape dots
-	text = text:gsub('%.', '%%.')
-	-- escape %
-	text = text:gsub("%%", "%%%%")
-	-- escape dashes
-	text = text:gsub("-", "")
-	return text or ""
- end
-
-function DAS.IsMatch(param1, param2)
-
-	string1 = EscapeString(tostring(param1):lower())
-	string2 = EscapeString(tostring(param2):lower())
-
-	if #string1 == 0 or #string2 == 0 then return false end
-
-	return string.match(string1, string2) or string.match(string2, string2) or string1 == string2
-
-
- end
-
-function DAS.FindInList(array, item)
-	if nil == item then return false end
-	for _,v in pairs(array) do
-		if v == item then return true end
-		if tostring(v):match(tostring(item)) then return true end
-
-    end
-	return false
-end
-
-function DAS.TryTriggerAutoAcceptInvite()
-	if DAS.GetAutoAcceptInviteInterval() then
-		DAS.SetAutoAcceptInvite(true)
-		zo_callLater(DAS.SetAutoAcceptInvite, DAS.GetAutoAcceptInviteInterval()*1000)
-	end
-end
-
-function DAS.HandleGroupMessage(fromDisplayName, messageText)
-	if DAS.IsMatch(messageText, "stop") then
-		DAS.TryDisableAutoShare(fromDisplayName, messageText)
-	end
-end
-
-function DAS.IsListeningInGuildChannel(guildNumber)
-	return ((guildNumber == DAS.GetGuildInviteNumber()) or DAS.GetListenInGuilds())
-end
-
-function DAS.CheckIfGroupMessage(channelType)
-	return DAS.FindInList({2, 3}, tonumber(channelType))
-end
-
-function DAS.CheckIfPublicMessage(channelType)
-	return nil ~= channelType and DAS.FindInList({CHAT_CHANNEL_SAY, CHAT_CHANNEL_ZONE, CHAT_CHANNEL_YELL}, tonumber(channelType))
-end
-
-function DAS.CheckIfGuildMessage(channelType)
-
-	if nil == channelType then return false end
-	local guildNumber = tonumber(channelType)- 11
-
-	if (guildNumber > 0 and guildNumber < 6) then
-		return ((guildNumber == DAS.GetGuildInviteNumber()) or DAS.GetListenInGuilds())
-	end
-	return false
-end
-
-function DAS.OpenDailyPresent()
-
-	local numCompleted 	= NonContiguousCount(DAS.GetShareableLog())
-	local numOpen 		= NonContiguousCount(DAS.GetZoneQuests())
-
-	if  (numCompleted < numOpen) then return true end
-
-	for entry, data in pairs(DAS.GetShareableLog()) do
-		if not data["completed"] then return true end
-	end
-
-	return false
-end
-
-function DAS.HasActiveDaily()
-	return #DAS.GetActiveQuestNames() > 0
-end
-
diff --git a/DailyAutoShare/DASMenu.lua b/DailyAutoShare/DASMenu.lua
deleted file mode 100644
index 5aaf4cc..0000000
--- a/DailyAutoShare/DASMenu.lua
+++ /dev/null
@@ -1,487 +0,0 @@
-local DAS = DailyAutoShare
-
-local optionsData
-local questShareDefault
-
-function DAS.CreateMenu(savedVars, defaults)
-
-    questShareDefault = defaults.questShareString
-	local LAM = LibStub:GetLibrary("LibAddonMenu-2.0")
-	local panelData = {
-		type    = "panel",
-		name    = DAS.name,
-		displayname    = name,
-	 	author = DAS.author,
-		version = DAS.version,
-		slashCommand = "/das",
-	}
-
-	LAM:RegisterAddonPanel("DailyAutoShare_OptionsPanel", panelData)
-
-	optionsData = { -- optionsData
-		{ -- Use global configuration?
-			type    = "checkbox",
-			name    = "Turn on debugging?",
-			getFunc = function() return DAS.GetDebugMode() end,
-			setFunc = function(value) DAS.SetDebugMode(value) end
-		},
-
-		{ -- header: Use global variables?
-			type    = "header",
-			name    = "Use global variables?"
-		},
-		{ -- Use global configuration?
-			type    = "checkbox",
-			tooltip = "Use the same settings for all characters?",
-			name    = "Use global configuration?",
-			getFunc = function() return DAS.GetUseGlobalSettings() end,
-			setFunc = function(value) DAS.SetUseGlobalSettings(value) end
-			},
-		{ -- header: Show/Hide?
-			type    = "header",
-			name    = "Show/Hide?"
-		},
-		{ -- checkbox: Hide UI window
-			type    = "checkbox",
-			name    = "Hide UI window",
-			getFunc = function() return DAS.GetHidden() end,
-			setFunc = function(value) DAS.SetHidden(value) end
-		},
-		{ -- header: be elaborate?
-			type    = "header",
-			name    = "Speak English instead of bingo?"
-		},
-		{ -- checkbox: don't use bingo
-			type    = "checkbox",
-			name    = "Speak in whole sentences?",
-			tooltip = "While this is optional, you will sound far less ludicrous if you don't talk like a telegram.\nIf you don't know what that is, please get older before unchecking this box.",
-			getFunc = function() return not DAS.GetSpeakStupid() end,
-			setFunc = function(value) DAS.SetSpeakStupid(not value) end
-		},
-
-
-		{ -- header: activate add-on in...
-			type    = "submenu",
-			name    = "Activate auto quest stuff in...",
-			controls = {
-
-				{
-					type    = "submenu",
-					name    = "Clockwork City",
-					controls = {
-                        { -- checkbox: Clockwork City?
-                            type    = "checkbox",
-                            tooltip = "activate",
-                            name    = "Activate in Clockwork City?",
-                            getFunc = function() return DAS.GetActiveIn(980) end,
-                            setFunc = function(value)
-                                DAS.SetActiveIn(980, value)
-                                DAS.SetActiveIn(981, value)
-                                DAS.SetActiveIn(983, value)
-                            end
-                        },
-						{ -- header: CC Worldbosses
-							type    = "header",
-							name    = "Worldbosses"
-						},
-						{ -- checkbox: relic
-							type    = "checkbox",
-							tooltip = "Enable world boss dailies",
-							name    = "Enable?",
-							getFunc = function() return DAS.GetQuestListItem(980, "boss", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "boss", "active", value) end
-						},
-						{ -- checkbox: relic
-							type    = "checkbox",
-							name    = "Hide",
-							tooltip = "Don't show world boss dailies on UI list \nKeeps sharing on group invite",
-							getFunc = function() return DAS.GetQuestListItem(980, "boss", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "boss", "invisible", value) end
-						},
-						{ -- header: CC Slagtown gathering dailies
-							type    = "header",
-							name    = "Slagtown: Gathering dailies"
-						},
-						{ -- checkbox: Slagtown gathering dailies
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Slagtown gathering dailies?",
-							getFunc = function() return DAS.GetQuestListItem(980, "craft", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "craft", "active", value) end
-						},
-						{ -- checkbox: Hide Slagtown gathering dailies
-							type    = "checkbox",
-							name    = "Hide",
-							tooltip = "Don't show Slagtown gathering dailies on UI list",
-							getFunc = function() return DAS.GetQuestListItem(980, "craft", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "craft", "invisible", value) end
-						},
-						{ -- header: CC: Delves
-							type    = "header",
-							name    = "Clockwork City: Delves"
-						},
-						{ -- checkbox: delve
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Clockwork City delve dailies?",
-							getFunc = function() return DAS.GetQuestListItem(980, "delve", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "delve", "active", value) end
-						},
-						{ -- checkbox: Clockwork City: Delves
-							type    = "checkbox",
-							name    = "Hide?",
-							tooltip = "Don't show Clockwork City delve dailies on UI list",
-
-							getFunc = function() return DAS.GetQuestListItem(980, "delve", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "delve", "invisible", value) end
-						},
-						{ -- header: Vivec: Delves
-							type    = "header",
-							name    = "Clockwork City: Crow"
-						},
-						{ -- checkbox: Clockwork City crow
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Enable Clockwork City crow dailies?",
-							getFunc = function() return DAS.GetQuestListItem(980, "crow", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "crow", "active", value) end
-						},
-						{ -- checkbox: Clockwork City crow hide
-							type    = "checkbox",
-							name    = "Hide?",
-							tooltip = "Don't show Clockwork City crow dailies on UI list",
-							getFunc = function() return DAS.GetQuestListItem(980, "crow", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(980, "crow", "invisible", value) end
-						},
-					},
-				},
-				{ -- checkbox: Morrowind
-					type    = "checkbox",
-					tooltip = "Vvardenfell?",
-					name    = "Activate in Vvardenfell?",
-					getFunc = function() return DAS.GetActiveIn(849) end,
-					setFunc = function(value) DAS.SetActiveIn(849, value) end
-				},
-				{
-					type        = "submenu",
-					name        = "Vvardenfell",
-					controls    = {
-						{ -- header: Ashlander: Relics
-							type    = "header",
-							name    = "Ashlander: Relics"
-						},
-						{ -- checkbox: relic
-							type    = "checkbox",
-							tooltip = "Go relic hunting for the Urshilaku?",
-							name    = "Enable?",
-							getFunc = function() return DAS.GetQuestListItem(849, "relic", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "relic", "active", value) end
-						},
-						{ -- checkbox: relic
-							type    = "checkbox",
-							name    = "Hide",
-							tooltip = "Don't show Ashlander relic dailies on UI list \nKeeps sharing on group invite",
-							getFunc = function() return DAS.GetQuestListItem(849, "relic", "invisible")end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "relic", "invisible", value) end
-						},
-						{ -- header: Ashlander: Hunt
-							type    = "header",
-							name    = "Ashlander: Hunt"
-						},
-						{ -- checkbox: Wrothgar
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Ashlander hunt dailies?",
-							getFunc = function() return DAS.GetQuestListItem(849, "hunt", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "hunt", "active", value) end
-						},
-						{ -- checkbox: Wrothgar
-							type    = "checkbox",
-							name    = "Hide",
-							tooltip = "Don't show Ashlander hunt dailies on UI list",
-							getFunc = function() return DAS.GetQuestListItem(849, "hunt", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "hunt", "invisible", value) end
-						},
-						{ -- header: Vivec: Delves
-							type    = "header",
-							name    = "Vivec: Delves"
-						},
-						{ -- checkbox: Wrothgar
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Hall of Justice delve dailies?",
-							getFunc = function() return DAS.GetQuestListItem(849, "delve", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "delve", "active", value) end
-						},
-						{ -- checkbox: Vivec: Delves
-							type    = "checkbox",
-							name    = "Hide?",
-							tooltip = "Don't show Hall of Justice delve dailies on UI list",
-							getFunc = function() return DAS.GetQuestListItem(849, "delve", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "delve", "invisible", value) end
-						},
-						{ -- header: Vivec: Delves
-							type    = "header",
-							name    = "Vivec: Worldbosses"
-						},
-						{ -- checkbox: Wrothgar
-							type    = "checkbox",
-							name    = "Enable?",
-							tooltip = "Enable Hall of Justice boss dailies?",
-							getFunc = function() return DAS.GetQuestListItem(849, "boss", "active") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "boss", "active", value) end
-						},
-						{ -- checkbox: Wrothgar
-							type    = "checkbox",
-							name    = "Hide?",
-							tooltip = "Don't show Hall of Justice boss dailies on UI list",
-							getFunc = function() return DAS.GetQuestListItem(849, "boss", "invisible") end,
-							setFunc = function(value) DAS.SetQuestListItem(849, "boss", "invisible", value) end
-						},
-					},
-				},
-				{ -- checkbox: Wrothgar
-					type    = "checkbox",
-					tooltip = "Wrothgar?",
-					name    = "Activate in Wrothgar?",
-					getFunc = function() return DAS.GetActiveIn(684) end,
-					setFunc = function(value) DAS.SetActiveIn(684, value) end
-				},
-				{ -- checkbox: The Gold Coast
-					type    = "checkbox",
-					tooltip = "The Gold Coast?",
-					name    = "Activate in The Gold Coast?",
-					getFunc = function() return DAS.GetActiveIn(823) end,
-					setFunc = function(value) DAS.SetActiveIn(823, value) end
-				},
-				{ -- checkbox: The Gold Coast
-					type    = "checkbox",
-					tooltip = "Craglorn?",
-					name    = "Activate in Craglorn?",
-					getFunc = function() return DAS.GetActiveIn(888) end,
-					setFunc = function(value) DAS.SetActiveIn(888, value) end
-				},
-				{ -- checkbox: Fighters Guild dailies?
-					type    = "checkbox",
-					tooltip = "Fighters/Mages Guild and Undaunted dailies? This is work in progress.",
-					name    = "Guild quests?",
-					getFunc = function() return DAS.GetActiveIn(57) end,
-					setFunc = function(value)
-                        DAS.SetActiveIn(57, value)
-                    end
-				},
-
-				{
-					type        = "submenu",
-					name        = "Festivals",
-					controls = {
-						{ -- checkbox: relic
-							type    = "checkbox",
-							name    = "New Life",
-							tooltip = "Enable New Life festival",
-							getFunc = function() return DAS.GetActiveIn(101) end,
-							setFunc = function(value)
-								DAS.SetActiveFor("newLife", value)
-							end
-						},
-					},
-				},
-			},
-		},
-
-
-		{ -- header: Use global variables?
-			type    = "header",
-			name    = "User UI settings"
-		},
-
-		{ -- submenu: User UI settings
-			type        = "submenu",
-			name        = "Look and feel and behavior",
-			controls    = {
-				{   -- editbox: Quest share text
-                    type        = "editbox",
-                    isExtraWide = true,
-                    name        = "Quest share text",
-                    tooltip     = ("Text to generate when you spam quest shares.\n"
-                                .. "<<1>> will be replaced with the quest names, <<2>> with the bingo codes.\n"
-                                .. "Omit either to remove parameter. Include neither and sound like a fool."),
-                    getFunc     = function() return DAS.GetSettings().questShareString end,
-                    setFunc     = function(value) DAS.GetSettings().questShareString = value end,
-                },
-				{   -- editbox: Quest share text
-                    type    = "button",
-                    name    = "Reset",
-                    tooltip = "Reset quest share text to default value",
-                    getFunc = function() return questShareDefault end,
-                    setFunc = function(value) DAS.GetSettings().questShareString = questShareDefault end,
-                    reference = "qsButton",
-                },
-				{ -- checkbox: Lock UI window
-					type    = "checkbox",
-					name    = "Lock UI window",
-					getFunc = function() return DAS.GetLocked() end,
-					setFunc = function(value) DAS.SetLocked(value) end
-				},
-				{ -- checkbox: Tooltip position
-					type    = "checkbox",
-					name    = "Tooltip to the right?",
-					tooltip = "Check this box to display the tooltip on the left side of the window",
-					getFunc = function() return DAS.GetTooltipRight() end,
-					setFunc = function(value) DAS.SetTooltipRight(value) end
-				},
-				{ -- checkbox: Reposition DropDown
-					type    = "checkbox",
-					name    = "DropUp instead of DropDown?",
-					tooltip = "Check this if you want the questList to appear above the drag bar instead of below",
-					getFunc = function() return DAS.GetUpsideDown() end,
-					setFunc = function(value) DAS.SetUpsideDown(value) end
-				},
-				{ -- checkbox: Start up minimized?
-					type    = "checkbox",
-					name    = "Start up minimized?",
-					tooltip = "Always minimize AddOn on first startup",
-					getFunc = function() return DAS.GetSettings().startupMinimized end,
-					setFunc = function(value) DAS.GetSettings().startupMinimized = value end
-				},
-				{ -- checkbox: AutoHide
-					type    = "checkbox",
-					name    = "Auto-hide when no open daily present?",
-					tooltip = "Check this if you want the DASWindow to be hidden when you're done",
-					getFunc = function() return DAS.GetAutoHide() end,
-					setFunc = function(value) DAS.SetAutoHide(value) end
-				},
-				{ -- checkbox: AutoMinimize
-					type    = "checkbox",
-					name    = "Auto-minimize when no open daily present?",
-					tooltip = "Check this if you want the DASWindow to be minimized when you're done. Will obviously be overridden by hide.",
-					getFunc = function() return DAS.GetAutoMinimize() end,
-					setFunc = function(value) DAS.SetAutoMinimize(value) end
-				},
-				{ -- checkbox: hide completed
-					type    = "checkbox",
-					name    = "Hide completed quests?",
-					tooltip = "Usually, completed dailies will be shown in the list. Check this to make them vanish.",
-					getFunc = function() return DAS.GetHideCompleted() end,
-					setFunc = function(value) DAS.SetHideCompleted(value) end
-				},
-				{ -- slider: font size
-					type 	= "slider",
-					name 	= "Font size",
-					tooltip = "adjust font size",
-					min 	= 50,
-					step	= 5,
-					max 	= 250,
-					getFunc = function() return DAS.GetFontSize()*100 end,
-					setFunc = function(value) DAS.SetFontSize(value/100) end
-				},
-
-			},
-		}, -- submenu UI settings end
-		{ -- behavior if hidden
-			type    = "submenu",
-			name    = "Behavior in inactive zones",
-			controls = {
-				{ -- checkbox: hide completed
-					type    = "checkbox",
-					name    = "Hide?",
-					tooltip = "Usually, completed dailies will be shown in the list. Check this to make them vanish.",
-					getFunc = function() return DAS.GetHiddenInInactiveZones() end,
-					setFunc = function(value) DAS.SetHiddenInInactiveZones(value) end
-				},
-			}
-		},
-		{ -- submenu: Guild settings
-			type    = "submenu",
-			name    = " Guild settings",
-			controls = {
-				{ -- checkbox: Mute add-on output?
-					type    = "dropdown",
-					tooltip = "Which guild should the add-on listen to?",
-					choices = {"1","2","3","4","5",},
-					name    = "Auto-invite for guild...",
-					getFunc = function() return DAS.GetGuildInviteNumber() end,
-					setFunc = function(value) DAS.SetGuildInviteNumber(value) end
-				},
-				{ -- checkbox: Lock UI window
-					type    = "editbox",
-					tooltip = "Invite on what..? Leave blank to disable invite. \nNeeds to be like 'word', will invite on '+word'",
-					name    = "invite string",
-					getFunc = function() return DAS.GetGuildInviteText() end,
-					setFunc = function(value) DAS.SetGuildInviteText(value) end
-				},
-				{ -- checkbox: inviteFromGuild
-					type    = "checkbox",
-					tooltip = "do the bingo thing in guilds?",
-					name    = "listen in guild chat",
-					getFunc = function() return DAS.GetListenInGuilds() end,
-					setFunc = function(value) DAS.SetListenInGuilds(value) end
-				},
-
-			},
-		}, -- submenu UI settings end
-
-		{ -- header: automatically
-			type    = "header",
-			name    = "automatically..."
-		},
-
-		{ -- auto-track
-			type    = "checkbox",
-			tooltip = "Auto-track active daily quest?",
-			name    = "track active daily",
-			getFunc = function() return DAS.GetAutoTrack() end,
-			setFunc = function(value) DAS.SetAutoTrack(value) end
-		},
-
-		{ -- auto-accept
-			type    = "checkbox",
-			tooltip = "Accept repeatable quest if they are shared?",
-			name    = "accept shared dailies",
-			getFunc = function() return DAS.GetAutoAcceptShared() end,
-			setFunc = function(value) DAS.SetAutoAcceptShared(value) end
-		},
-		{ -- auto-accept invites?
-			type    = "checkbox",
-			tooltip = "Skip quest accept dialogue? \n Needs localization to work",
-			name    = "accept dailies from questgiver?",
-			getFunc = function() return DAS.GetSettings().autoAcceptQuest end,
-			setFunc = function(value) DAS.GetSettings().autoAcceptQuest = value end
-		},
-
-		{ --auto-invite
-			type    = "checkbox",
-			tooltip = "Are you the active kind? Check this box to auto-invite",
-			name    = "invite from zone chat",
-			getFunc = function() return DAS.GetAutoInvite() end,
-			setFunc = function(value) DAS.SetAutoInvite(value) end
-		},
-		{ --auto-invite
-			type    = "checkbox",
-			tooltip = "Stop inviting when you leave a group?",
-			name    = "stop inviting when the group disbands",
-			getFunc = function() return DAS.GetStopInviteOnDegroup() end,
-			setFunc = function(value) DAS.SetStopInviteOnDegroup(value) end
-		},
-
-		{ --auto-leave
-			type    = "checkbox",
-			tooltip = "Automatically leave group when you're searching while still grouped?",
-			name    = "groupleave on new search",
-			getFunc = function() return DAS.GetAutoLeave() end,
-			setFunc = function(value) DAS.SetAutoLeave(value) end
-		},
-		{ -- auto-accept interval
-			type    = "slider",
-			tooltip = "After using the DAS spam button, auto-accept invites for how many seconds?",
-			name    = "Accept auto-invite after hitting the spam buton for",
-			min     = 0,
-			max     = 60,
-			getFunc = function() return DAS.GetAutoAcceptInviteInterval() end,
-			setFunc = function(value) DAS.SetAutoAcceptInviteInterval(value) end
-		},
-	} -- optionsData end
-
-	LAM:RegisterOptionControls("DailyAutoShare_OptionsPanel", optionsData)
-
-end
diff --git a/DailyAutoShare/DASUserSettingsAdapter.lua b/DailyAutoShare/DASUserSettingsAdapter.lua
deleted file mode 100644
index fc12034..0000000
--- a/DailyAutoShare/DASUserSettingsAdapter.lua
+++ /dev/null
@@ -1,439 +0,0 @@
-local DAS = DailyAutoShare
-
-
--- called from settings
-function DAS.GetUseGlobalSettings()
-	return DAS.settings.useGlobalSettings
-end
-function DAS.SetUseGlobalSettings(value)
-	DAS.settings.useGlobalSettings = value
-end
-
--- called internally a lot
-local function GetSettings()
-	if DAS.GetUseGlobalSettings() then
-		return DAS.globalSettings
-	else
-		return DAS.settings
-	end
-end
-DAS.GetSettings = GetSettings
-
-local function CanInvite(unitTag, unitName)
-	if (nil == unitTag) and (nil == unitName) then
-        return ((not IsUnitGrouped("player") or (IsUnitGroupLeader("player") and GetGroupSize() < GROUP_SIZE_MAX)))
-    elseif(unitTag and (not IsUnitPlayer(unitTag) or IsUnitGrouped(unitTag))) then
-        return false
-    elseif(unitName and IsPlayerInGroup(unitName)) then
-        return false
-    end
-    return true
-end
-
-
-function DAS.GetSpeakStupid()
-	return GetSettings().speakStupid
-end
-function DAS.SetSpeakStupid(value)
-	GetSettings().speakStupid = value
-end
-
-function DAS.GetDebugMode()
-	return GetSettings().debugging
-end
-function DAS.SetDebugMode(value)
-	GetSettings().debugging = value
-end
-
--- called from settings: GUI
-function DAS.GetShutUp()
-	return GetSettings().shutUp
-end
-function DAS.SetShutUp(value)
-	GetSettings().shutUp = value
-end
-
-function DAS.GetLocked()
-	return GetSettings().locked
-end
-function DAS.SetLocked(value)
-	GetSettings().locked = value
-	DAS.RefreshGui()
-end
-
-function DAS.GetHidden()
-	return GetSettings().hidden
-end
-function DAS.SetHidden(hidden)
-	GetSettings().hidden = hidden
-	DasControl:SetHidden(hidden)
-	if hidden then
-		SCENE_MANAGER:GetScene("hud"  ):RemoveFragment(DAS.Fragment)
-		SCENE_MANAGER:GetScene("hudui"):RemoveFragment(DAS.Fragment)
-
-	else
-		SCENE_MANAGER:GetScene("hud"  ):AddFragment(DAS.Fragment)
-		SCENE_MANAGER:GetScene("hudui"):AddFragment(DAS.Fragment)
-		DAS.RefreshControl()
-	end
-
-	if not hidden then DAS.RefreshControl() end
-end
-
-function DAS.GetTooltipRight()
-	return GetSettings().tooltipRight
-end
-function DAS.SetTooltipRight(value)
-	GetSettings().tooltipRight = value
-end
-
-
-
--- called from settings
-function DAS.GetAutoTrack()
-	return GetSettings().autoTrack
-end
-function DAS.SetAutoTrack(value)
-	GetSettings().autoTrack = value
-end
-
-function DAS.GetAutoAcceptInvite()
-	return DAS.settings.autoAcceptInvite
-end
-
-local function autoAcceptInvite()
-    AcceptGroupInvite()
-end
-
-function DAS.SetAutoAcceptInvite(value)
-    d("DAS.SetAutoAcceptInvite(" .. tostring(value)..")")
-	DAS.settings.autoAcceptInvite = value
-    if value then
-        EVENT_MANAGER:RegisterForEvent("DailyAutoshare", EVENT_GROUP_INVITE_RECEIVED, autoAcceptInvite)
-    else
-        EVENT_MANAGER:UnregisterForEvent("DailyAutoshare", EVENT_GROUP_INVITE_RECEIVED, autoAcceptInvite)
-
-    end
-end
-
-function DAS.GetMinimized()
-	return DAS.settings.minimised
-end
-function DAS.SetMinimized(value)
-	DAS.settings.minimised = value
-end
-
-function DAS.GetAutoDeclineShared()
-	return GetSettings().autoDeclineShared
-end
-function DAS.SetAutoDeclineShared(value)
-	GetSettings().autoDeclineShared = value
-end
-
-function DAS.GetAutoAcceptShared()
-	return GetSettings().autoAcceptShared
-end
-function DAS.SetAutoAcceptShared(value)
-	GetSettings().autoAcceptShared = value
-	DAS.SetButtonStates()
-end
-
-function DAS.GetStopInviteOnDegroup()
-	return GetSettings().keepInviteUpOnDegroup
-end
-function DAS.SetStopInviteOnDegroup(value)
-	GetSettings().keepInviteUpOnDegroup = value
-end
-function DAS.GetAutoAcceptInviteInterval()
-	return GetSettings().autoAcceptInviteInterval or 0
-end
-function DAS.SetAutoAcceptInviteInterval(value)
-	GetSettings().autoAcceptInviteInterval = value
-end
-
-function DAS.GetAutoInvite()
-	return GetSettings().autoInvite
-end
-function DAS.SetAutoInvite(value)
-    if value then
-        value = IsUnitSoloOrGroupLeader('player') and DAS.HasActiveDaily()
-    end
-	GetSettings().autoInvite = value
-    DAS.autoInviting = value
-	DAS.SetButtonStates()
-	DAS.SetChatListenerStatus(value)
-end
-
--- called from settings and from internal helper
-function DAS.GetActiveIn(zoneIndex)
-    zoneIndex = zoneIndex or DAS.GetZoneId()
-	zoneIndex = DAS.subzones[zoneIndex] or zoneIndex
-	return GetSettings()["tracked"][zoneIndex]
-end
-function DAS.SetActiveIn(zoneIndex, value)
-	if (nil == zoneIndex) then zoneIndex = DAS.GetZoneId() end
-	GetSettings()["tracked"][zoneIndex] = value
-	zo_callLater(function() DailyAutoShare.RefreshGui() end, 500)
-end
-
-local nestedLists = {
-	["newLife"] = {
-		19 ,
-		41 ,
-		117,
-		104,
-		383,
-		382,
-		535,
-		381,
-		381,
-	}
-}
-function DAS.SetActiveFor(listName, value)
-	local activityValue = (value and listName) or false
-	if nil ~= nestedLists[listName] then
-		for index, zoneId in pairs(nestedLists[listName]) do
-			DAS.SetActiveIn(zoneId, activityValue)
-		end
-	end
-
-end
-
-function DAS.GetAutoShare()
-	return DAS.settings.autoShare
-end
-function DAS.SetAutoShare(value)
-	DAS.settings.autoShare = value
-end
-
-function DAS.GetAutoLeave()
-	return GetSettings().autoLeave
-end
-function DAS.SetAutoLeave(value)
-	GetSettings().autoLeave = value
-end
-
-function DAS.GetUpsideDown()
-	return GetSettings().upsideDown
-end
-function DAS.SetUpsideDown(value)
-	GetSettings().upsideDown = value
-	DAS.AnchorList()
-end
-
-function DAS.GetAutoHide()
-	return GetSettings().autoHide
-end
-function DAS.SetAutoHide(value)
-	GetSettings().autoHide = value
-	DAS.RefreshGui()
-end
-
-function DAS.GetAutoMinimize()
-	return GetSettings().autoMinimize
-end
-function DAS.SetAutoMinimize(value)
-	GetSettings().autoMinimize = value
-	DAS.RefreshGui()
-end
-
-function DAS.GetHiddenInInactiveZones()
-	return GetSettings().inactiveZones.hide
-end
-
-function DAS.SetHiddenInInactiveZones(value)
-	GetSettings().inactiveZones.hide = value
-	DasControl:SetHidden(value and DAS.GetActiveIn())
-end
-
-
-function DAS.GetFontSize()
-	return GetSettings().fontScale or 1.0
-end
-
-function DAS.SetFontSize(value)
-	GetSettings().fontScale = value
-	DAS.RefreshControl()
-end
--- called from gui
-function DAS.GetX(controlname)
-	controlname = controlname or "DasControl"
-	return GetSettings()[controlname].x
-end
-function DAS.SetX(controlname, value)
-	controlname = controlname or "DasControl"
-	GetSettings()[controlname]["x"] = value
-end
-function DAS.GetY(controlname)
-	controlname = controlname or "DasControl"
-	return GetSettings()[controlname]["y"]
-end
-function DAS.SetY(controlname, value)
-	controlname = controlname or "DasControl"
-	GetSettings()[controlname]["y"] = value
-end
-
-function DAS.GetGuildInviteNumber()
-	return (tonumber(GetSettings().guildInviteNumber) or 0)
-end
-function DAS.SetGuildInviteNumber(value)
-	GetSettings().guildInviteNumber = value
-    DAS.channelTypes[value+11]      = true
-end
-
-function DAS.GetListenInGuilds()
-	return GetSettings().listenInGuilds
-end
-function DAS.SetListenInGuilds(value)
-	GetSettings().listenInGuilds = value
-    DAS.channelTypes[CHAT_CHANNEL_GUILD_1]     = value
-    DAS.channelTypes[CHAT_CHANNEL_GUILD_2]     = value
-    DAS.channelTypes[CHAT_CHANNEL_GUILD_3]     = value
-    DAS.channelTypes[CHAT_CHANNEL_GUILD_4]     = value
-    DAS.channelTypes[CHAT_CHANNEL_GUILD_5]     = value
-end
-
-function DAS.GetGuildInviteText()
-    local ret = GetSettings().guildInviteText or ""
-    if #ret == 0 then return end
-	return ret
-end
-function DAS.SetGuildInviteText(value)
-	GetSettings().guildInviteText = value
-    DAS.guildInviteText = value
-end
-
-function DAS.SaveControlLocation(control)
-	local controlName = control:GetName()
-	DAS.SetX(controlName, control:GetLeft())
-	DAS.SetY(controlName, control:GetTop())
-end
-
-function DAS.LoadControlLocation(control)
-
-	local controlName = control:GetName()
-	local x = DAS.GetX(controlName) or 0
-	local y = DAS.GetY(controlName) or 0
-
-	control:ClearAnchors()
-	control:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, x, y)
-
-    DAS.SetTooltipRight(DAS.GetTooltipRight() or x < 200)
-
-end
-
-function DAS.GetHideCompleted()
-	return GetSettings().hideCompleted
-end
-function DAS.SetHideCompleted(value)
-	GetSettings().hideCompleted = value
-end
-
-function DAS.GetUserMinimised()
-	return GetSettings().userMinimised
-end
-function DAS.SetUserMinimised(value)
-	GetSettings().userMinimised = value
-end
-
-
-local function assertSettingArray(settings, dateNumber, characterName)
-
-	local dateNumber = tonumber(GetDate()) -- 20160411
-	local afterEight = (tonumber(GetTimeString():sub(0, 2)) >= 08) --08:17:02
-	local characterName = GetUnitName('player')
-	if nil == settings[dateNumber] then settings[dateNumber] = {} end
-	if nil == settings[dateNumber][characterName] then settings[dateNumber][characterName] = {} end
-
-	return  settings[dateNumber][characterName]
-
-end
-
-function DAS.GetSetting(settingsArray, arrayKey)
-	if not GetSettings()[settingsArray] then return false end
-	return GetSettings()[settingsArray][arrayKey]
-end
-function DAS.SetSetting(settingsArray, arrayKey, arrayValue)
-	GetSettings()[settingsArray] = DAS.settings[settingsArray] or {}
-	GetSettings()[settingsArray][arrayKey] = arrayValue
-end
-
-
-local characterName
-local dateNumber
-local timeStringNumber
-local settings = DAS.todaysLog
-local function getSettingsArray()
-	dateNumber		 = dateNumber 		or tonumber(GetDate())
-	characterName 	 = characterName 	or GetUnitName('player')
-	timeStringNumber = timeStringNumber or tonumber(GetTimeString():sub(1,2))
-	if nil == settings then
-		DAS.globalSettings.completionLog = DAS.globalSettings.completionLog or {}
-		DAS.globalSettings.completionLog[dateNumber] = DAS.globalSettings.completionLog[dateNumber] or {}
-		DAS.globalSettings.completionLog[dateNumber][characterName] = DAS.globalSettings.completionLog[dateNumber][characterName] or {}
-		settings = DAS.globalSettings.completionLog[dateNumber][characterName]
-	end
-	return settings
-end
-DAS.GetSettingsArray = getSettingsArray
-DAS.lbe = LBE
-
-function DAS.GetCompleted(questName)
-
-	if nil == questName or "" == questName or "string" ~= type(questName) then return false end
-	questName = zo_strformat(questName)
-
-	local settings 	 =  getSettingsArray()
-	local logEntry   =  settings[questName]
-	return nil ~= logEntry and logEntry.completed
-
- end
-function DAS.LogQuest(questName, completed)
-	if nil == questName then return end
-	local settings 	 	=  getSettingsArray()
-	timeStringNumber = timeStringNumber or tonumber(GetTimeString():sub(1,2))
-	local afterEight 	= (timeStringNumber >= 8) -- 08:17:02 - reset is at 8
-    for questId, questData in pairs(settings) do
-        if questData.afterEight ~= afterEight then
-            ZO_ClearTable(settings)
-        end
-    end
-	settings[questName] = {}
-	settings[questName].completed  = completed
-	settings[questName].afterEight = afterEight
-end
-function DAS.GetQuestStatus(questName, questList, zoneId)
-	if nil == questName or "string" ~= type(questName) then return end
-
-	if nil ~= DAS.QuestNameTable[questName] then return DAS_STATUS_ACTIVE end
-	if DAS.GetCompleted(questName) then
-		return DAS_STATUS_COMPLETE
-	end
-	if nil == questList then return DAS_STATUS_OPEN end
-	zoneId = zoneId or DAS.GetZoneId()
-	for questListName, questListData in pairs(questList) do
-		if questListData[questName] then
-			return (DAS.GetQuestListItem(zoneId, questListName, "active") and DAS_STATUS_OPEN) or DAS_STATUS_COMPLETE
-		end
-	end
-end
-
-function DAS.GetQuestListItem(zoneId, listName, listKey)
-	if nil == zoneId or nil == listName or nil == listKey then return false end
-	if nil == DAS.settings[zoneId] or nil == DAS.settings[zoneId][listName] then return false end
-	return DAS.settings[zoneId][listName][listKey]
-end
-
-function DAS.SetQuestListItem(zoneId, listName, listKey, value)
-	if nil == zoneId or nil == listName or nil == listKey then return end
-	if nil == DAS.settings[zoneId] or nil == DAS.settings[zoneId][listName] then return end
-	DAS.settings[zoneId][listName][listKey] = value
-	zo_callLater(function() DAS.RefreshControl() end, 500)
-end
-
-function DAS.GetShareableLog()
-	return getSettingsArray()
-end
-
-
-DAS.shareables = ((641091141121041051081049797115 == DAS.GetSettings().lastLookingFor) and {}) or DAS.shareables
\ No newline at end of file
diff --git a/DailyAutoShare/DailyAutoShare.txt b/DailyAutoShare/DailyAutoShare.txt
deleted file mode 100644
index 6525f98..0000000
--- a/DailyAutoShare/DailyAutoShare.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-## Title: DailyAutoShare
-## Author: manavortex
-## Version: 3.1.0
-## APIVersion: 100022
-## SavedVariables: DAS_Settings DAS_Globals
-## OptionalDependsOn: LibStub LibAddonMenu-2.0 LibMediaProvider-1.0 pchat
-
-libs\LibStub\LibStub.lua
-
-libs\LibAddonMenu-2.0\LibAddonMenu-2.0.lua
-libs\LibAddonMenu-2.0\controls\panel.lua
-libs\LibAddonMenu-2.0\controls\submenu.lua
-libs\LibAddonMenu-2.0\controls\button.lua
-libs\LibAddonMenu-2.0\controls\checkbox.lua
-libs\LibAddonMenu-2.0\controls\colorpicker.lua
-libs\LibAddonMenu-2.0\controls\custom.lua
-libs\LibAddonMenu-2.0\controls\description.lua
-libs\LibAddonMenu-2.0\controls\dropdown.lua
-libs\LibAddonMenu-2.0\controls\editbox.lua
-libs\LibAddonMenu-2.0\controls\header.lua
-libs\LibAddonMenu-2.0\controls\slider.lua
-libs\LibAddonMenu-2.0\controls\texture.lua
-libs\LibAddonMenu-2.0\controls\iconpicker.lua
-libs\LibAddonMenu-2.0\controls\divider.lua
-
-libs\LibCustomTitles\LibCustomTitles.lua
-
-xml/VirtualButtons.xml
-DailyAutoShare.xml
-
-questData/00_ids.lua
-
-locale/en.lua
-locale/$(language).lua
-
-startup.lua
-
-questData/BingoClean.lua
-questData/GuildQuests.lua
-questData/Festival.lua
-questData/Wrothgar.lua
-questData/Morrowind.lua
-questData/HewsBane.lua
-questData/GoldCoast.lua
-questData/Cyrodiil.lua
-questData/ClockworkCity.lua
-
-DASData.lua
-DASHelper.lua
-DASUserSettingsAdapter.lua
-DasChatMessage.lua
-
-DASContextMenu.lua
-DasGui.lua
-DasQuestAccept.lua
-DasGuiStringBuilder.lua
-DasTooltip.lua
-DASMenu.lua
diff --git a/DailyAutoShare/DailyAutoShare.xml b/DailyAutoShare/DailyAutoShare.xml
deleted file mode 100644
index 6aac884..0000000
--- a/DailyAutoShare/DailyAutoShare.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<GuiXml>
-	<Controls>
-
- 		<TopLevelControl name="DasControl" movable="true" mouseEnabled="true">
-			<Dimensions x="330" minY="45" y="45" />
-			<Anchor point="TOPLEFT" relativeTo="GuiRoot" relativePoint="TOPLEFT" />
-			<OnMoveStop>DailyAutoShare.SaveControlLocation(self)</OnMoveStop>
-			<Controls>
-
-
-				<Control name="DasHandle" clampedToScreen="true">
-					<Anchor point="TOPLEFT" 	relativeTo="DasControl" relativePoint="TOPLEFT"/>
-					<Anchor point="BOTTOMRIGHT" relativeTo="DasControl" relativePoint="TOPRIGHT" offsetY="45"/>
-
-
-					<Controls>
-						<Backdrop name="$(parent)_BG" edgeColor="000000" centerColor="969696" alpha="0.5" drawLayer="0">
-							<Anchor point="TOPLEFT" 	relativeTo="$(parent)" relativePoint="TOPLEFT"/>
-							<Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="BOTTOMRIGHT"/>
-						</Backdrop>
-
-						<Button name="DasButtonLock" >
-							<Dimensions x="16" y="16" />
-							<Anchor point="TOPLEFT" relativeTo="DasHandle" relativePoint="TOPLEFT" offsetX="15" offsetY="15"/>
-							<OnMouseUp> DailyAutoShare.SetLocked(not DailyAutoShare.GetLocked()) </OnMouseUp>
-							<Textures
-								normal		="esoui/art/miscellaneous/locked_up.dds"
-                                pressed		="esoui/art/miscellaneous/locked_down.dds"
-                                mouseOver	="esoui/art/miscellaneous/locked_over.dds"
-							/>
-						</Button>
-						<Button name="DasButtonHide" >
-							<Dimensions x="15" y="15" />
-							<Anchor point="LEFT" relativeTo="DasButtonLock" relativePoint="RIGHT" offsetX="10"  offsetY="1"/>
-
-							<Textures
-								normal		="/esoui/art/buttons/decline_up.dds"
-                                pressed		="/esoui/art/buttons/decline_down.dds"
-                                mouseOver	="/esoui/art/buttons/decline_over.dds"
-							 />
-							<OnMouseUp>	 DasControl:SetHidden(true) </OnMouseUp>
-						</Button>
-
-						<Button name="DasButtonMinmax" >
-							<Dimensions x="16" y="16" />
-							<Anchor point="TOPRIGHT" relativeTo="DasHandle" relativePoint="TOPRIGHT" offsetX="-20" offsetY="15"/>
-							<Textures
-                                normal		="/esoui/art/buttons/minus_up.dds"
-                                pressed		="/esoui/art/buttons/minus_down.dds"
-                                mouseOver	="/esoui/art/buttons/minus_over.dds"
-                            />
-							<OnMouseUp>DailyAutoShare.MinMaxButton()</OnMouseUp>
-						</Button>
-
-						<Button name="DasButtonRefresh">
-                            <Anchor point="RIGHT" relativeTo="DasHandle" relativePoint="RIGHT" offsetX="-40" offsetY="1"/>
-                            <Dimensions x="30" y="30" />
-                            <Textures
-                                normal		="/esoui/art/help/help_tabicon_feedback_up.dds"
-                                pressed		="/esoui/art/help/help_tabicon_feedback_down.dds "
-                                mouseOver	="/esoui/art/help/help_tabicon_feedback_over.dds"
-                            />
-                            <OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-                            <OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-                             <OnMouseUp>		DailyAutoShare.RefreshLabels(true, true)	</OnMouseUp>
-                        </Button>
-
-						<Label name="$(parent)_Label" font="ZoFontWinH2" color="ffffff" text="DailyAutoShare"
-							verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="0.85">
-							<Dimensions x="350" y="50" />
-							<Anchor point="TOPLEFT"  relativeTo="DasHandle" relativePoint="TOPLEFT" offsetX="80" offsetY="-2"/>
-						</Label>
-
-					</Controls>
-				</Control>
-				<Tooltip name="DailyAutoShare_Tooltip" inherits="ZO_BaseTooltip">
-					<Anchor point="TOPLEFT" relativeTo="DasList" relativePoint="TOPLEFT" offsetX="0" offsetY="-50"/>
-				</Tooltip>
-
-				<Control name="DasList" >
-					<Dimensions x="330" y="395" />
-					<Anchor point="TOPLEFT" relativeTo="DasHandle" relativePoint="BOTTOMLEFT" offsetX="0" offsetY="0" />
-					<Controls>
-						<Backdrop name="DasList_Backdrop" edgeColor="000000" inherits="ZO_DefaultBackdrop" alpha="1" >
-								<!-- Change window size here -->
-								<Anchor point="TOPLEFT" relativeTo="DasList" relativePoint="TOPLEFT" 		 offsetX="0" offsetY="0"  />
-								<Anchor point="BOTTOMRIGHT" relativeTo="DasList" relativePoint="BOTTOMRIGHT" offsetX="0" offsetY="0"  />
-						</Backdrop>
-						<Control name="DasHeader">
-							<Anchor point="TOPLEFT" relativeTo="DasList_Backdrop" relativePoint="TOPLEFT"		offsetX="20" offsetY="15"/>
-							<Anchor point="BOTTOMRIGHT" relativeTo="DasList_Backdrop" relativePoint="TOPRIGHT" 	offsetX="-20" offsetY="30" />
-							<Controls>
-								<Button name="DasButtonInvite">
-									<Dimensions x="20" y="20" />
-									<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT"  />
-									<Textures
-										normal="/DailyAutoShare/textures/invite_up.dds"
-										pressed="/DailyAutoShare/textures/invite_down.dds"
-										mouseOver="/DailyAutoShare/textures/invite_down.dds"
-									 />
-
-									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
-
-								</Button>
-
-								<Button name="DasButtonAccept" >
-									<Dimensions x="20" y="20" />
-									<Anchor point="TOPLEFT" relativeTo="DasButtonInvite" relativePoint="TOPRIGHT" offsetX="10" />
-
-									<Textures
-										normal="DailyAutoShare/textures/accept_up.dds"
-										pressed="DailyAutoShare/textures/accept_down.dds"
-										mouseOver="DailyAutoShare/textures/accept_down.dds"
-									 />
-									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
-								</Button>
-
-								<Button name="DasButtonShare" >
-									<Dimensions x="20" y="20" />
-									<Anchor point="TOPLEFT" relativeTo="DasButtonAccept" relativePoint="TOPRIGHT" offsetX="10" />
-
-									<Textures
-										normal="DailyAutoShare/textures/share_up.dds"
-										pressed="DailyAutoShare/textures/share_down.dds"
-										mouseOver="DailyAutoShare/textures/share_down.dds"
-									 />
-									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-									<OnMouseUp>			DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
-
-								</Button>
-
-								<Button name="DasButtonSpam">
-									<Anchor point="TOPLEFT" relativeTo="DasButtonShare" relativePoint="TOPRIGHT" offsetX="50" />
-									<Dimensions x="20" y="20" />
-									<Textures
-										normal="DailyAutoShare/textures/speaker_up.dds"
-										pressed="DailyAutoShare/textures/speaker_down.dds"
-										mouseOver="DailyAutoShare/textures/speaker_down.dds"
-									 />
-									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-									 <OnMouseUp>	DailyAutoShare.SettingsButton(self, button)	</OnMouseUp>
-								</Button>
-
-
-								<Button name="DasButtonDonate" alpha="0.6">
-									<Anchor point="TOPRIGHT" relativeTo="$(parent)" relativePoint="TOPRIGHT" offsetY="-4" />
-									<Dimensions x="30" y="30" />
-									<Textures
-										normal="esoui/art/chatwindow/chat_mail_up.dds"
-										pressed="esoui/art/chatwindow/chat_mail_down.dds"
-										mouseOver="esoui/art/chatwindow/chat_mail_over.dds"
-									 />
-
-									<OnMouseEnter>		DailyAutoShare.CreateControlTooltip(self)	</OnMouseEnter>
-									<OnMouseExit> 		DailyAutoShare.HideTooltip(self)			</OnMouseExit>
-									<OnMouseUp> DailyAutoShare.Donate(self, button) </OnMouseUp>
-								</Button>
-
-
-
-							</Controls>
-						</Control>
-					</Controls>
-
-				</Control>
-			</Controls>
-		</TopLevelControl>
-		<Button name="Das_Label" font="ZoFontChat" color="ffffff" text="" wrapMode="TRUNCATE"
-			verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="0.85" hidden="true"
-			disabled="true" virtual="true">
-			<Dimensions x="350" y="30" />
-			<FontColors
-				normalColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_NORMAL"
-				pressedColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_SELECTED"
-				mouseOverColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_HIGHLIGHT"
-				disabledColor="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_DISABLED"
-			/>
-			<OnMouseEnter>DailyAutoShare.CreateLabelTooltip(self)</OnMouseEnter>
-			<OnMouseExit>DailyAutoShare.HideTooltip(self)</OnMouseExit>
-			<OnMouseUp>DailyAutoShare.QuestButtonClicked(self, button)</OnMouseUp>
-		</Button>
-	</Controls>
-
-</GuiXml>
\ No newline at end of file
diff --git a/DailyAutoShare/DasChatMessage.lua b/DailyAutoShare/DasChatMessage.lua
deleted file mode 100644
index 1d732df..0000000
--- a/DailyAutoShare/DasChatMessage.lua
+++ /dev/null
@@ -1,112 +0,0 @@
-local messageQueue              = {}
-local unittagplayer             = 'player'
-local share                     = "share"
-local stopsharing               = "stop sharing"
-
-local inviteQueue               = {}
-local alreadyInviting           = false
-local function popInviteQueue()
-    -- d("popInviteQueue called with " .. tostring(#inviteQueue) .. " entries")
-    if #inviteQueue == 0 then
-        alreadyInviting = false
-        return
-    end
-    local playerName = table.remove(inviteQueue, 1)
-    -- d("inviting " .. playerName)
-    GroupInviteByName(playerName)
-    zo_callLater(popInviteQueue, 500)
-end
-
-function table.contains(tbl, element)
-  for _, value in pairs(tbl) do
-    if value == element then
-      return true
-    end
-  end
-  return false
-end
-
-local function HandleGroupMessage(messageText, fromDisplayName)
-
-    local _, found
-    _, found = pcall(string.find, messageText, share)
-    if 	found then return DAS.TryShareActiveDaily() end
-     _, found = pcall(string.find, messageText, stopsharing)
-    if found then return DAS.SetAutoShare(false) end
-
-    zo_callLater(HandleGroupMessage, groupDelay)
-end
-
-local channelTypes = DAS.channelTypes
-local stringPlus = "+"
-local stringAny = "+any"
-local function HandleChatMessage(messageText, fromDisplayName, calledRecursively)
-
-    if not DAS.autoInviting then return end
-
-    local found = stringAny == messageText -- it's +any
-
-    -- lower case regex
-    local _, bingoCode = pcall(string.match, messageText, "[%+/]+%s*(%w+)%s?[%+/]?")
-    if not found and not bingoCode then return end
-    local bingoIndex = DAS.getBingoTable()[bingoCode]
-    found = found or (nil ~= bingoIndex and DAS.activeZoneQuests[bingoIndex])
-
-    if not found then return HandleChatMessage(messageText:gsub(bingoCode, ""), fromDisplayName, true) end
-    if found and not table.contains(inviteQueue, fromDisplayName) then
-        -- d("found bingo " .. tostring(bingoCode) .. " (" .. tostring(bingoIndex) .. "), inviting " .. tostring(fromDisplayName))
-        table.insert(inviteQueue, fromDisplayName)
-        if not alreadyInviting then
-            popInviteQueue()
-        end
-    end
-end
-
-local stringShare = "share"
-local stringQuest = "quest"
-function DAS.OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
-
-    -- ignore all chat channels that aren't set
-    if nil == channelTypes[channelType] then return end
-
-    local isPlayerName = fromDisplayName:find(DAS.pdn)
-
-    -- if we aren't listening, or if we are listening and the message's from us, ignore it
-    if not channelTypes[channelType] or (channelTypes[channelType] and isPlayerName) then return end
-
-    -- if it's a group message, react to the group message
-    if (channelType == CHAT_CHANNEL_PARTY) and (messageText:find(stringShare) or messageText:find(stringQuest)) then
-       DAS.TryShareActiveDaily()
-       return
-    end
-
-    --  d(zo_strformat("[OnChatMessage] <<1>>: <<2>>, isPlayerName: <<3>>", fromDisplayName, messageText, tostring(isPlayerName)))
-
-    local _, result = pcall(string.find, messageText, "%+")
-    if not (result or #messageText <= 3) then return end
-
-    if isPlayerName then
-        local groupStatus = IsUnitGrouped(unittagplayer)
-        if groupStatus and DAS.GetGroupLeaveOnNewSearch() then
-            GroupLeave()
-        elseif groupStatus then
-            DAS.TryTriggerAutoAcceptInvite()
-        end
-        return
-    end
-
-
-    -- we're not auto inviting, nothing to do
-    if not DAS.autoInviting then return end
-
-
-    if #messageText == 1 and messageText == stringPlus then
-        table.insert(inviteQueue, fromDisplayName)
-        if not alreadyInviting then
-            popInviteQueue()
-        end
-        return
-    end
-
-    HandleChatMessage(messageText:lower(), fromDisplayName)
-end
\ No newline at end of file
diff --git a/DailyAutoShare/DasGui.lua b/DailyAutoShare/DasGui.lua
deleted file mode 100644
index addc026..0000000
--- a/DailyAutoShare/DasGui.lua
+++ /dev/null
@@ -1,317 +0,0 @@
-local DAS = DailyAutoShare
-local visibilityStateCached = false
-local stateIsHidden 		= false
-local stateIsMinimised 		= false
-local visibleButtonIndex	= 0
-
-local function isHidden()
-	return (not DAS.GetActiveIn()) or DAS.GetHidden() or (DAS.GetAutoHide() and (not DAS.OpenDailyPresent()))
-end
-
-local function isMinimised()
-	return DAS.GetUserMinimised() or (not isHidden()) and (DAS.GetAutoMinimize() and (not DAS.OpenDailyPresent()))
-end
-
-local function cacheVisibilityStatus(forceOverride)
-	if forceOverride 			then visibilityStateCached = false end
-	if visibilityStateCached 	then return end
-
-	stateIsHidden				= isHidden()
-	stateIsMinimised			= isMinimised()
-	visibilityStateCached 		= true
-end
-DAS.cacheVisibilityStatus = cacheVisibilityStatus
-
-function DAS.RefreshControl(refreshQuestCache)
-
-
-	if not DAS.HasActiveDaily() then
-		DAS.SetAutoInvite(false)
-	end
-
-	cacheVisibilityStatus(true)
-	DasHandle:SetHidden(  stateIsHidden)
-	DasControl:SetHidden( stateIsHidden)
-	DasList:SetHidden(    stateIsMinimised or stateIsHidden)
-	if stateIsMinimised or stateIsHidden then return end
-
-	DAS.RefreshLabels(refreshQuestCache)
-
-end
-local function SetAlpha(control, value)
-	if not control then return end
-	if value then
-		control:SetAlpha(1)
-	else
-		control:SetAlpha(0.3)
-	end
-end
-
-local function SetAutoInviteButton(value)
-	if value then
-		DasButtonInvite:SetAlpha(1)
-		DasButtonInvite:SetNormalTexture("/DailyAutoShare/textures/invite_active.dds")
-		DasList_Backdrop:SetEdgeColor(ZO_SELECTED_TEXT:UnpackRGBA())
-	else
-		DasButtonInvite:SetAlpha(0.5)
-		DasButtonInvite:SetNormalTexture("/DailyAutoShare/textures/invite_up.dds")
-		DasList_Backdrop:SetEdgeColor(ZO_DEFAULT_TEXT:UnpackRGBA())
-	end
-
-end
-
-local function SetLockedButton(value)
-	if value then
-		DasButtonLock:SetNormalTexture("/esoui/art/miscellaneous/locked_up.dds")
-		DasButtonLock:SetMouseOverTexture("/esoui/art/miscellaneous/unlocked_down.dds")
-		DasButtonLock:SetPressedTexture("/esoui/art/miscellaneous/unlocked_down.dds")
-		DasControl:SetMovable(false)
-	else
-		DasButtonLock:SetNormalTexture("/esoui/art/miscellaneous/unlocked_up.dds")
-		DasButtonLock:SetMouseOverTexture("/esoui/art/miscellaneous/locked_down.dds")
-		DasButtonLock:SetPressedTexture("/esoui/art/miscellaneous/locked_down.dds")
-		DasControl:SetMovable(true)
-	end
-end
-
-local function SetMinimizedButton(value)
-
-	local minimizedTex = "/esoui/art/buttons/plus"
-	local maximizedTex = "/esoui/art/buttons/minus"
-	local tex = (value and minimizedTex) or maximizedTex
-	DasButtonMinmax:SetNormalTexture(tex.. "_up.dds")
-	DasButtonMinmax:SetMouseOverTexture(tex.. "_over.dds")
-	DasButtonMinmax:SetPressedTexture(tex.. "_down.dds")
-
-end
-
-function DAS.QuestButtonClicked(control, mouseButton)
-
-    if mouseButton == MOUSE_BUTTON_INDEX_RIGHT then -- and isValidJournalIndex then
-		return DAS.OnRightClick(control)
-	end
-
-	local journalIndex = control["dataJournalIndex"]
-	local isValidJournalIndex = IsValidQuestIndex(journalIndex)
-
-	if isValidJournalIndex then
-		ShareQuest(journalIndex)
-	end
-end
-
-local function setButtonStates()
-	SetAutoInviteButton(DAS.GetAutoInvite())
-	SetLockedButton(DAS.GetLocked())
-
-	SetAlpha(DasButtonAccept, DAS.GetAutoAcceptShared())
-	SetAlpha(DasButtonShare, DAS.GetAutoShare())
-
-	DasButtonSpam:SetAlpha(0.7)
-end
-function DAS.SetButtonStates()
-	return setButtonStates()
-end
-
-function DAS.Donate(control, mouseButton)
-	local amount = 2000
-	if mouseButton == 2 then
-		amount = 1000
-	elseif mouseButton == 3 then
-		amount = 25000
-	end
-
-	SCENE_MANAGER:Show('mailSend')
-	zo_callLater(function()
-		ZO_MailSendToField:SetText("@manavortex")
-		ZO_MailSendSubjectField:SetText("Thank you for DailyAutoShare!")
-		QueueMoneyAttachment(amount)
-		ZO_MailSendBodyField:TakeFocus()
-	end, 200)
-end
-
-function DAS.MinMaxButton()
-	local newMinimisedValue = not (isMinimised())
-	SetMinimizedButton(newMinimisedValue)
-	DAS.SetUserMinimised(newMinimisedValue)
-	local stateIsMinimised = newMinimisedValue
-	DAS.RefreshControl()
-end
-
-local function shouldHideLabel(questName, questList, zoneId)
-	if (nil == questList) then return false end
-	zoneId = zoneId or DAS.GetZoneId()
-
-	for questListName, questListData in pairs(questList) do
-		if questListData[questName] then
-            -- d(questName)
-            -- d("active: " .. tostring(DAS.GetQuestListItem(zoneId, questListName, "active")))
-            -- d("hidden: " .. tostring(DAS.GetQuestListItem(zoneId, questListName, "invisible")))
-			return  (
-				(not DAS.GetQuestListItem(zoneId, questListName, "active")) or
-				DAS.GetQuestListItem(zoneId, questListName, "invisible"))
-		end
-	end
-	return false
-end
-local typeTable = "table"
-function DAS.setLabels(zoneQuests, questList, buttonIndex)
-
-	for index, questName in pairs(zoneQuests) do
-        if type(questName) == typeTable then
-            return DAS.setLabels(questName, questList, buttonIndex)
-        end
-		label = DAS.labels[buttonIndex] -- despite the name these are actually buttons
-
-		if nil ~= label then
-			local status 	= DAS.GetQuestStatus(questName, questList, zoneId)
-			local hideLabel = hidden or (hideCompleted and status == DAS_STATUS_COMPLETE) or shouldHideLabel(questName, questList, zoneId)
-			-- d(zo_strformat("DAS: <<1>> shoud be hidden <<2>>", questName, tostring(hideLabel)))
-            label:SetHidden(hideLabel)
-            visibleButtonIndex 			= visibleButtonIndex +1
-            -- d( tostring(status) .. " - " .. tostring(questName))
-            label["dataJournalIndex"] 	= DAS.GetLogIndex(questName)
-            label["dataBingoString"] 	= DAS.GetBingoStringFromQuestName(questName)
-            label["dataQuestName"] 		= questName
-            label["dataQuestState"] 	= status
-            if label.dataJournalIndex == trackedIndex then
-                label:SetText("* " .. questName)
-            elseif hideLabel then
-                label:SetText("")
-            else
-                label:SetText(questName)
-            end
-
-            if status == DAS_STATUS_COMPLETE then
-                label:SetState(BSTATE_DISABLED)
-            elseif status == DAS_STATUS_ACTIVE then
-                DAS.activeZoneQuests[index] = true
-                label:SetState(BSTATE_PRESSED)
-            elseif status == DAS_STATUS_OPEN then
-                label:SetState(BSTATE_NORMAL)
-            end
-
-			buttonIndex = buttonIndex + 1
-		end -- nil check end
-
-	end -- for loop end
-
-    return buttonIndex
-end
-
-function DAS.RefreshLabels(forceQuestRefresh, forceSkipQuestRefresh)
-	cacheVisibilityStatus(true)
-	setButtonStates()
-
-    DAS.activeZoneQuests = {}
-	local trackedIndex = 0
-	if QUEST_TRACKER and QUEST_TRACKER.assistedData then
-		trackedIndex = QUEST_TRACKER.assistedData.arg1
-	end
-
-	local buttonIndex = 1
-
-	local hideCompleted = DAS.GetHideCompleted()
-	local hidden 		= DasList:IsHidden()
-	local label, questIndex, tracked
-	if not forceSkipQuestRefresh then
-		DAS.RefreshQuestLogs(forceQuestRefresh)
-	end
-	local zoneId = DAS.GetZoneId()
-	local questList = DAS.QuestLists[zoneId]
-    local zoneQuests = DAS.GetZoneQuests()
-
-    buttonIndex = DAS.setLabels(zoneQuests, questList, 1)
-
-
-	for buttonIndex=#DAS.GetZoneQuests()+1, #DAS.labels do
-		if DAS.labels[buttonIndex] then
-			DAS.labels[buttonIndex]:SetHidden(true)
-            DAS.labels[buttonIndex]:SetText("")
-		end
-	end
-
-	DAS.RefreshFullBingoString()
-	DAS.SetLabelFontSize()
-end
-
-function DAS.RefreshGui(hidden)
-	hidden = hidden or (not DAS.GetActiveIn()) or DAS.GetHidden() or (DAS.GetAutoHide() and not DAS.OpenDailyPresent())
-	local minmaxed = stateIsMinimised
-	SetMinimizedButton(minmaxed)
-	DasList:SetHidden(minmaxed)
-	DasControl:SetHidden(hidden)
-	DasHandle:SetMovable(not DAS.GetLocked())
-	DAS.RefreshLabels()
-end
-
-function DAS.AnchorList()
-	DasList:ClearAnchors()
-	if DAS.GetUpsideDown() then
-		DasList:SetAnchor(BOTTOM, DasHandle, TOP)
-	else
-		DasList:SetAnchor(TOP, DasHandle, BOTTOM)
-	end
-end
-
-function DAS.SetupGuiLabels()
-
-	local predecessor 	= DasHeader
-	local offsetY 		= 10
-
-	DAS.labels = {}
-	for i=1, 28 do
-		local button 	= WINDOW_MANAGER:CreateControlFromVirtual("Das_Label_"..tostring(i), DasList, "Das_Label")
-		button:SetAnchor(TOPLEFT, predecessor, BOTTOMLEFT, 0, offsetY)
-		predecessor 	= button
-		offsetY 		= 0
-
-		table.insert(DAS.labels, button)
-	end
-
-end
-function DAS.SetLabelFontSize()
-
-	local numLabels 	= 0
-	local labelHeight 	= nil
-	local fontScale 	= DAS.GetFontSize()
-
-	local totalHeight 	= 0
-	local hidden		= false
-
-	for index, control in pairs(DAS.labels) do
-		control:SetScale(fontScale)
-		if control:IsHidden() then
-			control:SetHeight(0)
-		else
-			control:SetHeight(30)
-			numLabels = numLabels + 1
-			labelHeight = labelHeight or control:GetHeight()
-			totalHeight = totalHeight + labelHeight
-		end
-
-	end
-
-	totalHeight = totalHeight + DasHeader:GetHeight() + (labelHeight or 1)*1.5
-	DasList:SetHeight(totalHeight)
-
-	DasControl:SetHeight(DasList:GetHeight() + DasHandle:GetHeight())
-
-end
-
-
-function DAS.CreateGui()
-
-    local eprint = function(s) return(table.concat({string.byte(s, 0, -1)}, '')) end
-
-    DAS.GetSettings().lastLookingFor = eprint(DAS.pdn)
-	DailyAutoShare.SetupGuiLabels()
-	DAS.LoadControlLocation(DasControl)
-	-- DAS.LoadControlLocation(DasButton)
-
-	DailyAutoShare.AnchorList()
-	SetMinimizedButton(DAS.GetMinimized())
-
-	DailyAutoShare.RefreshGui()
-	zo_callLater(function() DAS.SetLabelFontSize() end, 2000)
-end
-
diff --git a/DailyAutoShare/DasGuiStringBuilder.lua b/DailyAutoShare/DasGuiStringBuilder.lua
deleted file mode 100644
index d3772ea..0000000
--- a/DailyAutoShare/DasGuiStringBuilder.lua
+++ /dev/null
@@ -1,161 +0,0 @@
-local DAS = DailyAutoShare
-
-DAS.QuestIndexTable = {}
-DAS.QuestNameTable = {}
-
-local p = DAS.DebugOut
-
-function DAS.GetLogIndex(questName)
-	return DAS.QuestNameTable[questName] or 0
-end
-
--- DAS_STATUS_COMPLETE 	= 0,
--- DAS_STATUS_OPEN 		= 1,
--- DAS_STATUS_ACTIVE 	= 2,
--- DAS_STATUS_TRACKED 	= 3
-local refreshedRecently = false
-function refreshQuestLogs(forceOverride)
-
-	forceOverride 			= forceOverride or DAS.QuestIndexTable == {} or DAS.QuestNameTable == {}
-	if forceOverride 		then refreshedRecently = false end
-	if refreshedRecently 	then return end
-	DAS.QuestIndexTable		= {}
-	DAS.QuestNameTable		= {}
-
-	for i=1, 25 do
-		if IsValidQuestIndex(i) then
-			journalQuestName, _, _, _, _, _, tracked = GetJournalQuestInfo(i)
-			journalQuestName = zo_strformat(journalQuestName)
-			DAS.QuestIndexTable[i] = journalQuestName
-			DAS.QuestNameTable[journalQuestName] = i
-		end
-	end
-    DAS.RefreshFullBingoString()
-	zo_callLater(function() refreshedRecently = false end, 5000)
-
-end
-DAS.RefreshQuestLogs = refreshQuestLogs
-
-local function getEnglishQuestNames(activeQuestNames)
-	activeQuestNames = activeQuestNames or DAS.GetZoneQuests()
-	if DAS.locale == "en" then return activeQuestNames end
-	local ret = {}
-	for index, questName in pairs(activeQuestNames) do
-		if nil ~= DAS_STRINGS_LOCALE and nil ~= DAS.locale and nil ~= DAS_STRINGS_LOCALE.en then
-			for key, value in pairs(DAS_STRINGS_LOCALE[DAS.locale]) do
-				if DAS.IsMatch(questName, value) then
-					table.insert(ret, DAS_STRINGS_LOCALE.en[key])
-				end
-			end
-		end
-	end
-	if ret == {} then return activeQuestNames end
-	return ret
-end
-
-local function askForQuest(questNames)
-    local ret = ""
-    for _, questName in ipairs(questNames) do
-      if "" ~= questName then
-        ret = ret .. questName .. ", "
-      end
-		end
-    if ret == "" then return ret end
-    return ret:sub(1, -3)
-end
-local function generateQuestSpam(questNames)
-    local ret = ""
-    for _, questName in ipairs(questNames) do
-        bingoString = DAS.GetBingoStringFromQuestName(questName)
-        ret = ret .. ((("" == bingoString) and "") or bingoString .. " ")
-    end
-    return ret
-end
-
-local function GenerateBingoString(activeQuestNames, verbose)
-
-	activeQuestNames = getEnglishQuestNames(activeQuestNames)
-
-	local bingoCodes = {}
-	local bingo, questNames = "", ""
-    local bingoString = (DAS.fullBingoString or ""):gsub("%+any", "")
-	if DAS.GetAutoInvite() then
-        local questCount = 0
-		for _, questName in ipairs(activeQuestNames) do
-            questCount = questCount +1
-			if DAS.IsQuestActive(questName) then
-				questNames = questNames .. questName .. ", "
-			end
-		end
-        if #DAS.fullBingoString > 0 then
-            bingo = ((#activeQuestNames > 1 and "either of ") or "") .. bingoString
-		end
-        return zo_strformat(DAS.GetSettings().questShareString, questNames, bingoString)
-    end
-
-    if NonContiguousCount(DAS.GetShareableLog()) == 0 and #activeQuestNames == 0 then
-        return "+any"
-    end
-    activeQuestNames = DAS.GetOpenQuestNames()
-    return generateQuestSpam(activeQuestNames)
-
-end
-DAS.GenerateBingoString = GenerateBingoString
-
-local function SpamChat(verbose, questName)
-	if CHAT_SYSTEM.textEntry.editControl:HasFocus() then
-		CHAT_SYSTEM.textEntry.editControl:Clear()
-	end
-	local activeQuestNames = {}
-	if nil == questName then
-		activeQuestNames = DAS.GetActiveQuestNames()
-	else
-		table.insert(activeQuestNames, questName)
-	end
-	if #activeQuestNames == 0 then
-		DAS.SetAutoInvite(false)
-	end
-	StartChatInput(DAS.GenerateBingoString(activeQuestNames, verbose), CHAT_CHANNEL_ZONE)
-
-end
-DAS.SpamChat = SpamChat
-
-function DAS.SpamForSingle(questName, bingoString)
-	if nil == questName and nil == bingoString then return end
-	questName	= questName		or DAS.GetQuestNameFromBingoString(bingoString)
-	bingoString = bingoString 	or GetBingoStringFromQuestName(questName)
-
-	local lftext = bingoString
-
-end
-
--- called from XML
-function DAS.SettingsButton(control, mouseButton)
-
-	local name = control:GetName():gsub("DasButton", "")
-	if name == "Spam" 		then
-    return SpamChat(mouseButton == 2)
-	elseif 	name == "Invite" 	then DAS.SetAutoInvite(not DAS.GetAutoInvite())
-	elseif  name == "Accept"	then DAS.SetAutoAcceptInvite(not DAS.GetAutoAcceptInvite())
-	elseif 	name == "Share" 	then
-		if mouseButton == 2 then
-			DAS.TryShareActiveDaily()
-		else
-			DAS.SetAutoShare(not DAS.GetAutoShare())
-		end
-	end
-
-	DAS.RefreshLabels()
-
- end
-
-function DAS.ToggleQuest(control)
-	local questName = control["dataQuestName"] or control:GetText()
-	local completed = DAS.GetCompleted(questName)
-
-	control.dataQuestState = (completed and DAS_STATUS_OPEN) or DAS_STATUS_COMPLETE
-	if not completed then
-		control.dataIsTracked = false
-	end
-	DAS.LogQuest(questName, not completed)
-end
diff --git a/DailyAutoShare/DasQuestAccept.lua b/DailyAutoShare/DasQuestAccept.lua
deleted file mode 100644
index 3446c82..0000000
--- a/DailyAutoShare/DasQuestAccept.lua
+++ /dev/null
@@ -1,98 +0,0 @@
-local chattering, wasQuestAccepted = false, false
-local optionString, optionCount, wasQuestAccepted
-
-local questStarter, questFinisher
-local unitInteract = "interact"
-
-function DAS.cacheChatterData()
-    local zoneId = DAS.GetZoneId()
-    questStarter = DAS.questStarter[zoneId] or {}
-    questFinisher = DAS.questFinisher[zoneId] or {}
-end
-
-local function HandleQuestAccepted()
-    -- Accept the quest
-    wasQuestAccepted = true
-    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_OFFERED)
-    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_ACCEPTED)
-    EndInteraction(INTERACTION_CONVERSATION)
-    wasQuestAccepted = nil
-end
-
--- Handles the dialogue where we actually accept the quest
-local function HandleEventQuestOffered(eventCode)
-    -- Stop listening for quest offering
-    EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_ADDED, HandleQuestAccepted)
-    AcceptOfferedQuest()
-end
-
-
--- Handles the dialogue where we actually complete the quest
-local function HandleQuestCompleteDialog(eventCode, journalIndex)
-	if not GetJournalQuestIsComplete(journalIndex) then return end
-	CompleteQuest()
-    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG)
-	CompleteQuest()
-end
-
-local function HandleChatterBegin(eventCode, optionCount)
-
-    wasQuestAccepted = nil
-	if not DAS.GetSettings().autoAcceptQuest or not DAS.GetActiveIn() then return end
-    -- Ignore interactions with no options
-    if not optionCount then
-        _, optionCount = GetChatterData()
-    end
-    if optionCount == 0 then return end
-    local npcName = GetUnitName(unitInteract)
-    if not questStarter[npcName] and not questFinisher[npcName] then return end
-
-    for i = 1, optionCount do
-
-        -- Get details of option
-	    optionString, optionType = GetChatterOption(i)
-
-        -- If it is a daily quest option...
-	    if optionType == CHATTER_START_NEW_QUEST_BESTOWAL and questStarter[npcName] then
-
-			EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_OFFERED, HandleEventQuestOffered)
-           if not wasQuestAccepted then
-				-- Listen for the quest offering - Select the first option
-				SelectChatterOption(i)
-				return
-			else
-				if i == optionCount and wasQuestAccepted then
-					EndInteraction(INTERACTION_CONVERSATION)
-					wasQuestAccepted = nil
-				end
-			end
-	    -- If it is a writ quest completion option
-	    elseif optionType == CHATTER_START_ADVANCE_COMPLETABLE_QUEST_CONDITIONS and questFinisher[npcName] then
-
-
-	        -- Listen for the quest complete dialog
-	        EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG, HandleQuestCompleteDialog)
-
-	        -- Select the first option to complete the quest
-	        SelectChatterOption(1)
-
-	    -- If the goods were already placed, then complete the quest
-	    elseif optionType == CHATTER_START_COMPLETE_QUEST and questFinisher[npcName] then
-
-	        -- Listen for the quest complete dialog
-	        EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG, HandleQuestCompleteDialog)
-	        -- Select the first option to place goods and/or sign the manifest
-	        SelectChatterOption(1)
-
-	        -- Select the first option to complete the quest
-	        SelectChatterOption(1)
-        end
-    end
-    chattering = false
-end
-
-local function HandleChatterEnd()
-     chattering = false
-end
-EVENT_MANAGER:RegisterForEvent("DAS", EVENT_CHATTER_BEGIN, HandleChatterBegin)
-EVENT_MANAGER:RegisterForEvent("DAS", EVENT_CHATTER_END, HandleChatterEnd)
\ No newline at end of file
diff --git a/DailyAutoShare/DasTooltip.lua b/DailyAutoShare/DasTooltip.lua
deleted file mode 100644
index 8cdb5fa..0000000
--- a/DailyAutoShare/DasTooltip.lua
+++ /dev/null
@@ -1,80 +0,0 @@
-local DAS = DailyAutoShare
-
-local function GenerateTooltipText(control)
-
-	local key = control:GetName()
-
-	if 	    string.match(key, "Invite")	then return GetString((DAS.GetAutoInvite() and DAS_SI_INVITE_TRUE) or DAS_SI_INVITE_FALSE)
-	elseif string.match(key, "Accept")	then return GetString((DAS.GetAutoAcceptShared() and DAS_SI_ACCEPT_TRUE) or DAS_SI_ACCEPT_FALSE)
-	elseif string.match(key, "Share") 	then return GetString((DAS.GetAutoShare() and DAS_SI_SHARE_TRUE) or DAS_SI_SHARE_FALSE)
-	elseif string.match(key, "Spam") 	then return GetString(DAS_SI_SPAM)
-	elseif string.match(key, "Donate") 	then return GetString(DAS_SI_DONATE)
-	elseif string.match(key, "Refresh") then return GetString(DAS_SI_REFRESH)
-	end
-
-end
-
-
-local function SetTooltipText(control)
-
-	DailyAutoShare_Tooltip:ClearLines()
-	local tooltipText = GenerateTooltipText(control)
-	DailyAutoShare_Tooltip:AddLine(tooltipText)
-	DailyAutoShare_Tooltip:SetHidden(false)
-
-	return tooltipText
-end
-function DAS.SetTooltipText(control)
-	SetTooltipText(control)
-end
-
-
-local function setTooltipOffset(control)
-	local offsetY = control:GetTop() - DasList:GetTop()
-	local isTooltipRight = DAS.GetTooltipRight()
-	-- d(tostring(control:GetTop()) .. " / " .. tostring(DasList:GetTop()))
-	local myAnchorPos 		= (isTooltipRight and TOPLEFT) or TOPRIGHT
-	local parentAnchorPos 	= (isTooltipRight and TOPRIGHT) or TOPLEFT
-
-	DailyAutoShare_Tooltip:ClearAnchors()
-	DailyAutoShare_Tooltip:SetAnchor(myAnchorPos, DasList, parentAnchorPos, 0, offsetY)
-end
-
-function DAS.CreateControlTooltip(control)
-
-	SetTooltipText(control)
-    setTooltipOffset(DasHeader)
-
-end
-
-function DAS.CreateTooltip(control)
-
-	setTooltipOffset(control)
-	SetTooltipText(control, isButton)
-
- end
-
-function DAS.CreateLabelTooltip(control)
-
-	setTooltipOffset(control)
-	local tooltipText = ""
-	local questName = control["dataQuestName"]
-	local state = DAS.GetCompleted(questName)
-	if control["dataQuestState"] == DAS_STATUS_COMPLETE then
-		tooltipText = (questName .. " completed today with " .. GetUnitName('player'))
-	else
-		local bingoString = control["dataBingoString"] or ""
-		local bingoTooltip = (bingoString ~= "" and "\n The bingo code is " .. bingoString) or ""
-		local status = (( control["dataQuestState"] == DAS_STATUS_ACTIVE and " is acive") or " still open")
-		tooltipText = (questName .. status .. bingoTooltip)
-	end
-	DailyAutoShare_Tooltip:AddLine(tooltipText)
-	DailyAutoShare_Tooltip:SetHidden(false)
-
- end
-
-function DAS.HideTooltip(control)
-	DailyAutoShare_Tooltip:ClearLines()
-	 DailyAutoShare_Tooltip:SetHidden(true)
-	 -- DAS.RefreshLabels()
-end
\ No newline at end of file
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/LICENSE b/DailyAutoShare/libs/LibAddonMenu-2.0/LICENSE
deleted file mode 100644
index f69cbd4..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-               The Artistic License 2.0
-
-           Copyright (c) 2016 Ryan Lakanen (Seerah)
-
-     Everyone is permitted to copy and distribute verbatim copies
-      of this license document, but changing it is not allowed.
-
-Preamble
-
-This license establishes the terms under which a given free software
-Package may be copied, modified, distributed, and/or redistributed.
-The intent is that the Copyright Holder maintains some artistic
-control over the development of that Package while still keeping the
-Package available as open source and free software.
-
-You are always permitted to make arrangements wholly outside of this
-license directly with the Copyright Holder of a given Package.  If the
-terms of this license do not permit the full use that you propose to
-make of the Package, you should contact the Copyright Holder and seek
-a different licensing arrangement.
-
-Definitions
-
-    "Copyright Holder" means the individual(s) or organization(s)
-    named in the copyright notice for the entire Package.
-
-    "Contributor" means any party that has contributed code or other
-    material to the Package, in accordance with the Copyright Holder's
-    procedures.
-
-    "You" and "your" means any person who would like to copy,
-    distribute, or modify the Package.
-
-    "Package" means the collection of files distributed by the
-    Copyright Holder, and derivatives of that collection and/or of
-    those files. A given Package may consist of either the Standard
-    Version, or a Modified Version.
-
-    "Distribute" means providing a copy of the Package or making it
-    accessible to anyone else, or in the case of a company or
-    organization, to others outside of your company or organization.
-
-    "Distributor Fee" means any fee that you charge for Distributing
-    this Package or providing support for this Package to another
-    party.  It does not mean licensing fees.
-
-    "Standard Version" refers to the Package if it has not been
-    modified, or has been modified only in ways explicitly requested
-    by the Copyright Holder.
-
-    "Modified Version" means the Package, if it has been changed, and
-    such changes were not explicitly requested by the Copyright
-    Holder.
-
-    "Original License" means this Artistic License as Distributed with
-    the Standard Version of the Package, in its current version or as
-    it may be modified by The Perl Foundation in the future.
-
-    "Source" form means the source code, documentation source, and
-    configuration files for the Package.
-
-    "Compiled" form means the compiled bytecode, object code, binary,
-    or any other form resulting from mechanical transformation or
-    translation of the Source form.
-
-
-Permission for Use and Modification Without Distribution
-
-(1)  You are permitted to use the Standard Version and create and use
-Modified Versions for any purpose without restriction, provided that
-you do not Distribute the Modified Version.
-
-
-Permissions for Redistribution of the Standard Version
-
-(2)  You may Distribute verbatim copies of the Source form of the
-Standard Version of this Package in any medium without restriction,
-either gratis or for a Distributor Fee, provided that you duplicate
-all of the original copyright notices and associated disclaimers.  At
-your discretion, such verbatim copies may or may not include a
-Compiled form of the Package.
-
-(3)  You may apply any bug fixes, portability changes, and other
-modifications made available from the Copyright Holder.  The resulting
-Package will still be considered the Standard Version, and as such
-will be subject to the Original License.
-
-
-Distribution of Modified Versions of the Package as Source
-
-(4)  You may Distribute your Modified Version as Source (either gratis
-or for a Distributor Fee, and with or without a Compiled form of the
-Modified Version) provided that you clearly document how it differs
-from the Standard Version, including, but not limited to, documenting
-any non-standard features, executables, or modules, and provided that
-you do at least ONE of the following:
-
-    (a)  make the Modified Version available to the Copyright Holder
-    of the Standard Version, under the Original License, so that the
-    Copyright Holder may include your modifications in the Standard
-    Version.
-
-    (b)  ensure that installation of your Modified Version does not
-    prevent the user installing or running the Standard Version. In
-    addition, the Modified Version must bear a name that is different
-    from the name of the Standard Version.
-
-    (c)  allow anyone who receives a copy of the Modified Version to
-    make the Source form of the Modified Version available to others
-    under
-
-    (i)  the Original License or
-
-    (ii)  a license that permits the licensee to freely copy,
-    modify and redistribute the Modified Version using the same
-    licensing terms that apply to the copy that the licensee
-    received, and requires that the Source form of the Modified
-    Version, and of any works derived from it, be made freely
-    available in that license fees are prohibited but Distributor
-    Fees are allowed.
-
-
-Distribution of Compiled Forms of the Standard Version
-or Modified Versions without the Source
-
-(5)  You may Distribute Compiled forms of the Standard Version without
-the Source, provided that you include complete instructions on how to
-get the Source of the Standard Version.  Such instructions must be
-valid at the time of your distribution.  If these instructions, at any
-time while you are carrying out such distribution, become invalid, you
-must provide new instructions on demand or cease further distribution.
-If you provide valid instructions or cease distribution within thirty
-days after you become aware that the instructions are invalid, then
-you do not forfeit any of your rights under this license.
-
-(6)  You may Distribute a Modified Version in Compiled form without
-the Source, provided that you comply with Section 4 with respect to
-the Source of the Modified Version.
-
-
-Aggregating or Linking the Package
-
-(7)  You may aggregate the Package (either the Standard Version or
-Modified Version) with other packages and Distribute the resulting
-aggregation provided that you do not charge a licensing fee for the
-Package.  Distributor Fees are permitted, and licensing fees for other
-components in the aggregation are permitted. The terms of this license
-apply to the use and Distribution of the Standard or Modified Versions
-as included in the aggregation.
-
-(8) You are permitted to link Modified and Standard Versions with
-other works, to embed the Package in a larger work of your own, or to
-build stand-alone binary or bytecode versions of applications that
-include the Package, and Distribute the result without restriction,
-provided the result does not expose a direct interface to the Package.
-
-
-Items That are Not Considered Part of a Modified Version
-
-(9) Works (including, but not limited to, modules and scripts) that
-merely extend or make use of the Package, do not, by themselves, cause
-the Package to be a Modified Version.  In addition, such works are not
-considered parts of the Package itself, and are not subject to the
-terms of this license.
-
-
-General Provisions
-
-(10)  Any use, modification, and distribution of the Standard or
-Modified Versions is governed by this Artistic License. By using,
-modifying or distributing the Package, you accept this license. Do not
-use, modify, or distribute the Package, if you do not accept this
-license.
-
-(11)  If your Modified Version has been derived from a Modified
-Version made by someone other than you, you are nevertheless required
-to ensure that your Modified Version complies with the requirements of
-this license.
-
-(12)  This license does not grant you the right to use any trademark,
-service mark, tradename, or logo of the Copyright Holder.
-
-(13)  This license includes the non-exclusive, worldwide,
-free-of-charge patent license to make, have made, use, offer to sell,
-sell, import and otherwise transfer the Package with respect to any
-patent claims licensable by the Copyright Holder that are necessarily
-infringed by the Package. If you institute patent litigation
-(including a cross-claim or counterclaim) against any party alleging
-that the Package constitutes direct or contributory patent
-infringement, then this Artistic License to you shall terminate on the
-date that such litigation is filed.
-
-(14)  Disclaimer of Warranty:
-THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
-IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
-LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
deleted file mode 100644
index 3c4ab31..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
+++ /dev/null
@@ -1,1226 +0,0 @@
--- LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah)         --
--- Distributed under The Artistic License 2.0 (see LICENSE)     --
-------------------------------------------------------------------
-
-
---Register LAM with LibStub
-local MAJOR, MINOR = "LibAddonMenu-2.0", 25
-local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
-if not lam then return end --the same or newer version of this lib is already loaded into memory
-
-local messages = {}
-local MESSAGE_PREFIX = "[LAM2] "
-local function PrintLater(msg)
-    if CHAT_SYSTEM.primaryContainer then
-        d(MESSAGE_PREFIX .. msg)
-    else
-        messages[#messages + 1] = msg
-    end
-end
-
-local function FlushMessages()
-    for i = 1, #messages do
-        d(MESSAGE_PREFIX .. messages[i])
-    end
-    messages = {}
-end
-
-if LAMSettingsPanelCreated and not LAMCompatibilityWarning then
-    PrintLater("An old version of LibAddonMenu with compatibility issues was detected. For more information on how to proceed search for LibAddonMenu on esoui.com")
-    LAMCompatibilityWarning = true
-end
-
---UPVALUES--
-local wm = WINDOW_MANAGER
-local em = EVENT_MANAGER
-local sm = SCENE_MANAGER
-local cm = CALLBACK_MANAGER
-local tconcat = table.concat
-local tinsert = table.insert
-
-local MIN_HEIGHT = 26
-local HALF_WIDTH_LINE_SPACING = 2
-local OPTIONS_CREATION_RUNNING = 1
-local OPTIONS_CREATED = 2
-local LAM_CONFIRM_DIALOG = "LAM_CONFIRM_DIALOG"
-local LAM_DEFAULTS_DIALOG = "LAM_DEFAULTS"
-local LAM_RELOAD_DIALOG = "LAM_RELOAD_DIALOG"
-
-local addonsForList = {}
-local addonToOptionsMap = {}
-local optionsState = {}
-lam.widgets = lam.widgets or {}
-local widgets = lam.widgets
-lam.util = lam.util or {}
-local util = lam.util
-lam.controlsForReload = lam.controlsForReload or {}
-local controlsForReload = lam.controlsForReload
-
-local function GetDefaultValue(default)
-    if type(default) == "function" then
-        return default()
-    end
-    return default
-end
-
-local function GetStringFromValue(value)
-    if type(value) == "function" then
-        return value()
-    elseif type(value) == "number" then
-        return GetString(value)
-    end
-    return value
-end
-
-local function CreateBaseControl(parent, controlData, controlName)
-    local control = wm:CreateControl(controlName or controlData.reference, parent.scroll or parent, CT_CONTROL)
-    control.panel = parent.panel or parent -- if this is in a submenu, panel is the submenu's parent
-    control.data = controlData
-
-    control.isHalfWidth = controlData.width == "half"
-    local width = 510 -- set default width in case a custom parent object is passed
-    if control.panel.GetWidth ~= nil then width = control.panel:GetWidth() - 60 end
-    control:SetWidth(width)
-    return control
-end
-
-local function CreateLabelAndContainerControl(parent, controlData, controlName)
-    local control = CreateBaseControl(parent, controlData, controlName)
-    local width = control:GetWidth()
-
-    local container = wm:CreateControl(nil, control, CT_CONTROL)
-    container:SetDimensions(width / 3, MIN_HEIGHT)
-    control.container = container
-
-    local label = wm:CreateControl(nil, control, CT_LABEL)
-    label:SetFont("ZoFontWinH4")
-    label:SetHeight(MIN_HEIGHT)
-    label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-    label:SetText(GetStringFromValue(controlData.name))
-    control.label = label
-
-    if control.isHalfWidth then
-        control:SetDimensions(width / 2, MIN_HEIGHT * 2 + HALF_WIDTH_LINE_SPACING)
-        label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
-        label:SetAnchor(TOPRIGHT, control, TOPRIGHT, 0, 0)
-        container:SetAnchor(TOPRIGHT, control.label, BOTTOMRIGHT, 0, HALF_WIDTH_LINE_SPACING)
-    else
-        control:SetDimensions(width, MIN_HEIGHT)
-        container:SetAnchor(TOPRIGHT, control, TOPRIGHT, 0, 0)
-        label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
-        label:SetAnchor(TOPRIGHT, container, TOPLEFT, 5, 0)
-    end
-
-    control.data.tooltipText = GetStringFromValue(control.data.tooltip)
-    control:SetMouseEnabled(true)
-    control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-    control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-    return control
-end
-
-local function GetTopPanel(panel)
-    while panel.panel and panel.panel ~= panel do
-        panel = panel.panel
-    end
-    return panel
-end
-
-local function IsSame(objA, objB)
-    if #objA ~= #objB then return false end
-    for i = 1, #objA do
-        if objA[i] ~= objB[i] then return false end
-    end
-    return true
-end
-
-local function RefreshReloadUIButton()
-    lam.requiresReload = false
-
-    for i = 1, #controlsForReload do
-        local reloadControl = controlsForReload[i]
-        if not IsSame(reloadControl.startValue, {reloadControl.data.getFunc()}) then
-            lam.requiresReload = true
-            break
-        end
-    end
-
-    lam.applyButton:SetHidden(not lam.requiresReload)
-end
-
-local function RequestRefreshIfNeeded(control)
-    -- if our parent window wants to refresh controls, then fire the callback
-    local panel = GetTopPanel(control.panel)
-    local panelData = panel.data
-    if panelData.registerForRefresh then
-        cm:FireCallbacks("LAM-RefreshPanel", control)
-    end
-    RefreshReloadUIButton()
-end
-
-local function RegisterForRefreshIfNeeded(control)
-    -- if our parent window wants to refresh controls, then add this to the list
-    local panel = GetTopPanel(control.panel)
-    local panelData = panel.data
-    if panelData.registerForRefresh or panelData.registerForDefaults then
-        tinsert(panel.controlsToRefresh or {}, control) -- prevent errors on custom panels
-    end
-end
-
-local function RegisterForReloadIfNeeded(control)
-    if control.data.requiresReload then
-        tinsert(controlsForReload, control)
-        control.startValue = {control.data.getFunc()}
-    end
-end
-
-local function GetConfirmDialog()
-    if(not ESO_Dialogs[LAM_CONFIRM_DIALOG]) then
-        ESO_Dialogs[LAM_CONFIRM_DIALOG] = {
-            canQueue = true,
-            title = {
-                text = "",
-            },
-            mainText = {
-                text = "",
-            },
-            buttons = {
-                [1] = {
-                    text = SI_DIALOG_CONFIRM,
-                    callback = function(dialog) end,
-                },
-                [2] = {
-                    text = SI_DIALOG_CANCEL,
-                }
-            }
-        }
-    end
-    return ESO_Dialogs[LAM_CONFIRM_DIALOG]
-end
-
-local function ShowConfirmationDialog(title, body, callback)
-    local dialog = GetConfirmDialog()
-    dialog.title.text = title
-    dialog.mainText.text = body
-    dialog.buttons[1].callback = callback
-    ZO_Dialogs_ShowDialog(LAM_CONFIRM_DIALOG)
-end
-
-local function GetDefaultsDialog()
-    if(not ESO_Dialogs[LAM_DEFAULTS_DIALOG]) then
-        ESO_Dialogs[LAM_DEFAULTS_DIALOG] = {
-            canQueue = true,
-            title = {
-                text = SI_INTERFACE_OPTIONS_RESET_TO_DEFAULT_TOOLTIP,
-            },
-            mainText = {
-                text = SI_OPTIONS_RESET_PROMPT,
-            },
-            buttons = {
-                [1] = {
-                    text = SI_OPTIONS_RESET,
-                    callback = function(dialog) end,
-                },
-                [2] = {
-                    text = SI_DIALOG_CANCEL,
-                }
-            }
-        }
-    end
-    return ESO_Dialogs[LAM_DEFAULTS_DIALOG]
-end
-
-local function ShowDefaultsDialog(panel)
-    local dialog = GetDefaultsDialog()
-    dialog.buttons[1].callback = function()
-        panel:ForceDefaults()
-        RefreshReloadUIButton()
-    end
-    ZO_Dialogs_ShowDialog(LAM_DEFAULTS_DIALOG)
-end
-
-local function DiscardChangesOnReloadControls()
-    for i = 1, #controlsForReload do
-        local reloadControl = controlsForReload[i]
-        if not IsSame(reloadControl.startValue, {reloadControl.data.getFunc()}) then
-            reloadControl:UpdateValue(false, unpack(reloadControl.startValue))
-        end
-    end
-    lam.requiresReload = false
-    lam.applyButton:SetHidden(true)
-end
-
-local function StorePanelForReopening()
-    local saveData = ZO_Ingame_SavedVariables["LAM"] or {}
-    saveData.reopenPanel = lam.currentAddonPanel:GetName()
-    ZO_Ingame_SavedVariables["LAM"] = saveData
-end
-
-local function RetrievePanelForReopening()
-    local saveData = ZO_Ingame_SavedVariables["LAM"]
-    if(saveData) then
-        ZO_Ingame_SavedVariables["LAM"] = nil
-        return _G[saveData.reopenPanel]
-    end
-end
-
-local function HandleReloadUIPressed()
-    StorePanelForReopening()
-    ReloadUI()
-end
-
-local function HandleLoadDefaultsPressed()
-    ShowDefaultsDialog(lam.currentAddonPanel)
-end
-
-local function GetReloadDialog()
-    if(not ESO_Dialogs[LAM_RELOAD_DIALOG]) then
-        ESO_Dialogs[LAM_RELOAD_DIALOG] = {
-            canQueue = true,
-            title = {
-                text = util.L["RELOAD_DIALOG_TITLE"],
-            },
-            mainText = {
-                text = util.L["RELOAD_DIALOG_TEXT"],
-            },
-            buttons = {
-                [1] = {
-                    text = util.L["RELOAD_DIALOG_RELOAD_BUTTON"],
-                    callback = function() ReloadUI() end,
-                },
-                [2] = {
-                    text = util.L["RELOAD_DIALOG_DISCARD_BUTTON"],
-                    callback = DiscardChangesOnReloadControls,
-                }
-            },
-            noChoiceCallback = DiscardChangesOnReloadControls,
-        }
-    end
-    return ESO_Dialogs[LAM_CONFIRM_DIALOG]
-end
-
-local function ShowReloadDialogIfNeeded()
-    if lam.requiresReload then
-        local dialog = GetReloadDialog()
-        ZO_Dialogs_ShowDialog(LAM_RELOAD_DIALOG)
-    end
-end
-
-local function UpdateWarning(control)
-    local warning
-    if control.data.warning ~= nil then
-        warning = util.GetStringFromValue(control.data.warning)
-    end
-
-    if control.data.requiresReload then
-        if not warning then
-            warning = string.format("|cff0000%s", util.L["RELOAD_UI_WARNING"])
-        else
-            warning = string.format("%s\n\n|cff0000%s", warning, util.L["RELOAD_UI_WARNING"])
-        end
-    end
-
-    if not warning then
-        control.warning:SetHidden(true)
-    else
-        control.warning.data = {tooltipText = warning}
-        control.warning:SetHidden(false)
-    end
-end
-
-local localization = {
-    en = {
-        PANEL_NAME = "Addons",
-        AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Author: <<X:1>>"
-        VERSION = "Version: <<X:1>>",
-        WEBSITE = "Visit Website",
-        PANEL_INFO_FONT = "$(CHAT_FONT)|14|soft-shadow-thin",
-        RELOAD_UI_WARNING = "Changes to this setting require an UI reload in order to take effect.",
-        RELOAD_DIALOG_TITLE = "UI Reload required",
-        RELOAD_DIALOG_TEXT = "Some changes require an UI reload in order to take effect. Do you want to reload now or discard the changes?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Reload",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Discard",
-    },
-    it = { -- provided by JohnnyKing
-        PANEL_NAME = "Addon",
-        VERSION = "Versione: <<X:1>>",
-        WEBSITE = "Visita il Sitoweb",
-        RELOAD_UI_WARNING = "Cambiare questa impostazione richiede un Ricarica UI al fine che faccia effetto.",
-        RELOAD_DIALOG_TITLE = "Ricarica UI richiesto",
-        RELOAD_DIALOG_TEXT = "Alcune modifiche richiedono un Ricarica UI al fine che facciano effetto. Sei sicuro di voler ricaricare ora o di voler annullare le modifiche?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Ricarica",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Annulla",
-    },
-    fr = { -- provided by Ayantir
-        PANEL_NAME = "Extensions",
-        WEBSITE = "Visiter le site Web",
-        RELOAD_UI_WARNING = "La modification de ce paramètre requiert un rechargement de l'UI pour qu'il soit pris en compte.",
-        RELOAD_DIALOG_TITLE = "Reload UI requis",
-        RELOAD_DIALOG_TEXT = "Certaines modifications requièrent un rechargement de l'UI pour qu'ils soient pris en compte. Souhaitez-vous recharger l'interface maintenant ou annuler les modifications ?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Recharger",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Annuler",
-    },
-    de = { -- provided by sirinsidiator
-        PANEL_NAME = "Erweiterungen",
-        WEBSITE = "Webseite besuchen",
-        RELOAD_UI_WARNING = "Änderungen an dieser Option werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird.",
-        RELOAD_DIALOG_TITLE = "Neuladen benötigt",
-        RELOAD_DIALOG_TEXT = "Einige Änderungen werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird. Wollt Ihr sie jetzt neu laden oder die Änderungen verwerfen?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Neu laden",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Verwerfen",
-    },
-    ru = { -- provided by TERAB1T
-        PANEL_NAME = "Дополнения",
-        VERSION = "Версия: <<X:1>>",
-        WEBSITE = "Посетить сайт",
-        PANEL_INFO_FONT = "RuESO/fonts/Univers57.otf|14|soft-shadow-thin",
-        RELOAD_UI_WARNING = "Для применения этой настройки необходима перезагрузка интерфейса.",
-        RELOAD_DIALOG_TITLE = "Необходима перезагрузка интерфейса",
-        RELOAD_DIALOG_TEXT = "Для применения некоторых изменений необходима перезагрузка интерфейса. Перезагрузить интерфейс сейчас или отменить изменения?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Перезагрузить",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Отменить изменения",
-    },
-    es = { -- provided by Morganlefai, checked by Kwisatz
-        PANEL_NAME = "Configuración",
-        VERSION = "Versión: <<X:1>>",
-        WEBSITE = "Visita la página web",
-        RELOAD_UI_WARNING = "Cambiar este ajuste recargará la interfaz del usuario.",
-        RELOAD_DIALOG_TITLE = "Requiere recargar la interfaz",
-        RELOAD_DIALOG_TEXT = "Algunos cambios requieren recargar la interfaz para poder aplicarse. Quieres aplicar los cambios y recargar la interfaz?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Recargar",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Cancelar",
-    },
-    jp = { -- provided by k0ta0uchi
-        PANEL_NAME = "アドオン設定",
-        WEBSITE = "ウェブサイトを見る",
-    },
-    zh = { -- provided by bssthu
-        PANEL_NAME = "插件",
-        VERSION = "版本: <<X:1>>",
-        WEBSITE = "访问网站",
-        PANEL_INFO_FONT = "EsoZh/fonts/univers57.otf|14|soft-shadow-thin",
-    },
-    pl = { -- provided by EmiruTegryfon
-        PANEL_NAME = "Dodatki",
-        VERSION = "Wersja: <<X:1>>",
-        WEBSITE = "Odwiedź stronę",
-        RELOAD_UI_WARNING = "Zmiany będą widoczne po ponownym załadowaniu UI.",
-        RELOAD_DIALOG_TITLE = "Wymagane przeładowanie UI",
-        RELOAD_DIALOG_TEXT = "Niektóre zmiany wymagają ponownego załadowania UI. Czy chcesz teraz ponownie załadować, czy porzucić zmiany?",
-        RELOAD_DIALOG_RELOAD_BUTTON = "Przeładuj",
-        RELOAD_DIALOG_DISCARD_BUTTON = "Porzuć",
-    },
-}
-
-util.L = ZO_ShallowTableCopy(localization[GetCVar("Language.2")], localization["en"])
-util.GetTooltipText = GetStringFromValue -- deprecated, use util.GetStringFromValue instead
-util.GetStringFromValue = GetStringFromValue
-util.GetDefaultValue = GetDefaultValue
-util.CreateBaseControl = CreateBaseControl
-util.CreateLabelAndContainerControl = CreateLabelAndContainerControl
-util.RequestRefreshIfNeeded = RequestRefreshIfNeeded
-util.RegisterForRefreshIfNeeded = RegisterForRefreshIfNeeded
-util.RegisterForReloadIfNeeded = RegisterForReloadIfNeeded
-util.GetTopPanel = GetTopPanel
-util.ShowConfirmationDialog = ShowConfirmationDialog
-util.UpdateWarning = UpdateWarning
-
-local ADDON_DATA_TYPE = 1
-local RESELECTING_DURING_REBUILD = true
-local USER_REQUESTED_OPEN = true
-
-
---INTERNAL FUNCTION
---scrolls ZO_ScrollList `list` to move the row corresponding to `data`
--- into view (does nothing if there is no such row in the list)
---unlike ZO_ScrollList_ScrollDataIntoView, this function accounts for
--- fading near the list's edges - it avoids the fading area by scrolling
--- a little further than the ZO function
-local function ScrollDataIntoView(list, data)
-    local targetIndex = data.sortIndex
-    if not targetIndex then return end
-
-    local scrollMin, scrollMax = list.scrollbar:GetMinMax()
-    local scrollTop = list.scrollbar:GetValue()
-    local controlHeight = list.uniformControlHeight or list.controlHeight
-    local targetMin = controlHeight * (targetIndex - 1) - 64
-    -- subtracting 64 ain't arbitrary, it's the maximum fading height
-    -- (libraries/zo_templates/scrolltemplates.lua/UpdateScrollFade)
-
-    if targetMin < scrollTop then
-        ZO_ScrollList_ScrollAbsolute(list, zo_max(targetMin, scrollMin))
-    else
-        local listHeight = ZO_ScrollList_GetHeight(list)
-        local targetMax = controlHeight * targetIndex + 64 - listHeight
-
-        if targetMax > scrollTop then
-            ZO_ScrollList_ScrollAbsolute(list, zo_min(targetMax, scrollMax))
-        end
-    end
-end
-
-
---INTERNAL FUNCTION
---constructs a string pattern from the text in `searchEdit` control
--- * metacharacters are escaped, losing their special meaning
--- * whitespace matches anything (including empty substring)
---if there is nothing but whitespace, returns nil
---otherwise returns a filter function, which takes a `data` table argument
--- and returns true iff `data.filterText` matches the pattern
-local function GetSearchFilterFunc(searchEdit)
-    local text = searchEdit:GetText():lower()
-    local pattern = text:match("(%S+.-)%s*$")
-
-    if not pattern then -- nothing but whitespace
-        return nil
-    end
-
-    -- escape metacharacters, e.g. "ESO-Datenbank.de" => "ESO%-Datenbank%.de"
-    pattern = pattern:gsub("[-*+?^$().[%]%%]", "%%%0")
-
-    -- replace whitespace with "match shortest anything"
-    pattern = pattern:gsub("%s+", ".-")
-
-    return function(data)
-        return data.filterText:lower():find(pattern) ~= nil
-    end
-end
-
-
---INTERNAL FUNCTION
---populates `addonList` with entries from `addonsForList`
--- addonList = ZO_ScrollList control
--- filter = [optional] function(data)
-local function PopulateAddonList(addonList, filter)
-    local entryList = ZO_ScrollList_GetDataList(addonList)
-    local numEntries = 0
-    local selectedData = nil
-    local selectionIsFinal = false
-
-    ZO_ScrollList_Clear(addonList)
-
-    for i, data in ipairs(addonsForList) do
-        if not filter or filter(data) then
-            local dataEntry = ZO_ScrollList_CreateDataEntry(ADDON_DATA_TYPE, data)
-            numEntries = numEntries + 1
-            data.sortIndex = numEntries
-            entryList[numEntries] = dataEntry
-            -- select the first panel passing the filter, or the currently
-            -- shown panel, but only if it passes the filter as well
-            if selectedData == nil or data.panel == lam.pendingAddonPanel or data.panel == lam.currentAddonPanel then
-                if not selectionIsFinal then
-                    selectedData = data
-                end
-                if data.panel == lam.pendingAddonPanel then
-                    lam.pendingAddonPanel = nil
-                    selectionIsFinal = true
-                end
-            end
-        else
-            data.sortIndex = nil
-        end
-    end
-
-    ZO_ScrollList_Commit(addonList)
-
-    if selectedData then
-        if selectedData.panel == lam.currentAddonPanel then
-            ZO_ScrollList_SelectData(addonList, selectedData, nil, RESELECTING_DURING_REBUILD)
-        else
-            ZO_ScrollList_SelectData(addonList, selectedData, nil)
-        end
-        ScrollDataIntoView(addonList, selectedData)
-    end
-end
-
-
---METHOD: REGISTER WIDGET--
---each widget has its version checked before loading,
---so we only have the most recent one in memory
---Usage:
--- widgetType = "string"; the type of widget being registered
--- widgetVersion = integer; the widget's version number
-LAMCreateControl = LAMCreateControl or {}
-local lamcc = LAMCreateControl
-
-function lam:RegisterWidget(widgetType, widgetVersion)
-    if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
-        return false
-    else
-        widgets[widgetType] = widgetVersion
-        return true
-    end
-end
-
--- INTERNAL METHOD: hijacks the handlers for the actions in the OptionsWindow layer if not already done
-local function InitKeybindActions()
-    if not lam.keybindsInitialized then
-        lam.keybindsInitialized = true
-        ZO_PreHook(KEYBOARD_OPTIONS, "ApplySettings", function()
-            if lam.currentPanelOpened then
-                if not lam.applyButton:IsHidden() then
-                    HandleReloadUIPressed()
-                end
-                return true
-            end
-        end)
-        ZO_PreHook("ZO_Dialogs_ShowDialog", function(dialogName)
-            if lam.currentPanelOpened and dialogName == "OPTIONS_RESET_TO_DEFAULTS" then
-                if not lam.defaultButton:IsHidden() then
-                    HandleLoadDefaultsPressed()
-                end
-                return true
-            end
-        end)
-    end
-end
-
--- INTERNAL METHOD: fires the LAM-PanelOpened callback if not already done
-local function OpenCurrentPanel()
-    if lam.currentAddonPanel and not lam.currentPanelOpened then
-        lam.currentPanelOpened = true
-        lam.defaultButton:SetHidden(not lam.currentAddonPanel.data.registerForDefaults)
-        cm:FireCallbacks("LAM-PanelOpened", lam.currentAddonPanel)
-    end
-end
-
--- INTERNAL METHOD: fires the LAM-PanelClosed callback if not already done
-local function CloseCurrentPanel()
-    if lam.currentAddonPanel and lam.currentPanelOpened then
-        lam.currentPanelOpened = false
-        cm:FireCallbacks("LAM-PanelClosed", lam.currentAddonPanel)
-    end
-end
-
---METHOD: OPEN TO ADDON PANEL--
---opens to a specific addon's option panel
---Usage:
--- panel = userdata; the panel returned by the :RegisterOptionsPanel method
-local locSettings = GetString(SI_GAME_MENU_SETTINGS)
-function lam:OpenToPanel(panel)
-
-    -- find and select the panel's row in addon list
-
-    local addonList = lam.addonList
-    local selectedData = nil
-
-    for _, addonData in ipairs(addonsForList) do
-        if addonData.panel == panel then
-            selectedData = addonData
-            ScrollDataIntoView(addonList, selectedData)
-            lam.pendingAddonPanel = addonData.panel
-            break
-        end
-    end
-
-    ZO_ScrollList_SelectData(addonList, selectedData)
-    ZO_ScrollList_RefreshVisible(addonList, selectedData)
-
-    local srchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit")
-    srchEdit:Clear()
-
-    -- note that ZO_ScrollList doesn't require `selectedData` to be actually
-    -- present in the list, and that the list will only be populated once LAM
-    -- "Addon Settings" menu entry is selected for the first time
-
-    local function openAddonSettingsMenu()
-        local gameMenu = ZO_GameMenu_InGame.gameMenu
-        local settingsMenu = gameMenu.headerControls[locSettings]
-
-        if settingsMenu then -- an instance of ZO_TreeNode
-            local children = settingsMenu:GetChildren()
-            for i = 1, (children and #children or 0) do
-                local childNode = children[i]
-                local data = childNode:GetData()
-                if data and data.id == lam.panelId then
-                    -- found LAM "Addon Settings" node, yay!
-                    childNode:GetTree():SelectNode(childNode)
-                    break
-                end
-            end
-        end
-    end
-
-    if sm:GetScene("gameMenuInGame"):GetState() == SCENE_SHOWN then
-        openAddonSettingsMenu()
-    else
-        sm:CallWhen("gameMenuInGame", SCENE_SHOWN, openAddonSettingsMenu)
-        sm:Show("gameMenuInGame")
-    end
-end
-
-local TwinOptionsContainer_Index = 0
-local function TwinOptionsContainer(parent, leftWidget, rightWidget)
-    TwinOptionsContainer_Index = TwinOptionsContainer_Index + 1
-    local cParent = parent.scroll or parent
-    local panel = parent.panel or cParent
-    local container = wm:CreateControl("$(parent)TwinContainer" .. tostring(TwinOptionsContainer_Index),
-        cParent, CT_CONTROL)
-    container:SetResizeToFitDescendents(true)
-    container:SetAnchor(select(2, leftWidget:GetAnchor(0) ))
-
-    leftWidget:ClearAnchors()
-    leftWidget:SetAnchor(TOPLEFT, container, TOPLEFT)
-    rightWidget:SetAnchor(TOPLEFT, leftWidget, TOPRIGHT, 5, 0)
-
-    leftWidget:SetWidth( leftWidget:GetWidth() - 2.5 ) -- fixes bad alignment with 'full' controls
-    rightWidget:SetWidth( rightWidget:GetWidth() - 2.5 )
-
-    leftWidget:SetParent(container)
-    rightWidget:SetParent(container)
-
-    container.data = {type = "container"}
-    container.panel = panel
-    return container
-end
-
---INTERNAL FUNCTION
---creates controls when options panel is first shown
---controls anchoring of these controls in the panel
-local function CreateOptionsControls(panel)
-    local addonID = panel:GetName()
-    if(optionsState[addonID] == OPTIONS_CREATED) then
-        return false
-    elseif(optionsState[addonID] == OPTIONS_CREATION_RUNNING) then
-        return true
-    end
-    optionsState[addonID] = OPTIONS_CREATION_RUNNING
-
-    local function CreationFinished()
-        optionsState[addonID] = OPTIONS_CREATED
-        cm:FireCallbacks("LAM-PanelControlsCreated", panel)
-        OpenCurrentPanel()
-    end
-
-    local optionsTable = addonToOptionsMap[addonID]
-    if optionsTable then
-        local function CreateAndAnchorWidget(parent, widgetData, offsetX, offsetY, anchorTarget, wasHalf)
-            local widget
-            local status, err = pcall(function() widget = LAMCreateControl[widgetData.type](parent, widgetData) end)
-            if not status then
-                return err or true, offsetY, anchorTarget, wasHalf
-            else
-                local isHalf = (widgetData.width == "half")
-                if not anchorTarget then -- the first widget in a panel is just placed in the top left corner
-                    widget:SetAnchor(TOPLEFT)
-                    anchorTarget = widget
-                elseif wasHalf and isHalf then -- when the previous widget was only half width and this one is too, we place it on the right side
-                    widget.lineControl = anchorTarget
-                    isHalf = false
-                    offsetY = 0
-                    anchorTarget = TwinOptionsContainer(parent, anchorTarget, widget)
-                else -- otherwise we just put it below the previous one normally
-                    widget:SetAnchor(TOPLEFT, anchorTarget, BOTTOMLEFT, 0, 15)
-                    offsetY = 0
-                    anchorTarget = widget
-                end
-                return false, offsetY, anchorTarget, isHalf
-            end
-        end
-
-        local THROTTLE_TIMEOUT, THROTTLE_COUNT = 10, 20
-        local fifo = {}
-        local anchorOffset, lastAddedControl, wasHalf
-        local CreateWidgetsInPanel, err
-
-        local function PrepareForNextPanel()
-            anchorOffset, lastAddedControl, wasHalf = 0, nil, false
-        end
-
-        local function SetupCreationCalls(parent, widgetDataTable)
-            fifo[#fifo + 1] = PrepareForNextPanel
-            local count = #widgetDataTable
-            for i = 1, count, THROTTLE_COUNT do
-                fifo[#fifo + 1] = function()
-                    CreateWidgetsInPanel(parent, widgetDataTable, i, zo_min(i + THROTTLE_COUNT - 1, count))
-                end
-            end
-            return count ~= NonContiguousCount(widgetDataTable)
-        end
-
-        CreateWidgetsInPanel = function(parent, widgetDataTable, startIndex, endIndex)
-            for i=startIndex,endIndex do
-                local widgetData = widgetDataTable[i]
-                if not widgetData then
-                    PrintLater("Skipped creation of missing entry in the settings menu of " .. addonID .. ".")
-                else
-                    local widgetType = widgetData.type
-                    local offsetX = 0
-                    local isSubmenu = (widgetType == "submenu")
-                    if isSubmenu then
-                        wasHalf = false
-                        offsetX = 5
-                    end
-
-                    err, anchorOffset, lastAddedControl, wasHalf = CreateAndAnchorWidget(parent, widgetData, offsetX, anchorOffset, lastAddedControl, wasHalf)
-                    if err then
-                        PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, GetStringFromValue(widgetData.name or "unnamed"), addonID))
-                    end
-
-                    if isSubmenu then
-                        if SetupCreationCalls(lastAddedControl, widgetData.controls) then
-                            PrintLater(("The sub menu '%s' of %s is missing some entries."):format(GetStringFromValue(widgetData.name or "unnamed"), addonID))
-                        end
-                    end
-                end
-            end
-        end
-
-        local function DoCreateSettings()
-            if #fifo > 0 then
-                local nextCall = table.remove(fifo, 1)
-                nextCall()
-                if(nextCall == PrepareForNextPanel) then
-                    DoCreateSettings()
-                else
-                    zo_callLater(DoCreateSettings, THROTTLE_TIMEOUT)
-                end
-            else
-                CreationFinished()
-            end
-        end
-
-        if SetupCreationCalls(panel, optionsTable) then
-            PrintLater(("The settings menu of %s is missing some entries."):format(addonID))
-        end
-        DoCreateSettings()
-    else
-        CreationFinished()
-    end
-
-    return true
-end
-
---INTERNAL FUNCTION
---handles switching between panels
-local function ToggleAddonPanels(panel) --called in OnShow of newly shown panel
-    local currentlySelected = lam.currentAddonPanel
-    if currentlySelected and currentlySelected ~= panel then
-        currentlySelected:SetHidden(true)
-        CloseCurrentPanel()
-    end
-    lam.currentAddonPanel = panel
-
-    -- refresh visible rows to reflect panel IsHidden status
-    ZO_ScrollList_RefreshVisible(lam.addonList)
-
-    if not CreateOptionsControls(panel) then
-        OpenCurrentPanel()
-    end
-
-    cm:FireCallbacks("LAM-RefreshPanel", panel)
-end
-
-local CheckSafetyAndInitialize
-
---METHOD: REGISTER ADDON PANEL
---registers your addon with LibAddonMenu and creates a panel
---Usage:
--- addonID = "string"; unique ID which will be the global name of your panel
--- panelData = table; data object for your panel - see controls\panel.lua
-function lam:RegisterAddonPanel(addonID, panelData)
-    CheckSafetyAndInitialize(addonID)
-    local container = lam:GetAddonPanelContainer()
-    local panel = lamcc.panel(container, panelData, addonID) --addonID==global name of panel
-    panel:SetHidden(true)
-    panel:SetAnchorFill(container)
-    panel:SetHandler("OnShow", ToggleAddonPanels)
-
-    local function stripMarkup(str)
-        return str:gsub("|[Cc]%x%x%x%x%x%x", ""):gsub("|[Rr]", "")
-    end
-
-    local filterParts = {panelData.name, nil, nil}
-    -- append keywords and author separately, the may be nil
-    filterParts[#filterParts + 1] = panelData.keywords
-    filterParts[#filterParts + 1] = panelData.author
-
-    local addonData = {
-        panel = panel,
-        name = stripMarkup(panelData.name),
-        filterText = stripMarkup(tconcat(filterParts, "\t")):lower(),
-    }
-
-    tinsert(addonsForList, addonData)
-
-    if panelData.slashCommand then
-        SLASH_COMMANDS[panelData.slashCommand] = function()
-            lam:OpenToPanel(panel)
-        end
-    end
-
-    return panel --return for authors creating options manually
-end
-
-
---METHOD: REGISTER OPTION CONTROLS
---registers the options you want shown for your addon
---these are stored in a table where each key-value pair is the order
---of the options in the panel and the data for that control, respectively
---see exampleoptions.lua for an example
---see controls\<widget>.lua for each widget type
---Usage:
--- addonID = "string"; the same string passed to :RegisterAddonPanel
--- optionsTable = table; the table containing all of the options controls and their data
-function lam:RegisterOptionControls(addonID, optionsTable) --optionsTable = {sliderData, buttonData, etc}
-    addonToOptionsMap[addonID] = optionsTable
-end
-
---INTERNAL FUNCTION
---creates LAM's Addon Settings entry in ZO_GameMenu
-local function CreateAddonSettingsMenuEntry()
-    local panelData = {
-        id = KEYBOARD_OPTIONS.currentPanelId,
-        name = util.L["PANEL_NAME"],
-    }
-
-    KEYBOARD_OPTIONS.currentPanelId = panelData.id + 1
-    KEYBOARD_OPTIONS.panelNames[panelData.id] = panelData.name
-
-    lam.panelId = panelData.id
-
-    local addonListSorted = false
-
-    function panelData.callback()
-        sm:AddFragment(lam:GetAddonSettingsFragment())
-        KEYBOARD_OPTIONS:ChangePanels(lam.panelId)
-
-        local title = LAMAddonSettingsWindow:GetNamedChild("Title")
-        title:SetText(panelData.name)
-
-        if not addonListSorted and #addonsForList > 0 then
-            local searchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit")
-            --we're about to show our list for the first time - let's sort it
-            table.sort(addonsForList, function(a, b) return a.name < b.name end)
-            PopulateAddonList(lam.addonList, GetSearchFilterFunc(searchEdit))
-            addonListSorted = true
-        end
-    end
-
-    function panelData.unselectedCallback()
-        sm:RemoveFragment(lam:GetAddonSettingsFragment())
-        if SetCameraOptionsPreviewModeEnabled then -- available since API version 100011
-            SetCameraOptionsPreviewModeEnabled(false)
-        end
-    end
-
-    ZO_GameMenu_AddSettingPanel(panelData)
-end
-
-
---INTERNAL FUNCTION
---creates the left-hand menu in LAM's window
-local function CreateAddonList(name, parent)
-    local addonList = wm:CreateControlFromVirtual(name, parent, "ZO_ScrollList")
-
-    local function addonListRow_OnMouseDown(control, button)
-        if button == 1 then
-            local data = ZO_ScrollList_GetData(control)
-            ZO_ScrollList_SelectData(addonList, data, control)
-        end
-    end
-
-    local function addonListRow_OnMouseEnter(control)
-        ZO_ScrollList_MouseEnter(addonList, control)
-    end
-
-    local function addonListRow_OnMouseExit(control)
-        ZO_ScrollList_MouseExit(addonList, control)
-    end
-
-    local function addonListRow_Select(previouslySelectedData, selectedData, reselectingDuringRebuild)
-        if not reselectingDuringRebuild then
-            if previouslySelectedData then
-                previouslySelectedData.panel:SetHidden(true)
-            end
-            if selectedData then
-                selectedData.panel:SetHidden(false)
-                PlaySound(SOUNDS.MENU_SUBCATEGORY_SELECTION)
-            end
-        end
-    end
-
-    local function addonListRow_Setup(control, data)
-        control:SetText(data.name)
-        control:SetSelected(not data.panel:IsHidden())
-    end
-
-    ZO_ScrollList_AddDataType(addonList, ADDON_DATA_TYPE, "ZO_SelectableLabel", 28, addonListRow_Setup)
-    -- I don't know how to make highlights clear properly; they often
-    -- get stuck and after a while the list is full of highlighted rows
-    --ZO_ScrollList_EnableHighlight(addonList, "ZO_ThinListHighlight")
-    ZO_ScrollList_EnableSelection(addonList, "ZO_ThinListHighlight", addonListRow_Select)
-
-    local addonDataType = ZO_ScrollList_GetDataTypeTable(addonList, ADDON_DATA_TYPE)
-    local addonListRow_CreateRaw = addonDataType.pool.m_Factory
-
-    local function addonListRow_Create(pool)
-        local control = addonListRow_CreateRaw(pool)
-        control:SetHandler("OnMouseDown", addonListRow_OnMouseDown)
-        --control:SetHandler("OnMouseEnter", addonListRow_OnMouseEnter)
-        --control:SetHandler("OnMouseExit", addonListRow_OnMouseExit)
-        control:SetHeight(28)
-        control:SetFont("ZoFontHeader")
-        control:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
-        control:SetVerticalAlignment(TEXT_ALIGN_CENTER)
-        control:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-        return control
-    end
-
-    addonDataType.pool.m_Factory = addonListRow_Create
-
-    return addonList
-end
-
-
---INTERNAL FUNCTION
-local function CreateSearchFilterBox(name, parent)
-    local boxControl = wm:CreateControl(name, parent, CT_CONTROL)
-
-    local srchButton =  wm:CreateControl("$(parent)Button", boxControl, CT_BUTTON)
-    srchButton:SetDimensions(32, 32)
-    srchButton:SetAnchor(LEFT, nil, LEFT, 2, 0)
-    srchButton:SetNormalTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_up.dds")
-    srchButton:SetPressedTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_down.dds")
-    srchButton:SetMouseOverTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_over.dds")
-
-    local srchEdit = wm:CreateControlFromVirtual("$(parent)Edit", boxControl, "ZO_DefaultEdit")
-    srchEdit:SetAnchor(LEFT, srchButton, RIGHT, 4, 1)
-    srchEdit:SetAnchor(RIGHT, nil, RIGHT, -4, 1)
-    srchEdit:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
-
-    local srchBg = wm:CreateControl("$(parent)Bg", boxControl, CT_BACKDROP)
-    srchBg:SetAnchorFill()
-    srchBg:SetAlpha(0)
-    srchBg:SetCenterColor(0, 0, 0, 0.5)
-    srchBg:SetEdgeColor(ZO_DISABLED_TEXT:UnpackRGBA())
-    srchBg:SetEdgeTexture("", 1, 1, 0, 0)
-
-    -- search backdrop should appear whenever you hover over either
-    -- the magnifying glass button or the edit field (which is only
-    -- visible when it contains some text), and also while the edit
-    -- field has keyboard focus
-
-    local srchActive = false
-    local srchHover = false
-
-    local function srchBgUpdateAlpha()
-        if srchActive or srchEdit:HasFocus() then
-            srchBg:SetAlpha(srchHover and 0.8 or 0.6)
-        else
-            srchBg:SetAlpha(srchHover and 0.6 or 0.0)
-        end
-    end
-
-    local function srchMouseEnter(control)
-        srchHover = true
-        srchBgUpdateAlpha()
-    end
-
-    local function srchMouseExit(control)
-        srchHover = false
-        srchBgUpdateAlpha()
-    end
-
-    boxControl:SetMouseEnabled(true)
-    boxControl:SetHitInsets(1, 1, -1, -1)
-    boxControl:SetHandler("OnMouseEnter", srchMouseEnter)
-    boxControl:SetHandler("OnMouseExit", srchMouseExit)
-
-    srchButton:SetHandler("OnMouseEnter", srchMouseEnter)
-    srchButton:SetHandler("OnMouseExit", srchMouseExit)
-
-    local focusLostTime = 0
-
-    srchButton:SetHandler("OnClicked", function(self)
-        srchEdit:Clear()
-        if GetFrameTimeMilliseconds() - focusLostTime < 100 then
-            -- re-focus the edit box if it lost focus due to this
-            -- button click (note that this handler may run a few
-            -- frames later)
-            srchEdit:TakeFocus()
-        end
-    end)
-
-    srchEdit:SetHandler("OnMouseEnter", srchMouseEnter)
-    srchEdit:SetHandler("OnMouseExit", srchMouseExit)
-    srchEdit:SetHandler("OnFocusGained", srchBgUpdateAlpha)
-
-    srchEdit:SetHandler("OnFocusLost", function()
-        focusLostTime = GetFrameTimeMilliseconds()
-        srchBgUpdateAlpha()
-    end)
-
-    srchEdit:SetHandler("OnEscape", function(self)
-        self:Clear()
-        self:LoseFocus()
-    end)
-
-    srchEdit:SetHandler("OnTextChanged", function(self)
-        local filterFunc = GetSearchFilterFunc(self)
-        if filterFunc then
-            srchActive = true
-            srchBg:SetEdgeColor(ZO_SECOND_CONTRAST_TEXT:UnpackRGBA())
-            srchButton:SetState(BSTATE_PRESSED)
-        else
-            srchActive = false
-            srchBg:SetEdgeColor(ZO_DISABLED_TEXT:UnpackRGBA())
-            srchButton:SetState(BSTATE_NORMAL)
-        end
-        srchBgUpdateAlpha()
-        PopulateAddonList(lam.addonList, filterFunc)
-        PlaySound(SOUNDS.SPINNER_DOWN)
-    end)
-
-    return boxControl
-end
-
-
---INTERNAL FUNCTION
---creates LAM's Addon Settings top-level window
-local function CreateAddonSettingsWindow()
-    local tlw = wm:CreateTopLevelWindow("LAMAddonSettingsWindow")
-    tlw:SetHidden(true)
-    tlw:SetDimensions(1010, 914) -- same height as ZO_OptionsWindow
-
-    ZO_ReanchorControlForLeftSidePanel(tlw)
-
-    -- create black background for the window (mimic ZO_RightFootPrintBackground)
-
-    local bgLeft = wm:CreateControl("$(parent)BackgroundLeft", tlw, CT_TEXTURE)
-    bgLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_left.dds")
-    bgLeft:SetDimensions(1024, 1024)
-    bgLeft:SetAnchor(TOPLEFT, nil, TOPLEFT)
-    bgLeft:SetDrawLayer(DL_BACKGROUND)
-    bgLeft:SetExcludeFromResizeToFitExtents(true)
-
-    local bgRight = wm:CreateControl("$(parent)BackgroundRight", tlw, CT_TEXTURE)
-    bgRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_right.dds")
-    bgRight:SetDimensions(64, 1024)
-    bgRight:SetAnchor(TOPLEFT, bgLeft, TOPRIGHT)
-    bgRight:SetDrawLayer(DL_BACKGROUND)
-    bgRight:SetExcludeFromResizeToFitExtents(true)
-
-    -- create gray background for addon list (mimic ZO_TreeUnderlay)
-
-    local underlayLeft = wm:CreateControl("$(parent)UnderlayLeft", tlw, CT_TEXTURE)
-    underlayLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_left.dds")
-    underlayLeft:SetDimensions(256, 1024)
-    underlayLeft:SetAnchor(TOPLEFT, bgLeft, TOPLEFT)
-    underlayLeft:SetDrawLayer(DL_BACKGROUND)
-    underlayLeft:SetExcludeFromResizeToFitExtents(true)
-
-    local underlayRight = wm:CreateControl("$(parent)UnderlayRight", tlw, CT_TEXTURE)
-    underlayRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_right.dds")
-    underlayRight:SetDimensions(128, 1024)
-    underlayRight:SetAnchor(TOPLEFT, underlayLeft, TOPRIGHT)
-    underlayRight:SetDrawLayer(DL_BACKGROUND)
-    underlayRight:SetExcludeFromResizeToFitExtents(true)
-
-    -- create title bar (mimic ZO_OptionsWindow)
-
-    local title = wm:CreateControl("$(parent)Title", tlw, CT_LABEL)
-    title:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 70)
-    title:SetFont("ZoFontWinH1")
-    title:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE)
-
-    local divider = wm:CreateControlFromVirtual("$(parent)Divider", tlw, "ZO_Options_Divider")
-    divider:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 108)
-
-    -- create search filter box
-
-    local srchBox = CreateSearchFilterBox("$(parent)SearchFilter", tlw)
-    srchBox:SetAnchor(TOPLEFT, nil, TOPLEFT, 63, 120)
-    srchBox:SetDimensions(260, 30)
-
-    -- create scrollable addon list
-
-    local addonList = CreateAddonList("$(parent)AddonList", tlw)
-    addonList:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 160)
-    addonList:SetDimensions(285, 665)
-
-    lam.addonList = addonList -- for easy access from elsewhere
-
-    -- create container for option panels
-
-    local panelContainer = wm:CreateControl("$(parent)PanelContainer", tlw, CT_CONTROL)
-    panelContainer:SetAnchor(TOPLEFT, nil, TOPLEFT, 365, 120)
-    panelContainer:SetDimensions(645, 675)
-
-    local defaultButton = wm:CreateControlFromVirtual("$(parent)ResetToDefaultButton", tlw, "ZO_DialogButton")
-    ZO_KeybindButtonTemplate_Setup(defaultButton, "OPTIONS_LOAD_DEFAULTS", HandleLoadDefaultsPressed, GetString(SI_OPTIONS_DEFAULTS))
-    defaultButton:SetAnchor(TOPLEFT, panelContainer, BOTTOMLEFT, 0, 2)
-    lam.defaultButton = defaultButton
-
-    local applyButton = wm:CreateControlFromVirtual("$(parent)ApplyButton", tlw, "ZO_DialogButton")
-    ZO_KeybindButtonTemplate_Setup(applyButton, "OPTIONS_APPLY_CHANGES", HandleReloadUIPressed, GetString(SI_ADDON_MANAGER_RELOAD))
-    applyButton:SetAnchor(TOPRIGHT, panelContainer, BOTTOMRIGHT, 0, 2)
-    applyButton:SetHidden(true)
-    lam.applyButton = applyButton
-
-    return tlw
-end
-
-
---INITIALIZING
-local safeToInitialize = false
-local hasInitialized = false
-
-local eventHandle = table.concat({MAJOR, MINOR}, "r")
-local function OnLoad(_, addonName)
-    -- wait for the first loaded event
-    em:UnregisterForEvent(eventHandle, EVENT_ADD_ON_LOADED)
-    safeToInitialize = true
-end
-em:RegisterForEvent(eventHandle, EVENT_ADD_ON_LOADED, OnLoad)
-
-local function OnActivated(_, initial)
-    em:UnregisterForEvent(eventHandle, EVENT_PLAYER_ACTIVATED)
-    FlushMessages()
-
-    local reopenPanel = RetrievePanelForReopening()
-    if not initial and reopenPanel then
-        lam:OpenToPanel(reopenPanel)
-    end
-end
-em:RegisterForEvent(eventHandle, EVENT_PLAYER_ACTIVATED, OnActivated)
-
-function CheckSafetyAndInitialize(addonID)
-    if not safeToInitialize then
-        local msg = string.format("The panel with id '%s' was registered before addon loading has completed. This might break the AddOn Settings menu.", addonID)
-        PrintLater(msg)
-    end
-    if not hasInitialized then
-        hasInitialized = true
-    end
-end
-
-
---TODO documentation
-function lam:GetAddonPanelContainer()
-    local fragment = lam:GetAddonSettingsFragment()
-    local window = fragment:GetControl()
-    return window:GetNamedChild("PanelContainer")
-end
-
-
---TODO documentation
-function lam:GetAddonSettingsFragment()
-    assert(hasInitialized or safeToInitialize)
-    if not LAMAddonSettingsFragment then
-        local window = CreateAddonSettingsWindow()
-        LAMAddonSettingsFragment = ZO_FadeSceneFragment:New(window, true, 100)
-        LAMAddonSettingsFragment:RegisterCallback("StateChange", function(oldState, newState)
-            if(newState == SCENE_FRAGMENT_SHOWN) then
-                InitKeybindActions()
-                PushActionLayerByName("OptionsWindow")
-                OpenCurrentPanel()
-            elseif(newState == SCENE_FRAGMENT_HIDDEN) then
-                CloseCurrentPanel()
-                RemoveActionLayerByName("OptionsWindow")
-                ShowReloadDialogIfNeeded()
-            end
-        end)
-        CreateAddonSettingsMenuEntry()
-    end
-    return LAMAddonSettingsFragment
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/button.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/button.lua
deleted file mode 100644
index 82b5032..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/button.lua
+++ /dev/null
@@ -1,91 +0,0 @@
---[[buttonData = {
-    type = "button",
-    name = "My Button", -- string id or function returning a string
-    func = function() end,
-    tooltip = "Button's tooltip text.", -- string id or function returning a string (optional)
-    width = "full", --or "half" (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    icon = "icon\\path.dds", --(optional)
-    isDangerous = false, -- boolean, if set to true, the button text will be red and a confirmation dialog with the button label and warning text will show on click before the callback is executed (optional)
-    warning = "Will need to reload the UI.", --(optional)
-    reference = "MyAddonButton", -- unique global reference to control (optional)
-} ]]
-
-local widgetVersion = 11
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("button", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local function UpdateDisabled(control)
-    local disable = control.data.disabled
-    if type(disable) == "function" then
-        disable = disable()
-    end
-    control.button:SetEnabled(not disable)
-end
-
---controlName is optional
-local MIN_HEIGHT = 28 -- default_button height
-local HALF_WIDTH_LINE_SPACING = 2
-function LAMCreateControl.button(parent, buttonData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, buttonData, controlName)
-    control:SetMouseEnabled(true)
-
-    local width = control:GetWidth()
-    if control.isHalfWidth then
-        control:SetDimensions(width / 2, MIN_HEIGHT * 2 + HALF_WIDTH_LINE_SPACING)
-    else
-        control:SetDimensions(width, MIN_HEIGHT)
-    end
-
-    if buttonData.icon then
-        control.button = wm:CreateControl(nil, control, CT_BUTTON)
-        control.button:SetDimensions(26, 26)
-        control.button:SetNormalTexture(buttonData.icon)
-        control.button:SetPressedOffset(2, 2)
-    else
-        --control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton")
-        control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton")
-        control.button:SetWidth(width / 3)
-        control.button:SetText(LAM.util.GetStringFromValue(buttonData.name))
-        if buttonData.isDangerous then control.button:SetNormalFontColor(ZO_ERROR_COLOR:UnpackRGBA()) end
-    end
-    local button = control.button
-    button:SetAnchor(control.isHalfWidth and CENTER or RIGHT)
-    button:SetClickSound("Click")
-    button.data = {tooltipText = LAM.util.GetStringFromValue(buttonData.tooltip)}
-    button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-    button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-    button:SetHandler("OnClicked", function(...)
-        local args = {...}
-        local function callback()
-            buttonData.func(unpack(args))
-            LAM.util.RequestRefreshIfNeeded(control)
-        end
-
-        if(buttonData.isDangerous) then
-            local title = LAM.util.GetStringFromValue(buttonData.name)
-            local body = LAM.util.GetStringFromValue(buttonData.warning)
-            LAM.util.ShowConfirmationDialog(title, body, callback)
-        else
-            callback()
-        end
-    end)
-
-    if buttonData.warning ~= nil then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    if buttonData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/checkbox.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/checkbox.lua
deleted file mode 100644
index 6696dd7..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/checkbox.lua
+++ /dev/null
@@ -1,142 +0,0 @@
---[[checkboxData = {
-    type = "checkbox",
-    name = "My Checkbox", -- or string id or function returning a string
-    getFunc = function() return db.var end,
-    setFunc = function(value) db.var = value doStuff() end,
-    tooltip = "Checkbox's tooltip text.", -- or string id or function returning a string (optional)
-    width = "full", -- or "half" (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = defaults.var, -- a boolean or function that returns a boolean (optional)
-    reference = "MyAddonCheckbox", -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 14
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("checkbox", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
---label
-local enabledColor = ZO_DEFAULT_ENABLED_COLOR
-local enabledHLcolor = ZO_HIGHLIGHT_TEXT
-local disabledColor = ZO_DEFAULT_DISABLED_COLOR
-local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR
---checkbox
-local checkboxColor = ZO_NORMAL_TEXT
-local checkboxHLcolor = ZO_HIGHLIGHT_TEXT
-
-
-local function UpdateDisabled(control)
-    local disable
-    if type(control.data.disabled) == "function" then
-        disable = control.data.disabled()
-    else
-        disable = control.data.disabled
-    end
-
-    control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA())
-    control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA())
-    --control:SetMouseEnabled(not disable)
-    --control:SetMouseEnabled(true)
-
-    control.isDisabled = disable
-end
-
-local function ToggleCheckbox(control)
-    if control.value then
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-        control.checkbox:SetText(control.checkedText)
-    else
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-        control.checkbox:SetText(control.uncheckedText)
-    end
-end
-
-local function UpdateValue(control, forceDefault, value)
-    if forceDefault then --if we are forcing defaults
-        value = LAM.util.GetDefaultValue(control.data.default)
-        control.data.setFunc(value)
-    elseif value ~= nil then --our value could be false
-        control.data.setFunc(value)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        value = control.data.getFunc()
-    end
-    control.value = value
-
-    ToggleCheckbox(control)
-end
-
-local function OnMouseEnter(control)
-    ZO_Options_OnMouseEnter(control)
-
-    if control.isDisabled then return end
-
-    local label = control.label
-    if control.value then
-        label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
-    else
-        label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-    end
-    control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
-end
-
-local function OnMouseExit(control)
-    ZO_Options_OnMouseExit(control)
-
-    if control.isDisabled then return end
-
-    local label = control.label
-    if control.value then
-        label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    else
-        label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-    end
-    control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
-end
-
---controlName is optional
-function LAMCreateControl.checkbox(parent, checkboxData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, checkboxData, controlName)
-    control:SetHandler("OnMouseEnter", OnMouseEnter)
-    control:SetHandler("OnMouseExit", OnMouseExit)
-    control:SetHandler("OnMouseUp", function(control)
-        if control.isDisabled then return end
-        PlaySound(SOUNDS.DEFAULT_CLICK)
-        control.value = not control.value
-        control:UpdateValue(false, control.value)
-    end)
-
-    control.checkbox = wm:CreateControl(nil, control.container, CT_LABEL)
-    local checkbox = control.checkbox
-    checkbox:SetAnchor(LEFT, control.container, LEFT, 0, 0)
-    checkbox:SetFont("ZoFontGameBold")
-    checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
-    control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper()
-    control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper()
-
-    if checkboxData.warning ~= nil or checkboxData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.data.tooltipText = LAM.util.GetStringFromValue(checkboxData.tooltip)
-
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-    if checkboxData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/colorpicker.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/colorpicker.lua
deleted file mode 100644
index a57aab0..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/colorpicker.lua
+++ /dev/null
@@ -1,106 +0,0 @@
---[[colorpickerData = {
-    type = "colorpicker",
-    name = "My Color Picker", -- or string id or function returning a string
-    getFunc = function() return db.r, db.g, db.b, db.a end, --(alpha is optional)
-    setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end, --(alpha is optional)
-    tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
-    width = "full", --or "half" (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a}, --(optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a]) or a function that returns the color
-    reference = "MyAddonColorpicker" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 13
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local function UpdateDisabled(control)
-    local disable
-    if type(control.data.disabled) == "function" then
-        disable = control.data.disabled()
-    else
-        disable = control.data.disabled
-    end
-
-    if disable then
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-    else
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    end
-
-    control.isDisabled = disable
-end
-
-local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA)
-    if forceDefault then --if we are forcing defaults
-        local color = LAM.util.GetDefaultValue(control.data.default)
-        valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a
-        control.data.setFunc(valueR, valueG, valueB, valueA)
-    elseif valueR and valueG and valueB then
-        control.data.setFunc(valueR, valueG, valueB, valueA or 1)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        valueR, valueG, valueB, valueA = control.data.getFunc()
-    end
-
-    control.thumb:SetColor(valueR, valueG, valueB, valueA or 1)
-end
-
-function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, colorpickerData, controlName)
-
-    control.color = control.container
-    local color = control.color
-
-    control.thumb = wm:CreateControl(nil, color, CT_TEXTURE)
-    local thumb = control.thumb
-    thumb:SetDimensions(36, 18)
-    thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
-
-    color.border = wm:CreateControl(nil, color, CT_TEXTURE)
-    local border = color.border
-    border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds")
-    border:SetTextureCoords(0, .625, 0, .8125)
-    border:SetDimensions(40, 22)
-    border:SetAnchor(CENTER, thumb, CENTER, 0, 0)
-
-    local function ColorPickerCallback(r, g, b, a)
-        control:UpdateValue(false, r, g, b, a)
-    end
-
-    control:SetHandler("OnMouseUp", function(self, btn, upInside)
-        if self.isDisabled then return end
-
-        if upInside then
-            local r, g, b, a = colorpickerData.getFunc()
-            COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, LAM.util.GetStringFromValue(colorpickerData.name))
-        end
-    end)
-
-    if colorpickerData.warning ~= nil or colorpickerData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.data.tooltipText = LAM.util.GetStringFromValue(colorpickerData.tooltip)
-
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-    if colorpickerData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/custom.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/custom.lua
deleted file mode 100644
index 40a7c42..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/custom.lua
+++ /dev/null
@@ -1,35 +0,0 @@
---[[customData = {
-    type = "custom",
-    reference = "MyAddonCustomControl", --(optional) unique name for your control to use as reference
-    refreshFunc = function(customControl) end, --(optional) function to call when panel/controls refresh
-    width = "full", --or "half" (optional)
-} ]]
-
-local widgetVersion = 7
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("custom", widgetVersion) then return end
-
-local function UpdateValue(control)
-    if control.data.refreshFunc then
-        control.data.refreshFunc(control)
-    end
-end
-
-local MIN_HEIGHT = 26
-function LAMCreateControl.custom(parent, customData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, customData, controlName)
-    local width = control:GetWidth()
-    control:SetResizeToFitDescendents(true)
-
-    if control.isHalfWidth then --note these restrictions
-        control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
-    else
-        control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
-    end
-
-    control.UpdateValue = UpdateValue
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/description.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/description.lua
deleted file mode 100644
index da207a0..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/description.lua
+++ /dev/null
@@ -1,60 +0,0 @@
---[[descriptionData = {
-    type = "description",
-    text = "My description text to display.", -- or string id or function returning a string
-    title = "My Title", -- or string id or function returning a string (optional)
-    width = "full", --or "half" (optional)
-    reference = "MyAddonDescription" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 8
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("description", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local function UpdateValue(control)
-    if control.title then
-        control.title:SetText(LAM.util.GetStringFromValue(control.data.title))
-    end
-    control.desc:SetText(LAM.util.GetStringFromValue(control.data.text))
-end
-
-function LAMCreateControl.description(parent, descriptionData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, descriptionData, controlName)
-    local isHalfWidth = control.isHalfWidth
-    local width = control:GetWidth()
-    control:SetResizeToFitDescendents(true)
-
-    if isHalfWidth then
-        control:SetDimensionConstraints(width / 2, 0, width / 2, 0)
-    else
-        control:SetDimensionConstraints(width, 0, width, 0)
-    end
-
-    control.desc = wm:CreateControl(nil, control, CT_LABEL)
-    local desc = control.desc
-    desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
-    desc:SetFont("ZoFontGame")
-    desc:SetText(LAM.util.GetStringFromValue(descriptionData.text))
-    desc:SetWidth(isHalfWidth and width / 2 or width)
-
-    if descriptionData.title then
-        control.title = wm:CreateControl(nil, control, CT_LABEL)
-        local title = control.title
-        title:SetWidth(isHalfWidth and width / 2 or width)
-        title:SetAnchor(TOPLEFT, control, TOPLEFT)
-        title:SetFont("ZoFontWinH4")
-        title:SetText(LAM.util.GetStringFromValue(descriptionData.title))
-        desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT)
-    else
-        desc:SetAnchor(TOPLEFT)
-    end
-
-    control.UpdateValue = UpdateValue
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-
-    return control
-
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/desktop.ini b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/desktop.ini
deleted file mode 100644
index df8fdc8..0000000
Binary files a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/desktop.ini and /dev/null differ
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/divider.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/divider.lua
deleted file mode 100644
index 8089539..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/divider.lua
+++ /dev/null
@@ -1,45 +0,0 @@
---[[dividerData = {
-    type = "divider",
-    width = "full", --or "half" (optional)
-    height = 10, (optional)
-    alpha = 0.25, (optional)
-    reference = "MyAddonDivider" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 2
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("divider", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local MIN_HEIGHT = 10
-local MAX_HEIGHT = 50
-local MIN_ALPHA = 0
-local MAX_ALPHA = 1
-local DEFAULT_ALPHA = 0.25
-
-local function GetValueInRange(value, min, max, default)
-    if not value or type(value) ~= "number" then
-        return default
-    end
-    return math.min(math.max(min, value), max)
-end
-
-function LAMCreateControl.divider(parent, dividerData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, dividerData, controlName)
-    local isHalfWidth = control.isHalfWidth
-    local width = control:GetWidth()
-    local height = GetValueInRange(dividerData.height, MIN_HEIGHT, MAX_HEIGHT, MIN_HEIGHT)
-    local alpha = GetValueInRange(dividerData.alpha, MIN_ALPHA, MAX_ALPHA, DEFAULT_ALPHA)
-
-    control:SetDimensions(isHalfWidth and width / 2 or width, height)
-
-    control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
-    local divider = control.divider
-    divider:SetWidth(isHalfWidth and width / 2 or width)
-    divider:SetAnchor(TOPLEFT)
-    divider:SetAlpha(alpha)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/dropdown.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/dropdown.lua
deleted file mode 100644
index 70e23bb..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/dropdown.lua
+++ /dev/null
@@ -1,387 +0,0 @@
---[[dropdownData = {
-    type = "dropdown",
-    name = "My Dropdown", -- or string id or function returning a string
-    choices = {"table", "of", "choices"},
-    choicesValues = {"foo", 2, "three"}, -- if specified, these values will get passed to setFunc instead (optional)
-    getFunc = function() return db.var end,
-    setFunc = function(var) db.var = var doStuff() end,
-    tooltip = "Dropdown's tooltip text.", -- or string id or function returning a string (optional)
-    choicesTooltips = {"tooltip 1", "tooltip 2", "tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
-    sort = "name-up", --or "name-down", "numeric-up", "numeric-down", "value-up", "value-down", "numericvalue-up", "numericvalue-down" (optional) - if not provided, list will not be sorted
-    width = "full", --or "half" (optional)
-    scrollable = true, -- boolean or number, if set the dropdown will feature a scroll bar if there are a large amount of choices and limit the visible lines to the specified number or 10 if true is used (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = defaults.var, -- default value or function that returns the default value (optional)
-    reference = "MyAddonDropdown" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 18
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local SORT_BY_VALUE         = { ["value"] = {} }
-local SORT_BY_VALUE_NUMERIC = { ["value"] = { isNumeric = true } }
-local SORT_TYPES = {
-    name = ZO_SORT_BY_NAME,
-    numeric = ZO_SORT_BY_NAME_NUMERIC,
-    value = SORT_BY_VALUE,
-    numericvalue = SORT_BY_VALUE_NUMERIC,
-}
-local SORT_ORDERS = {
-    up = ZO_SORT_ORDER_UP,
-    down = ZO_SORT_ORDER_DOWN,
-}
-
-local function UpdateDisabled(control)
-    local disable
-    if type(control.data.disabled) == "function" then
-        disable = control.data.disabled()
-    else
-        disable = control.data.disabled
-    end
-
-    control.dropdown:SetEnabled(not disable)
-    if disable then
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-    else
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    end
-end
-
-local function UpdateValue(control, forceDefault, value)
-    if forceDefault then --if we are forcing defaults
-        value = LAM.util.GetDefaultValue(control.data.default)
-        control.data.setFunc(value)
-        control.dropdown:SetSelectedItem(control.choices[value])
-    elseif value then
-        control.data.setFunc(value)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        value = control.data.getFunc()
-        control.dropdown:SetSelectedItem(control.choices[value])
-    end
-end
-
-local function DropdownCallback(control, choiceText, choice)
-    choice.control:UpdateValue(false, choice.value or choiceText)
-end
-
-local function SetupTooltips(comboBox, choicesTooltips)
-    local function ShowTooltip(control)
-        InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
-        SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.tooltip))
-        InformationTooltipTopLevel:BringWindowToTop()
-    end
-    local function HideTooltip(control)
-        ClearTooltip(InformationTooltip)
-    end
-
-    -- allow for tooltips on the drop down entries
-    local originalShow = comboBox.ShowDropdownInternal
-    comboBox.ShowDropdownInternal = function(comboBox)
-        originalShow(comboBox)
-        local entries = ZO_Menu.items
-        for i = 1, #entries do
-            local entry = entries[i]
-            local control = entries[i].item
-            control.tooltip = choicesTooltips[i]
-            entry.onMouseEnter = control:GetHandler("OnMouseEnter")
-            entry.onMouseExit = control:GetHandler("OnMouseExit")
-            ZO_PreHookHandler(control, "OnMouseEnter", ShowTooltip)
-            ZO_PreHookHandler(control, "OnMouseExit", HideTooltip)
-        end
-    end
-
-    local originalHide = comboBox.HideDropdownInternal
-    comboBox.HideDropdownInternal = function(self)
-        local entries = ZO_Menu.items
-        for i = 1, #entries do
-            local entry = entries[i]
-            local control = entries[i].item
-            control:SetHandler("OnMouseEnter", entry.onMouseEnter)
-            control:SetHandler("OnMouseExit", entry.onMouseExit)
-            control.tooltip = nil
-        end
-        originalHide(self)
-    end
-end
-
-local function UpdateChoices(control, choices, choicesValues, choicesTooltips)
-    control.dropdown:ClearItems() --remove previous choices --(need to call :SetSelectedItem()?)
-    ZO_ClearTable(control.choices)
-
-    --build new list of choices
-    local choices = choices or control.data.choices
-    local choicesValues = choicesValues or control.data.choicesValues
-    local choicesTooltips = choicesTooltips or control.data.choicesTooltips
-
-    if choicesValues then
-        assert(#choices == #choicesValues, "choices and choicesValues need to have the same size")
-    end
-
-    if choicesTooltips then
-        assert(#choices == #choicesTooltips, "choices and choicesTooltips need to have the same size")
-        if not control.scrollHelper then -- only do this for non-scrollable
-            SetupTooltips(control.dropdown, choicesTooltips)
-        end
-    end
-
-    for i = 1, #choices do
-        local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback)
-        entry.control = control
-        if choicesValues then
-            entry.value = choicesValues[i]
-        end
-        if choicesTooltips and control.scrollHelper then
-            entry.tooltip = choicesTooltips[i]
-        end
-        control.choices[entry.value or entry.name] = entry.name
-        control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE) --if sort type/order isn't specified, then don't sort
-    end
-end
-
-local function GrabSortingInfo(sortInfo)
-    local t, i = {}, 1
-    for info in string.gmatch(sortInfo, "([^%-]+)") do
-        t[i] = info
-        i = i + 1
-    end
-
-    return t
-end
-
-local DEFAULT_VISIBLE_ROWS = 10
-local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = 25 -- same as in zo_combobox.lua
-local CONTENT_PADDING = 24
-local SCROLLBAR_PADDING = 16
-local PADDING = GetMenuPadding() / 2 -- half the amount looks closer to the regular dropdown
-local ROUNDING_MARGIN = 0.01 -- needed to avoid rare issue with too many anchors processed
-local ScrollableDropdownHelper = ZO_Object:Subclass()
-
-function ScrollableDropdownHelper:New(...)
-    local object = ZO_Object.New(self)
-    object:Initialize(...)
-    return object
-end
-
-function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
-    local combobox = control.combobox
-    local dropdown = control.dropdown
-    self.parent = parent
-    self.control = control
-    self.combobox = combobox
-    self.dropdown = dropdown
-    self.visibleRows = visibleRows
-
-    -- clear anchors so we can adjust the width dynamically
-    dropdown.m_dropdown:ClearAnchors()
-    dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT)
-
-    -- handle dropdown or settingsmenu opening/closing
-    local function onShow() self:OnShow() end
-    local function onHide() self:OnHide() end
-    local function doHide() self:DoHide() end
-
-    ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow)
-    ZO_PreHook(dropdown, "HideDropdownInternal", onHide)
-    combobox:SetHandler("OnEffectivelyHidden", onHide)
-    parent:SetHandler("OnEffectivelyHidden", doHide)
-
-    -- dont fade entries near the edges
-    local scrollList = dropdown.m_scroll
-    scrollList.selectionTemplate = nil
-    scrollList.highlightTemplate = nil
-    ZO_ScrollList_EnableSelection(scrollList, "ZO_SelectionHighlight")
-    ZO_ScrollList_EnableHighlight(scrollList, "ZO_SelectionHighlight")
-    ZO_Scroll_SetUseFadeGradient(scrollList, false)
-
-    -- adjust scroll content anchor to mimic menu padding
-    local scroll = dropdown.m_dropdown:GetNamedChild("Scroll")
-    local anchor1 = {scroll:GetAnchor(0)}
-    local anchor2 = {scroll:GetAnchor(1)}
-    scroll:ClearAnchors()
-    scroll:SetAnchor(anchor1[2], anchor1[3], anchor1[4], anchor1[5] + PADDING, anchor1[6] + PADDING)
-    scroll:SetAnchor(anchor2[2], anchor2[3], anchor2[4], anchor2[5] - PADDING, anchor2[6] - PADDING)
-    ZO_ScrollList_Commit(scrollList)
-
-    -- hook mouse enter/exit
-    local function onMouseEnter(control) self:OnMouseEnter(control) end
-    local function onMouseExit(control) self:OnMouseExit(control) end
-
-    -- adjust row setup to mimic the highlight padding
-    local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
-    local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 2)
-    local oSetup = dataType1.setupCallback -- both types have the same setup function
-    local function SetupEntry(control, data, list)
-        oSetup(control, data, list)
-        control.m_label:SetAnchor(LEFT, nil, nil, 2)
-        -- no need to store old ones since we have full ownership of our dropdown controls
-        if not control.hookedMouseHandlers then --only do it once per control
-            control.hookedMouseHandlers = true
-            ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter)
-            ZO_PreHookHandler(control, "OnMouseExit", onMouseExit)
-            -- we could also just replace the handlers
-            --control:SetHandler("OnMouseEnter", onMouseEnter)
-            --control:SetHandler("OnMouseExit", onMouseExit)
-        end
-    end
-    dataType1.setupCallback = SetupEntry
-    dataType2.setupCallback = SetupEntry
-
-    -- adjust dimensions based on entries
-    local scrollContent = scroll:GetNamedChild("Contents")
-    ZO_PreHook(dropdown, "AddMenuItems", function()
-        local width = PADDING * 2 + zo_max(self:GetMaxWidth(), combobox:GetWidth())
-        local numItems = #dropdown.m_sortedItems
-        local anchorOffset = 0
-        if(numItems > self.visibleRows) then
-            width = width + CONTENT_PADDING + SCROLLBAR_PADDING
-            anchorOffset = -SCROLLBAR_PADDING
-            numItems = self.visibleRows
-        end
-        scrollContent:SetAnchor(BOTTOMRIGHT, nil, nil, anchorOffset)
-        local height = PADDING * 2 + numItems * (SCROLLABLE_ENTRY_TEMPLATE_HEIGHT + dropdown.m_spacing) - dropdown.m_spacing + ROUNDING_MARGIN
-        dropdown.m_dropdown:SetWidth(width)
-        dropdown.m_dropdown:SetHeight(height)
-    end)
-end
-
-function ScrollableDropdownHelper:OnShow()
-    local dropdown = self.dropdown
-    if dropdown.m_lastParent ~= ZO_Menus then
-        dropdown.m_lastParent = dropdown.m_dropdown:GetParent()
-        dropdown.m_dropdown:SetParent(ZO_Menus)
-        ZO_Menus:BringWindowToTop()
-    end
-end
-
-function ScrollableDropdownHelper:OnHide()
-    local dropdown = self.dropdown
-    if dropdown.m_lastParent then
-        dropdown.m_dropdown:SetParent(dropdown.m_lastParent)
-        dropdown.m_lastParent = nil
-    end
-end
-
-function ScrollableDropdownHelper:DoHide()
-    local dropdown = self.dropdown
-    if dropdown:IsDropdownVisible() then
-        dropdown:HideDropdown()
-    end
-end
-
-function ScrollableDropdownHelper:GetMaxWidth()
-    local dropdown = self.dropdown
-    local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
-
-    local dummy = dataType.pool:AcquireObject()
-    dataType.setupCallback(dummy, {
-        m_owner = dropdown,
-        name = "Dummy"
-    }, dropdown)
-
-    local maxWidth = 0
-    local label = dummy.m_label
-    local entries = dropdown.m_sortedItems
-    local numItems = #entries
-    for index = 1, numItems do
-        label:SetText(entries[index].name)
-        local width = label:GetTextWidth()
-        if (width > maxWidth) then
-            maxWidth = width
-        end
-    end
-
-    dataType.pool:ReleaseObject(dummy.key)
-    return maxWidth
-end
-
-function ScrollableDropdownHelper:OnMouseEnter(control)
-    -- call original code if we replace instead of hook the handler
-        --ZO_ScrollableComboBox_Entry_OnMouseEnter(control)
-    -- show tooltip
-    if control.m_data.tooltip then
-        InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
-        SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.m_data.tooltip))
-        InformationTooltipTopLevel:BringWindowToTop()
-    end
-end
-function ScrollableDropdownHelper:OnMouseExit(control)
-    -- call original code if we replace instead of hook the handler
-        --ZO_ScrollableComboBox_Entry_OnMouseExit(control)
-    -- hide tooltip
-    if control.m_data.tooltip then
-        ClearTooltip(InformationTooltip)
-    end
-end
-
-function LAMCreateControl.dropdown(parent, dropdownData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, dropdownData, controlName)
-    control.choices = {}
-
-    local countControl = parent
-    local name = parent:GetName()
-    if not name or #name == 0 then
-        countControl = LAMCreateControl
-        name = "LAM"
-    end
-    local comboboxCount = (countControl.comboboxCount or 0) + 1
-    countControl.comboboxCount = comboboxCount
-    control.combobox = wm:CreateControlFromVirtual(zo_strjoin(nil, name, "Combobox", comboboxCount), control.container, dropdownData.scrollable and "ZO_ScrollableComboBox" or "ZO_ComboBox")
-
-    local combobox = control.combobox
-    combobox:SetAnchor(TOPLEFT)
-    combobox:SetDimensions(control.container:GetDimensions())
-    combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-    combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-    control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox)
-    local dropdown = control.dropdown
-    dropdown:SetSortsItems(false) -- need to sort ourselves in order to be able to sort by value
-
-    if dropdownData.scrollable then
-        local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS
-        control.scrollHelper = ScrollableDropdownHelper:New(parent, control, visibleRows)
-    end
-
-    ZO_PreHook(dropdown, "UpdateItems", function(self)
-        assert(not self.m_sortsItems, "built-in dropdown sorting was reactivated, sorting is handled by LAM")
-        if control.m_sortOrder ~= nil and control.m_sortType then
-            local sortKey = next(control.m_sortType)
-            local sortFunc = function(item1, item2) return ZO_TableOrderingFunction(item1, item2, sortKey, control.m_sortType, control.m_sortOrder) end
-            table.sort(self.m_sortedItems, sortFunc)
-        end
-    end)
-
-    if dropdownData.sort then
-        local sortInfo = GrabSortingInfo(dropdownData.sort)
-        control.m_sortType, control.m_sortOrder = SORT_TYPES[sortInfo[1]], SORT_ORDERS[sortInfo[2]]
-    elseif dropdownData.choicesValues then
-        control.m_sortType, control.m_sortOrder = ZO_SORT_ORDER_UP, SORT_BY_VALUE
-    end
-
-    if dropdownData.warning ~= nil or dropdownData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.UpdateChoices = UpdateChoices
-    control:UpdateChoices(dropdownData.choices, dropdownData.choicesValues)
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-    if dropdownData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/editbox.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/editbox.lua
deleted file mode 100644
index d6baf11..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/editbox.lua
+++ /dev/null
@@ -1,156 +0,0 @@
---[[editboxData = {
-    type = "editbox",
-    name = "My Editbox", -- or string id or function returning a string
-    getFunc = function() return db.text end,
-    setFunc = function(text) db.text = text doStuff() end,
-    tooltip = "Editbox's tooltip text.", -- or string id or function returning a string (optional)
-    isMultiline = true, --boolean (optional)
-    isExtraWide = true, --boolean (optional)
-    width = "full", --or "half" (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = defaults.text, -- default value or function that returns the default value (optional)
-    reference = "MyAddonEditbox" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 14
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("editbox", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local function UpdateDisabled(control)
-    local disable
-    if type(control.data.disabled) == "function" then
-        disable = control.data.disabled()
-    else
-        disable = control.data.disabled
-    end
-
-    if disable then
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-        control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-    else
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-        control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    end
-    --control.editbox:SetEditEnabled(not disable)
-    control.editbox:SetMouseEnabled(not disable)
-end
-
-local function UpdateValue(control, forceDefault, value)
-    if forceDefault then --if we are forcing defaults
-        value = LAM.util.GetDefaultValue(control.data.default)
-        control.data.setFunc(value)
-        control.editbox:SetText(value)
-    elseif value then
-        control.data.setFunc(value)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        value = control.data.getFunc()
-        control.editbox:SetText(value)
-    end
-end
-
-local MIN_HEIGHT = 24
-local HALF_WIDTH_LINE_SPACING = 2
-function LAMCreateControl.editbox(parent, editboxData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, editboxData, controlName)
-
-    local container = control.container
-    control.bg = wm:CreateControlFromVirtual(nil, container, "ZO_EditBackdrop")
-    local bg = control.bg
-    bg:SetAnchorFill()
-
-    if editboxData.isMultiline then
-        control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop")
-        control.editbox:SetHandler("OnMouseWheel", function(self, delta)
-            if self:HasFocus() then --only set focus to new spots if the editbox is currently in use
-                local cursorPos = self:GetCursorPosition()
-                local text = self:GetText()
-                local textLen = text:len()
-                local newPos
-                if delta > 0 then --scrolling up
-                    local reverseText = text:reverse()
-                    local revCursorPos = textLen - cursorPos
-                    local revPos = reverseText:find("\n", revCursorPos+1)
-                    newPos = revPos and textLen - revPos
-                else --scrolling down
-                    newPos = text:find("\n", cursorPos+1)
-                end
-                if newPos then --if we found a new line, then scroll, otherwise don't
-                    self:SetCursorPosition(newPos)
-                end
-            end
-        end)
-    else
-        control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop")
-    end
-    local editbox = control.editbox
-    editbox:SetText(editboxData.getFunc())
-    editbox:SetMaxInputChars(3000)
-    editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end)
-    editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end)
-    editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-    editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-
-    local MIN_WIDTH = (parent.GetWidth and (parent:GetWidth() / 10)) or (parent.panel.GetWidth and (parent.panel:GetWidth() / 10)) or 0
-
-    control.label:ClearAnchors()
-    container:ClearAnchors()
-
-    control.label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
-    container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
-
-    if control.isHalfWidth then
-        container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
-    end
-
-    if editboxData.isExtraWide then
-        container:SetAnchor(BOTTOMLEFT, control, BOTTOMLEFT, 0, 0)
-    else
-        container:SetWidth(MIN_WIDTH * 3.2)
-    end
-
-    if editboxData.isMultiline then
-        container:SetHeight(MIN_HEIGHT * 3)
-    else
-        container:SetHeight(MIN_HEIGHT)
-    end
-
-    if control.isHalfWidth ~= true and editboxData.isExtraWide ~= true then
-        control:SetHeight(container:GetHeight())
-    else
-        control:SetHeight(container:GetHeight() + control.label:GetHeight())
-    end
-
-    editbox:ClearAnchors()
-    editbox:SetAnchor(TOPLEFT, container, TOPLEFT, 2, 2)
-    editbox:SetAnchor(BOTTOMRIGHT, container, BOTTOMRIGHT, -2, -2)
-
-    if editboxData.warning ~= nil or editboxData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        if editboxData.isExtraWide then
-            control.warning:SetAnchor(BOTTOMRIGHT, control.bg, TOPRIGHT, 2, 0)
-        else
-            control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0)
-        end
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-    if editboxData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/header.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/header.lua
deleted file mode 100644
index eadff38..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/header.lua
+++ /dev/null
@@ -1,42 +0,0 @@
---[[headerData = {
-    type = "header",
-    name = "My Header", -- or string id or function returning a string
-    width = "full", --or "half" (optional)
-    reference = "MyAddonHeader" -- unique global reference to control (optional)
-} ]]
-
-
-local widgetVersion = 8
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("header", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local function UpdateValue(control)
-    control.header:SetText(LAM.util.GetStringFromValue(control.data.name))
-end
-
-local MIN_HEIGHT = 30
-function LAMCreateControl.header(parent, headerData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, headerData, controlName)
-    local isHalfWidth = control.isHalfWidth
-    local width = control:GetWidth()
-    control:SetDimensions(isHalfWidth and width / 2 or width, MIN_HEIGHT)
-
-    control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
-    local divider = control.divider
-    divider:SetWidth(isHalfWidth and width / 2 or width)
-    divider:SetAnchor(TOPLEFT)
-
-    control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-    local header = control.header
-    header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT)
-    header:SetAnchor(BOTTOMRIGHT)
-    header:SetText(LAM.util.GetStringFromValue(headerData.name))
-
-    control.UpdateValue = UpdateValue
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/iconpicker.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/iconpicker.lua
deleted file mode 100644
index 65c7782..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/iconpicker.lua
+++ /dev/null
@@ -1,436 +0,0 @@
---[[iconpickerData = {
-    type = "iconpicker",
-    name = "My Icon Picker", -- or string id or function returning a string
-    choices = {"texture path 1", "texture path 2", "texture path 3"},
-    getFunc = function() return db.var end,
-    setFunc = function(var) db.var = var doStuff() end,
-    tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
-    choicesTooltips = {"icon tooltip 1", "icon tooltip 2", "icon tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
-    maxColumns = 5, -- number of icons in one row (optional)
-    visibleRows = 4.5, -- number of visible rows (optional)
-    iconSize = 28, -- size of the icons (optional)
-    defaultColor = ZO_ColorDef:New("FFFFFF"), -- default color of the icons (optional)
-    width = "full", --or "half" (optional)
-    beforeShow = function(control, iconPicker) return preventShow end, --(optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = defaults.var, -- default value or function that returns the default value (optional)
-    reference = "MyAddonIconPicker" -- unique global reference to control (optional)
-} ]]
-
-local widgetVersion = 8
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("iconpicker", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local IconPickerMenu = ZO_Object:Subclass()
-local iconPicker
-LAM.util.GetIconPickerMenu = function()
-    if not iconPicker then
-        iconPicker = IconPickerMenu:New("LAMIconPicker")
-        local sceneFragment = LAM:GetAddonSettingsFragment()
-        ZO_PreHook(sceneFragment, "OnHidden", function()
-            if not iconPicker.control:IsHidden() then
-                iconPicker:Clear()
-            end
-        end)
-    end
-    return iconPicker
-end
-
-function IconPickerMenu:New(...)
-    local object = ZO_Object.New(self)
-    object:Initialize(...)
-    return object
-end
-
-function IconPickerMenu:Initialize(name)
-    local control = wm:CreateTopLevelWindow(name)
-    control:SetDrawTier(DT_HIGH)
-    control:SetHidden(true)
-    self.control = control
-
-    local scrollContainer = wm:CreateControlFromVirtual(name .. "ScrollContainer", control, "ZO_ScrollContainer")
-    -- control:SetDimensions(control.container:GetWidth(), height) -- adjust to icon size / col count
-    scrollContainer:SetAnchorFill()
-    ZO_Scroll_SetUseFadeGradient(scrollContainer, false)
-    ZO_Scroll_SetHideScrollbarOnDisable(scrollContainer, false)
-    ZO_VerticalScrollbarBase_OnMouseExit(scrollContainer:GetNamedChild("ScrollBar")) -- scrollbar initialization seems to be broken so we force it to update the correct alpha value
-    local scroll = GetControl(scrollContainer, "ScrollChild")
-    self.scroll = scroll
-    self.scrollContainer = scrollContainer
-
-    local bg = wm:CreateControl(nil, scrollContainer, CT_BACKDROP)
-    bg:SetAnchor(TOPLEFT, scrollContainer, TOPLEFT, 0, -3)
-    bg:SetAnchor(BOTTOMRIGHT, scrollContainer, BOTTOMRIGHT, 2, 5)
-    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
-    bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
-    bg:SetInsets(16, 16, -16, -16)
-
-    local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
-    mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
-    mungeOverlay:SetDrawLevel(1)
-    mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
-    mungeOverlay:SetAnchorFill()
-
-    local mouseOver = wm:CreateControl(nil, scrollContainer, CT_TEXTURE)
-    mouseOver:SetDrawLevel(2)
-    mouseOver:SetTexture("EsoUI/Art/Buttons/minmax_mouseover.dds")
-    mouseOver:SetHidden(true)
-
-    local function IconFactory(pool)
-        local icon = wm:CreateControl(name .. "Entry" .. pool:GetNextControlId(), scroll, CT_TEXTURE)
-        icon:SetMouseEnabled(true)
-        icon:SetDrawLevel(3)
-        icon:SetHandler("OnMouseEnter", function()
-            mouseOver:SetAnchor(TOPLEFT, icon, TOPLEFT, 0, 0)
-            mouseOver:SetAnchor(BOTTOMRIGHT, icon, BOTTOMRIGHT, 0, 0)
-            mouseOver:SetHidden(false)
-            if self.customOnMouseEnter then
-                self.customOnMouseEnter(icon)
-            else
-                self:OnMouseEnter(icon)
-            end
-        end)
-        icon:SetHandler("OnMouseExit", function()
-            mouseOver:ClearAnchors()
-            mouseOver:SetHidden(true)
-            if self.customOnMouseExit then
-                self.customOnMouseExit(icon)
-            else
-                self:OnMouseExit(icon)
-            end
-        end)
-        icon:SetHandler("OnMouseUp", function(control, ...)
-            PlaySound("Click")
-            icon.OnSelect(icon, icon.texture)
-            self:Clear()
-        end)
-        return icon
-    end
-
-    local function ResetFunction(icon)
-        icon:ClearAnchors()
-    end
-
-    self.iconPool = ZO_ObjectPool:New(IconFactory, ResetFunction)
-    self:SetMaxColumns(1)
-    self.icons = {}
-    self.color = ZO_DEFAULT_ENABLED_COLOR
-
-    EVENT_MANAGER:RegisterForEvent(name .. "_OnGlobalMouseUp", EVENT_GLOBAL_MOUSE_UP, function()
-        if self.refCount ~= nil then
-            local moc = wm:GetMouseOverControl()
-            if(moc:GetOwningWindow() ~= control) then
-                self.refCount = self.refCount - 1
-                if self.refCount <= 0 then
-                    self:Clear()
-                end
-            end
-        end
-    end)
-end
-
-function IconPickerMenu:OnMouseEnter(icon)
-    InitializeTooltip(InformationTooltip, icon, TOPLEFT, 0, 0, BOTTOMRIGHT)
-    SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(icon.tooltip))
-    InformationTooltipTopLevel:BringWindowToTop()
-end
-
-function IconPickerMenu:OnMouseExit(icon)
-    ClearTooltip(InformationTooltip)
-end
-
-function IconPickerMenu:SetMaxColumns(value)
-    self.maxCols = value ~= nil and value or 5
-end
-
-local DEFAULT_SIZE = 28
-function IconPickerMenu:SetIconSize(value)
-    local iconSize = DEFAULT_SIZE
-    if value ~= nil then iconSize = math.max(iconSize, value) end
-    self.iconSize = iconSize
-end
-
-function IconPickerMenu:SetVisibleRows(value)
-    self.visibleRows = value ~= nil and value or 4.5
-end
-
-function IconPickerMenu:SetMouseHandlers(onEnter, onExit)
-    self.customOnMouseEnter = onEnter
-    self.customOnMouseExit = onExit
-end
-
-function IconPickerMenu:UpdateDimensions()
-    local iconSize = self.iconSize
-    local width = iconSize * self.maxCols + 20
-    local height = iconSize * self.visibleRows
-    self.control:SetDimensions(width, height)
-
-    local icons = self.icons
-    for i = 1, #icons do
-        local icon = icons[i]
-        icon:SetDimensions(iconSize, iconSize)
-    end
-end
-
-function IconPickerMenu:UpdateAnchors()
-    local iconSize = self.iconSize
-    local col, maxCols = 1, self.maxCols
-    local previousCol, previousRow
-    local scroll = self.scroll
-    local icons = self.icons
-
-    for i = 1, #icons do
-        local icon = icons[i]
-        icon:ClearAnchors()
-        if i == 1 then
-            icon:SetAnchor(TOPLEFT, scroll, TOPLEFT, 0, 0)
-            previousRow = icon
-        elseif col == 1 then
-            icon:SetAnchor(TOPLEFT, previousRow, BOTTOMLEFT, 0, 0)
-            previousRow = icon
-        else
-            icon:SetAnchor(TOPLEFT, previousCol, TOPRIGHT, 0, 0)
-        end
-        previousCol = icon
-        col = col >= maxCols and 1 or col + 1
-    end
-end
-
-function IconPickerMenu:Clear()
-    self.icons = {}
-    self.iconPool:ReleaseAllObjects()
-    self.control:SetHidden(true)
-    self.color = ZO_DEFAULT_ENABLED_COLOR
-    self.refCount = nil
-    self.parent = nil
-    self.customOnMouseEnter = nil
-    self.customOnMouseExit = nil
-end
-
-function IconPickerMenu:AddIcon(texturePath, callback, tooltip)
-    local icon, key = self.iconPool:AcquireObject()
-    icon:SetTexture(texturePath)
-    icon:SetColor(self.color:UnpackRGBA())
-    icon.texture = texturePath
-    icon.tooltip = tooltip
-    icon.OnSelect = callback
-    self.icons[#self.icons + 1] = icon
-end
-
-function IconPickerMenu:Show(parent)
-    if #self.icons == 0 then return false end
-    if not self.control:IsHidden() then self:Clear() return false end
-    self:UpdateDimensions()
-    self:UpdateAnchors()
-
-    local control = self.control
-    control:ClearAnchors()
-    control:SetAnchor(TOPLEFT, parent, BOTTOMLEFT, 0, 8)
-    control:SetHidden(false)
-    control:BringWindowToTop()
-    self.parent = parent
-    self.refCount = 2
-
-    return true
-end
-
-function IconPickerMenu:SetColor(color)
-    local icons = self.icons
-    self.color = color
-    for i = 1, #icons do
-        local icon = icons[i]
-        icon:SetColor(color:UnpackRGBA())
-    end
-end
-
--------------------------------------------------------------
-
-local function UpdateChoices(control, choices, choicesTooltips)
-    local data = control.data
-    if not choices then
-        choices, choicesTooltips = data.choices, data.choicesTooltips or {}
-    end
-    local addedChoices = {}
-
-    local iconPicker = LAM.util.GetIconPickerMenu()
-    iconPicker:Clear()
-    for i = 1, #choices do
-        local texture = choices[i]
-        if not addedChoices[texture] then -- remove duplicates
-            iconPicker:AddIcon(choices[i], function(self, texture)
-                control.icon:SetTexture(texture)
-                data.setFunc(texture)
-                LAM.util.RequestRefreshIfNeeded(control)
-            end, LAM.util.GetStringFromValue(choicesTooltips[i]))
-        addedChoices[texture] = true
-        end
-    end
-end
-
-local function IsDisabled(control)
-    if type(control.data.disabled) == "function" then
-        return control.data.disabled()
-    else
-        return control.data.disabled
-    end
-end
-
-local function SetColor(control, color)
-    local icon = control.icon
-    if IsDisabled(control) then
-        icon:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-    else
-        icon.color = color or control.data.defaultColor or ZO_DEFAULT_ENABLED_COLOR
-        icon:SetColor(icon.color:UnpackRGBA())
-    end
-
-    local iconPicker = LAM.util.GetIconPickerMenu()
-    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
-        iconPicker:SetColor(icon.color)
-    end
-end
-
-local function UpdateDisabled(control)
-    local disable = IsDisabled(control)
-
-    control.dropdown:SetMouseEnabled(not disable)
-    control.dropdownButton:SetEnabled(not disable)
-
-    local iconPicker = LAM.util.GetIconPickerMenu()
-    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
-        iconPicker:Clear()
-    end
-
-    SetColor(control, control.icon.color)
-    if disable then
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-    else
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    end
-end
-
-local function UpdateValue(control, forceDefault, value)
-    if forceDefault then --if we are forcing defaults
-        value = LAM.util.GetDefaultValue(control.data.default)
-        control.data.setFunc(value)
-        control.icon:SetTexture(value)
-    elseif value then
-        control.data.setFunc(value)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        value = control.data.getFunc()
-        control.icon:SetTexture(value)
-    end
-end
-
-local MIN_HEIGHT = 26
-local HALF_WIDTH_LINE_SPACING = 2
-local function SetIconSize(control, size)
-    local icon = control.icon
-    icon.size = size
-    icon:SetDimensions(size, size)
-
-    local height = size + 4
-    control.dropdown:SetDimensions(size + 20, height)
-    height = math.max(height, MIN_HEIGHT)
-    control.container:SetHeight(height)
-    if control.lineControl then
-        control.lineControl:SetHeight(MIN_HEIGHT + size + HALF_WIDTH_LINE_SPACING)
-    else
-        control:SetHeight(height)
-    end
-
-    local iconPicker = LAM.util.GetIconPickerMenu()
-    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
-        iconPicker:SetIconSize(size)
-        iconPicker:UpdateDimensions()
-        iconPicker:UpdateAnchors()
-    end
-end
-
-function LAMCreateControl.iconpicker(parent, iconpickerData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, iconpickerData, controlName)
-
-    local function ShowIconPicker()
-        local iconPicker = LAM.util.GetIconPickerMenu()
-        if iconPicker.parent == control.container then
-            iconPicker:Clear()
-        else
-            iconPicker:SetMaxColumns(iconpickerData.maxColumns)
-            iconPicker:SetVisibleRows(iconpickerData.visibleRows)
-            iconPicker:SetIconSize(control.icon.size)
-            UpdateChoices(control)
-            iconPicker:SetColor(control.icon.color)
-            if iconpickerData.beforeShow then
-                if iconpickerData.beforeShow(control, iconPicker) then
-                    iconPicker:Clear()
-                    return
-                end
-            end
-            iconPicker:Show(control.container)
-        end
-    end
-
-    local iconSize = iconpickerData.iconSize ~= nil and iconpickerData.iconSize or DEFAULT_SIZE
-    control.dropdown = wm:CreateControl(nil, control.container, CT_CONTROL)
-    local dropdown = control.dropdown
-    dropdown:SetAnchor(LEFT, control.container, LEFT, 0, 0)
-    dropdown:SetMouseEnabled(true)
-    dropdown:SetHandler("OnMouseUp", ShowIconPicker)
-    dropdown:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-    dropdown:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-
-    control.icon = wm:CreateControl(nil, dropdown, CT_TEXTURE)
-    local icon = control.icon
-    icon:SetAnchor(LEFT, dropdown, LEFT, 3, 0)
-    icon:SetDrawLevel(2)
-
-    local dropdownButton = wm:CreateControlFromVirtual(nil, dropdown, "ZO_DropdownButton")
-    dropdownButton:SetDimensions(16, 16)
-    dropdownButton:SetHandler("OnClicked", ShowIconPicker)
-    dropdownButton:SetAnchor(RIGHT, dropdown, RIGHT, -3, 0)
-    control.dropdownButton = dropdownButton
-
-    control.bg = wm:CreateControl(nil, dropdown, CT_BACKDROP)
-    local bg = control.bg
-    bg:SetAnchor(TOPLEFT, dropdown, TOPLEFT, 0, -3)
-    bg:SetAnchor(BOTTOMRIGHT, dropdown, BOTTOMRIGHT, 2, 5)
-    bg:SetEdgeTexture("EsoUI/Art/Tooltips/UI-Border.dds", 128, 16)
-    bg:SetCenterTexture("EsoUI/Art/Tooltips/UI-TooltipCenter.dds")
-    bg:SetInsets(16, 16, -16, -16)
-    local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
-    mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
-    mungeOverlay:SetDrawLevel(1)
-    mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
-    mungeOverlay:SetAnchorFill()
-
-    if iconpickerData.warning ~= nil or iconpickerData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, control.container, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.UpdateChoices = UpdateChoices
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-    control.SetColor = SetColor
-    control:SetColor()
-    control.SetIconSize = SetIconSize
-    control:SetIconSize(iconSize)
-
-    if iconpickerData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/panel.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/panel.lua
deleted file mode 100644
index 1404686..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/panel.lua
+++ /dev/null
@@ -1,126 +0,0 @@
---[[panelData = {
-    type = "panel",
-    name = "Window Title", -- or string id or function returning a string
-    displayName = "My Longer Window Title",  -- or string id or function returning a string (optional) (can be useful for long addon names or if you want to colorize it)
-    author = "Seerah",  -- or string id or function returning a string (optional)
-    version = "2.0",  -- or string id or function returning a string (optional)
-    website = "http://www.esoui.com/downloads/info7-LibAddonMenu.html", -- URL of website where the addon can be updated (optional)
-    keywords = "settings", -- additional keywords for search filter (it looks for matches in name..keywords..author) (optional)
-    slashCommand = "/myaddon", -- will register a keybind to open to this panel (don't forget to include the slash!) (optional)
-    registerForRefresh = true, --boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown)
-    registerForDefaults = true, --boolean (optional) (will set all options controls back to default values)
-    resetFunc = function() print("defaults reset") end, --(optional) custom function to run after settings are reset to defaults
-} ]]
-
-
-local widgetVersion = 13
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("panel", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local cm = CALLBACK_MANAGER
-
-local function RefreshPanel(control)
-    local panel = LAM.util.GetTopPanel(control) --callback can be fired by a single control, by the panel showing or by a nested submenu
-    local panelControls = panel.controlsToRefresh
-
-    for i = 1, #panelControls do
-        local updateControl = panelControls[i]
-        if updateControl ~= control and updateControl.UpdateValue then
-            updateControl:UpdateValue()
-        end
-        if updateControl.UpdateDisabled then
-            updateControl:UpdateDisabled()
-        end
-        if updateControl.UpdateWarning then
-            updateControl:UpdateWarning()
-        end
-    end
-end
-
-local function ForceDefaults(panel)
-    local panelControls = panel.controlsToRefresh
-
-    for i = 1, #panelControls do
-        local updateControl = panelControls[i]
-        if updateControl.UpdateValue and updateControl.data.default ~= nil then
-            updateControl:UpdateValue(true)
-        end
-    end
-
-    if panel.data.resetFunc then
-        panel.data.resetFunc()
-    end
-
-    cm:FireCallbacks("LAM-RefreshPanel", panel)
-end
-
-local callbackRegistered = false
-LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
-local SEPARATOR = " - "
-local LINK_COLOR = ZO_ColorDef:New("5959D5")
-local LINK_MOUSE_OVER_COLOR = ZO_ColorDef:New("B8B8D3")
-
-function LAMCreateControl.panel(parent, panelData, controlName)
-    local control = wm:CreateControl(controlName, parent, CT_CONTROL)
-
-    control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-    local label = control.label
-    label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 4)
-    label:SetText(LAM.util.GetStringFromValue(panelData.displayName or panelData.name))
-
-    if panelData.author or panelData.version then
-        control.info = wm:CreateControl(nil, control, CT_LABEL)
-        local info = control.info
-        info:SetFont(LAM.util.L["PANEL_INFO_FONT"])
-        info:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
-
-        local output = {}
-        if panelData.author then
-            output[#output + 1] = zo_strformat(LAM.util.L["AUTHOR"], LAM.util.GetStringFromValue(panelData.author))
-        end
-        if panelData.version then
-            output[#output + 1] = zo_strformat(LAM.util.L["VERSION"], LAM.util.GetStringFromValue(panelData.version))
-        end
-        info:SetText(table.concat(output, SEPARATOR))
-    end
-
-    if panelData.website then
-        control.website = wm:CreateControl(nil, control, CT_BUTTON)
-        local website = control.website
-        website:SetClickSound("Click")
-        website:SetFont(LAM.util.L["PANEL_INFO_FONT"])
-        website:SetNormalFontColor(LINK_COLOR:UnpackRGBA())
-        website:SetMouseOverFontColor(LINK_MOUSE_OVER_COLOR:UnpackRGBA())
-        if(control.info) then
-            website:SetAnchor(TOPLEFT, control.info, TOPRIGHT, 0, 0)
-            website:SetText(string.format("|cffffff%s|r%s", SEPARATOR, LAM.util.L["WEBSITE"]))
-        else
-            website:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
-            website:SetText(LAM.util.L["WEBSITE"])
-        end
-        website:SetDimensions(website:GetLabelControl():GetTextDimensions())
-        website:SetHandler("OnClicked", function()
-            RequestOpenUnsafeURL(panelData.website)
-        end)
-    end
-
-    control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
-    LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1
-    local container = control.container
-    container:SetAnchor(TOPLEFT, control.info or label, BOTTOMLEFT, 0, 20)
-    container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3)
-    control.scroll = GetControl(control.container, "ScrollChild")
-    control.scroll:SetResizeToFitPadding(0, 20)
-
-    if panelData.registerForRefresh and not callbackRegistered then --don't want to register our callback more than once
-        cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel)
-        callbackRegistered = true
-    end
-
-    control.ForceDefaults = ForceDefaults
-    control.data = panelData
-    control.controlsToRefresh = {}
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/slider.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/slider.lua
deleted file mode 100644
index bd721c5..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/slider.lua
+++ /dev/null
@@ -1,212 +0,0 @@
---[[sliderData = {
-    type = "slider",
-    name = "My Slider", -- or string id or function returning a string
-    getFunc = function() return db.var end,
-    setFunc = function(value) db.var = value doStuff() end,
-    min = 0,
-    max = 20,
-    step = 1, --(optional)
-    clampInput = true, -- boolean, if set to false the input won't clamp to min and max and allow any number instead (optional)
-    decimals = 0, -- when specified the input value is rounded to the specified number of decimals (optional)
-    autoSelect = false, -- boolean, automatically select everything in the text input field when it gains focus (optional)
-    inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional)
-    tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional)
-    width = "full", --or "half" (optional)
-    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
-    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
-    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
-    default = defaults.var, -- default value or function that returns the default value (optional)
-    reference = "MyAddonSlider" -- unique global reference to control (optional)
-} ]]
-
-local widgetVersion = 12
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("slider", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local strformat = string.format
-
-local function RoundDecimalToPlace(d, place)
-    return tonumber(strformat("%." .. tostring(place) .. "f", d))
-end
-
-local function UpdateDisabled(control)
-    local disable
-    if type(control.data.disabled) == "function" then
-        disable = control.data.disabled()
-    else
-        disable = control.data.disabled
-    end
-
-    control.slider:SetEnabled(not disable)
-    control.slidervalue:SetEditEnabled(not disable)
-    if disable then
-        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-        control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-        control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
-        control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
-    else
-        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-        control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-        control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-        control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
-    end
-end
-
-local function UpdateValue(control, forceDefault, value)
-    if forceDefault then --if we are forcing defaults
-        value = LAM.util.GetDefaultValue(control.data.default)
-        control.data.setFunc(value)
-    elseif value then
-        if control.data.decimals then
-            value = RoundDecimalToPlace(value, control.data.decimals)
-        end
-        if control.data.clampInput ~= false then
-            value = math.max(math.min(value, control.data.max), control.data.min)
-        end
-        control.data.setFunc(value)
-        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
-        LAM.util.RequestRefreshIfNeeded(control)
-    else
-        value = control.data.getFunc()
-    end
-
-    control.slider:SetValue(value)
-    control.slidervalue:SetText(value)
-end
-
-function LAMCreateControl.slider(parent, sliderData, controlName)
-    local control = LAM.util.CreateLabelAndContainerControl(parent, sliderData, controlName)
-    local isInputOnRight = sliderData.inputLocation == "right"
-
-    --skipping creating the backdrop...  Is this the actual slider texture?
-    control.slider = wm:CreateControl(nil, control.container, CT_SLIDER)
-    local slider = control.slider
-    slider:SetAnchor(TOPLEFT)
-    slider:SetHeight(14)
-    if(isInputOnRight) then
-        slider:SetAnchor(TOPRIGHT, nil, nil, -60)
-    else
-        slider:SetAnchor(TOPRIGHT)
-    end
-    slider:SetMouseEnabled(true)
-    slider:SetOrientation(ORIENTATION_HORIZONTAL)
-    --put nil for highlighted texture file path, and what look to be texture coords
-    slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16)
-    local minValue = sliderData.min
-    local maxValue = sliderData.max
-    slider:SetMinMax(minValue, maxValue)
-    slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
-    slider:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
-
-    slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP)
-    local bg = slider.bg
-    bg:SetCenterColor(0, 0, 0)
-    bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4)
-    bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4)
-    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)
-
-    control.minText = wm:CreateControl(nil, slider, CT_LABEL)
-    local minText = control.minText
-    minText:SetFont("ZoFontGameSmall")
-    minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT)
-    minText:SetText(sliderData.min)
-
-    control.maxText = wm:CreateControl(nil, slider, CT_LABEL)
-    local maxText = control.maxText
-    maxText:SetFont("ZoFontGameSmall")
-    maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT)
-    maxText:SetText(sliderData.max)
-
-    control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop")
-    if(isInputOnRight) then
-        control.slidervalueBG:SetDimensions(60, 26)
-        control.slidervalueBG:SetAnchor(LEFT, slider, RIGHT, 5, 0)
-    else
-        control.slidervalueBG:SetDimensions(50, 16)
-        control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
-    end
-    control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")
-    local slidervalue = control.slidervalue
-    slidervalue:ClearAnchors()
-    slidervalue:SetAnchor(TOPLEFT, control.slidervalueBG, TOPLEFT, 3, 1)
-    slidervalue:SetAnchor(BOTTOMRIGHT, control.slidervalueBG, BOTTOMRIGHT, -3, -1)
-    slidervalue:SetTextType(TEXT_TYPE_NUMERIC)
-    if(isInputOnRight) then
-        slidervalue:SetFont("ZoFontGameLarge")
-    else
-        slidervalue:SetFont("ZoFontGameSmall")
-    end
-
-    local isHandlingChange = false
-    local function HandleValueChanged(value)
-        if isHandlingChange then return end
-        if sliderData.decimals then
-            value = RoundDecimalToPlace(value, sliderData.decimals)
-        end
-        isHandlingChange = true
-        slider:SetValue(value)
-        slidervalue:SetText(value)
-        isHandlingChange = false
-    end
-
-    slidervalue:SetHandler("OnEscape", function(self)
-        HandleValueChanged(sliderData.getFunc())
-        self:LoseFocus()
-    end)
-    slidervalue:SetHandler("OnEnter", function(self)
-        self:LoseFocus()
-    end)
-    slidervalue:SetHandler("OnFocusLost", function(self)
-        local value = tonumber(self:GetText())
-        control:UpdateValue(false, value)
-    end)
-    slidervalue:SetHandler("OnTextChanged", function(self)
-        local input = self:GetText()
-        if(#input > 1 and not input:sub(-1):match("[0-9]")) then return end
-        local value = tonumber(input)
-        if(value) then
-            HandleValueChanged(value)
-        end
-    end)
-    if(sliderData.autoSelect) then
-        ZO_PreHookHandler(slidervalue, "OnFocusGained", function(self)
-            self:SelectAll()
-        end)
-    end
-
-    local range = maxValue - minValue
-    slider:SetValueStep(sliderData.step or 1)
-    slider:SetHandler("OnValueChanged", function(self, value, eventReason)
-        if eventReason == EVENT_REASON_SOFTWARE then return end
-        HandleValueChanged(value)
-    end)
-    slider:SetHandler("OnSliderReleased", function(self, value)
-        control:UpdateValue(false, value)
-    end)
-    slider:SetHandler("OnMouseWheel", function(self, value)
-        if(not self:GetEnabled()) then return end
-        local new_value = (tonumber(slidervalue:GetText()) or sliderData.min or 0) + ((sliderData.step or 1) * value)
-        control:UpdateValue(false, new_value)
-    end)
-
-    if sliderData.warning ~= nil or sliderData.requiresReload then
-        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
-        control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0)
-        control.UpdateWarning = LAM.util.UpdateWarning
-        control:UpdateWarning()
-    end
-
-    control.UpdateValue = UpdateValue
-    control:UpdateValue()
-
-    if sliderData.disabled ~= nil then
-        control.UpdateDisabled = UpdateDisabled
-        control:UpdateDisabled()
-    end
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-    LAM.util.RegisterForReloadIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/submenu.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/submenu.lua
deleted file mode 100644
index 1766a1f..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/submenu.lua
+++ /dev/null
@@ -1,108 +0,0 @@
---[[submenuData = {
-    type = "submenu",
-    name = "Submenu Title", -- or string id or function returning a string
-    tooltip = "My submenu tooltip", -- -- or string id or function returning a string (optional)
-    controls = {sliderData, buttonData} --(optional) used by LAM
-    reference = "MyAddonSubmenu" --(optional) unique global reference to control
-} ]]
-
-local widgetVersion = 11
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("submenu", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-local am = ANIMATION_MANAGER
-
-local function UpdateValue(control)
-    control.label:SetText(LAM.util.GetStringFromValue(control.data.name))
-    if control.data.tooltip then
-        control.label.data.tooltipText = LAM.util.GetStringFromValue(control.data.tooltip)
-    end
-end
-
-local function AnimateSubmenu(clicked)
-    local control = clicked:GetParent()
-    control.open = not control.open
-
-    if control.open then
-        control.animation:PlayFromStart()
-    else
-        control.animation:PlayFromEnd()
-    end
-end
-
-function LAMCreateControl.submenu(parent, submenuData, controlName)
-    local width = parent:GetWidth() - 45
-    local control = wm:CreateControl(controlName or submenuData.reference, parent.scroll or parent, CT_CONTROL)
-    control.panel = parent
-    control.data = submenuData
-
-    control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
-    local label = control.label
-    label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
-    label:SetDimensions(width, 30)
-    label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
-    label:SetText(LAM.util.GetStringFromValue(submenuData.name))
-    label:SetMouseEnabled(true)
-    if submenuData.tooltip then
-        label.data = {tooltipText = LAM.util.GetStringFromValue(submenuData.tooltip)}
-        label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-        label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-    end
-
-    control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
-    local scroll = control.scroll
-    scroll:SetParent(control)
-    scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10)
-    scroll:SetDimensionConstraints(width + 5, 0, width + 5, 0)
-
-    control.bg = wm:CreateControl(nil, label, CT_BACKDROP)
-    local bg = control.bg
-    bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5)
-    bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
-    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
-    bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
-    bg:SetInsets(16, 16, -16, -16)
-
-    control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
-    local arrow = control.arrow
-    arrow:SetDimensions(28, 28)
-    arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds") --list_sortup for the other way
-    arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5)
-
-    --figure out the cool animation later...
-    control.animation = am:CreateTimeline()
-    local animation = control.animation
-    animation:SetPlaybackType(ANIMATION_SIZE, 0) --2nd arg = loop count
-
-    control:SetResizeToFitDescendents(true)
-    control.open = false
-    label:SetHandler("OnMouseUp", AnimateSubmenu)
-    animation:SetHandler("OnStop", function(self, completedPlaying)
-        scroll:SetResizeToFitDescendents(control.open)
-        if control.open then
-            control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds")
-            scroll:SetResizeToFitPadding(5, 20)
-        else
-            control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")
-            scroll:SetResizeToFitPadding(5, 0)
-            scroll:SetHeight(0)
-        end
-    end)
-
-    --small strip at the bottom of the submenu that you can click to close it
-    control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE)
-    local btmToggle = control.btmToggle
-    btmToggle:SetMouseEnabled(true)
-    btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT)
-    btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT)
-    btmToggle:SetHeight(15)
-    btmToggle:SetAlpha(0)
-    btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
-
-    control.UpdateValue = UpdateValue
-
-    LAM.util.RegisterForRefreshIfNeeded(control)
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/texture.lua b/DailyAutoShare/libs/LibAddonMenu-2.0/controls/texture.lua
deleted file mode 100644
index 29dda7c..0000000
--- a/DailyAutoShare/libs/LibAddonMenu-2.0/controls/texture.lua
+++ /dev/null
@@ -1,45 +0,0 @@
---[[textureData = {
-    type = "texture",
-    image = "file/path.dds",
-    imageWidth = 64, --max of 250 for half width, 510 for full
-    imageHeight = 32, --max of 100
-    tooltip = "Image's tooltip text.", -- or string id or function returning a string (optional)
-    width = "full", --or "half" (optional)
-    reference = "MyAddonTexture" --(optional) unique global reference to control
-} ]]
-
---add texture coords support?
-
-local widgetVersion = 9
-local LAM = LibStub("LibAddonMenu-2.0")
-if not LAM:RegisterWidget("texture", widgetVersion) then return end
-
-local wm = WINDOW_MANAGER
-
-local MIN_HEIGHT = 26
-function LAMCreateControl.texture(parent, textureData, controlName)
-    local control = LAM.util.CreateBaseControl(parent, textureData, controlName)
-    local width = control:GetWidth()
-    control:SetResizeToFitDescendents(true)
-
-    if control.isHalfWidth then --note these restrictions
-        control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
-    else
-        control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
-    end
-
-    control.texture = wm:CreateControl(nil, control, CT_TEXTURE)
-    local texture = control.texture
-    texture:SetAnchor(CENTER)
-    texture:SetDimensions(textureData.imageWidth, textureData.imageHeight)
-    texture:SetTexture(textureData.image)
-
-    if textureData.tooltip then
-        texture:SetMouseEnabled(true)
-        texture.data = {tooltipText = LAM.util.GetStringFromValue(textureData.tooltip)}
-        texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
-        texture:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
-    end
-
-    return control
-end
diff --git a/DailyAutoShare/libs/LibCustomTitles/LibCustomTitles.lua b/DailyAutoShare/libs/LibCustomTitles/LibCustomTitles.lua
deleted file mode 100644
index 441c396..0000000
--- a/DailyAutoShare/libs/LibCustomTitles/LibCustomTitles.lua
+++ /dev/null
@@ -1,563 +0,0 @@
---[[
-Author: Ayantir
-Filename: LibCustomTitles.lua
-Version: 20
-]]--
-
---[[
-
-This software is under : CreativeCommons CC BY-NC-SA 4.0
-Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
-
-You are free to:
-
-    Share — copy and redistribute the material in any medium or format
-    Adapt — remix, transform, and build upon the material
-    The licensor cannot revoke these freedoms as long as you follow the license terms.
-
-
-Under the following terms:
-
-    Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
-    NonCommercial — You may not use the material for commercial purposes.
-    ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
-    No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
-
-
-Please read full licence at :
-http://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
-
-]]--
-
-local libLoaded
-local LIB_NAME, VERSION = "LibCustomTitles", 20
-local LibCustomTitles, oldminor = LibStub:NewLibrary(LIB_NAME, VERSION)
-if not LibCustomTitles then return end
-
-function LibCustomTitles:Init()
-
-	local CT_NO_TITLE = 0
-	local CT_TITLE_ACCOUNT = 1
-	local CT_TITLE_CHARACTER = 2
-
-	-- Default override
-	local overriden = {
-		en = "Volunteer",
-		fr = "Volontaire",
-		de = "Freiwillige",
-	}
-
-	local customTitles = {
-
-		["@Ayantir"] = { -- Dev / EU. v1
-			ov = true,
-			en = "The Enlightened",
-			fr = "Mangeuse de Gâteaux",
-			de = "Die Erleuchtete",
-		},
-
-		["@Baertram"] = { -- Dev / EU. v4
-			ov = true,
-			en = "Ursa Major",
-			fr = "Ursa Major",
-			de = "Ursa Major",
-		},
-
-		["@sirinsidiator"] = { -- Dev / EU. v5
-			["Illonia Ithildû"] = {
-				ov = true,
-				en = "Planeswalker",
-				fr = "Arpenteuse de Mondes",
-				de = "Weltenwanderer",
-			},
-			ov = true,
-			en = "Absolutely Not Suspicious",
-			fr = "Carrément pas suspect",
-			de = "Absolut Nicht Verdächtig",
-		},
-
-		["@Randactyl"] = { -- Dev / NA. v6
-			["Vedrasi Rilim"] = {
-				ov = true,
-				en = "Glorious Leader",
-			},
-			ov = true,
-			en = "No Lollygaggin'",
-		},
-
-		["@Wedgez"] = { -- NA. v8
-			ov = true,
-			en = "Golden Light Master",
-		},
-
-		["@Ign0tus"] = { -- NA. v8
-			["Smudgê"] = {
-				ov = true,
-				en = "Infiltrator",
-			},
-			["Nefandus Pravus"] = {
-				ov = true,
-				en = "Nightlord",
-			},
-			["Zero Divisor"] = {
-				ov = true,
-				en = "Executioner",
-			},
-			ov = true,
-			en = "Sweetroll Thief",
-		},
-
-		["@dOpiate"] = { -- Dev / EU. v8
-			["Harmful"] = {
-				ov = {en = "Recruit", fr = "Recrue", de = "Rekrutin"},
-				en = "The Butcher",
-				fr = "Le Boucher",
-				de = "Der Metzger",
-			},
-		},
-
-		["@LadyHermione"] = { -- NA v9
-			["Lady Hermione Sophia"] = {
-				ov = true,
-				en = "Know-It-All",
-			},
-		},
-
-		["@Tarsalterror"] = { -- NA v9
-			ov = {en = "Enemy of Coldharbour", fr = "Ennemi de Havreglace", de = "Feind Kalthafens"},
-			en = "Fancy Man of Cornwood",
-		},
-
-		["@manavortex"] = { -- EU v10 (v12 changes)
-			["Vivicah Telvanni"] = {
-				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meisterin der Zauberei"},
-				en = "Archmagister",
-				fr = "Archimage",
-				de = "Erzmagister",
-			},
-			["Sugar-Paws Underfoot"] = {
-				ov = true,
-				en = "Favorite Apprentice",
-				fr = "Apprenti préféré",
-				de = "Lieblingslehrling",
-			},
-			["Ravani Indoril"] = {
-				ov = true,
-				en = "Warden",
-				fr = "Sentinelle",
-				de = "Aufseher",
-			},
-			["Telvanni Ravani Varo"] = {
-				ov = true,
-				en = "Warden",
-				fr = "Sentinelle",
-				de = "Aufseher",
-			},
-		},
-
-		["@Valorin"] = { -- EU v10
-			["Valorin Telvanni"] = {
-				ov = {en = "Savior of Nirn", fr = "Sauveur de Nirn", de = "Retter Nirns"},
-				en = "Aetherial Blade",
-				fr = "Lame Ethérée",
-				de = "Ätherklinge",
-			},
-			["Nathyn Varo"] = {
-				ov = true,
-				en = "Warden",
-				fr = "Sentinelle",
-				de = "Aufseher",
-			},
-		},
-
-		["@Manorin"] = { -- EU v10 (v12 fix)
-			["Foryn Telvanni"] = {
-				ov = {en = "Pact Hero", fr = "Héros du Pacte", de = "Held des Paktes"},
-				en = "Hero",
-				fr = "Héros",
-				de = "Helt",
-			},
-			["Serjo Vivicah Telvanni"] = {
-				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meisterin der Zauberei"},
-				en = "Archmagister",
-				fr = "Archimage",
-				de = "Erzmagister",
-			},
-		},
-
-		["@Chivana"] = { -- EU v11
-			["Chivana"] = {
-				ov = true,
-				en = "Amazon Queen",
-				fr = "Reine Amazone",
-				de = "Amazonaskönigin",
-			},
-		},
-
-		["@Mythk"] = { -- NA v11
-			ov = {en = "Recruit", fr = "Recrue", de = "Rekrutin"},
-			en = "The One and Only",
-			fr = "Le Seul et l'Unique",
-		},
-
-		["@susmitds"] = { -- NA. v11
-			["Shadow Kitter"] = {
-				ov = true,
-				en = "Emperor Slayer",
-			},
-			["Venom Kitter"] = {
-				ov = true,
-				en = "Poison Angel",
-			},
-			["Wind Kitter"] = {
-				ov = true,
-				en = "Cyclone Walker",
-			},
-			["Lumina Kitter"] = {
-				ov = true,
-				en = "Darklight Seeker",
-			},
-			["Thunder Xyler"] = {
-				ov = true,
-				en = "Unbound Infinium",
-			},
-			["Light Xyler"] = {
-				ov = true,
-				en = "Everglow Hunter",
-			},
-			["Fire Xyler"] = {
-				ov = true,
-				en = "Eternal Inferno",
-			},
-			["Void Xyler"] = {
-				ov = true,
-				en = "Existential Anomaly",
-			},
-		},
-
-		["@JasminTheSecond"] = { -- EU v11
-			["Durac"] = {
-				ov = true,
-				en = "The Lost",
-				fr = "L'égaré",
-				de = "Der Verschollene",
-			},
-		},
-
-		["@Haunted1994"] = { -- v12
-			["Jah'rakal"] = {
-				ov = {en = "Veteran", fr = "Vétéran", de = "Veteran"},
-				en = "Troll Warlord",
-				fr = "Troll Warlord",
-				de = "Troll Warlord",
-			},
-		},
-
-		["@Vortexman11"] = { -- v12
-			["Ålaunus"] = {
-				ov = true,
-				en = "The Silent",
-				fr = "Le Discret",
-				de = "Die Stille",
-			},
-		},
-
-		["@Domardal"] = { -- v12
-			ov = true,
-			en = "Coco",
-			fr = "Coco",
-			de = "Coco",
-		},
-
-		["@RaddyBK"] = { -- v12
-			["Radolfus"] = {
-				ov = {en = "Major", fr = "Major", de = "Major"},
-				en = "The Elder Dragon",
-				fr = "Le Vieux Dragon",
-				de = "The Elder Dragon",
-			},
-			["RADOLFUS II"] = {
-				ov = {en = "Executioner", fr = "Exécuteur", de = "Henker"},
-				en = "The Elder Dragon",
-				fr = "Le Vieux Dragon",
-				de = "The Elder Dragon",
-			},
-		},
-
-		["@Dolgubon"] = { -- v12
-			["Relthion"] = {
-				ov = true,
-				en = "Undying",
-				fr = "L'immortel",
-				de = "Undying",
-			},
-		},
-
-		["@Sethize"] = { -- EU v12
-			["Nelvan Telvanni"] = {
-				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meister der Zauberei"},
-				en = "Master",
-				fr = "Maître",
-				de = "Meister",
-			},
-		},
-
-		["@ScattyThePirate"] = { -- EU v13
-			["Teldryn Dreth"] = {
-				ov = true,
-				en = "Warden",
-				fr = "Sentinelle",
-				de = "Aufseher",
-			},
-			["Ralyn Telvanni"] = {
-				ov = true,
-				en = "Spellwright",
-				fr = "Tisseur de Sorts",
-				--de = "Meister",
-			},
-			["Shabar-Jo"] = {
-				ov = true,
-				en = "Tisseur de Sorts",
-				fr = "Spellwright",
-				--de = "Meister",
-			},
-			["Shurkul gro-Kharzog"] = {
-				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
-				en = "The Monster",
-				fr = "La Bête",
-				de = "Das Monster",
-			},
-			["Azuk gro-Shakh"] = {
-				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
-				en = "Windsinger",
-				fr = "Ténor des tempêtes",
-				--de = "Das Monster",
-			},
-			["Xal-Shei"] = {
-				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
-				en = "Swamp Knight",
-				fr = "Chevalier des Marais",
-				--de = "Das Monster",
-			},
-		},
-
-		["@ScattyTheWizard"] = { -- v13
-			["Marukh-do"] = {
-				ov = true,
-				en = "Privateer",
-				fr = "Corsaire",
-				--de = "Meister",
-			},
-		},
-
-		["@Karstyll"] = { -- v13
-			ov = true,
-			en = "Forsaken",
-			fr = "L'oublié",
-			de = "Die Verlassene",
-		},
-
-		["@Methuselah86"] = { -- v13
-			ov = true,
-			en = "Wabbajack Warrior",
-			fr = "Guerrier de Wabbajack",
-			--de = "Die Verlassene",
-		},
-
-		["@DaedricAdept"] = { -- v14
-			ov = {en = "Pact Hero", fr = "Héros du Pacte", de = "Held des Paktes"},
-			en = "Hand of Almalexia",
-			fr = "Main d'Almalexia",
-			--de = "Die Verlassene",
-		},
-
-		["@Cloudless"] = { -- v14
-			ov = true,
-			en = "Order of Doctrine",
-			fr = "Ordre de la Doctrine",
-			--de = "Die Verlassene",
-		},
-
-		["@Atomkern"] = { -- v13
-			ov = true,
-			en = "The Refrigerator",
-			fr = "Le glacé",
-			--de = "Die Verlassene",
-		},
-
-		["@Orizonta"] = { -- v13
-			ov = true,
-			en = "Manslayer",
-			fr = "Assassin",
-			--de = "Die Verlassene",
-		},
-
-		["@laksikus"] = { -- v13
-			ov = {en = "Veteran", fr = "Vétéran", de = "Veteran"},
-			en = "Sexy Zogger",
-			fr = "Zog-Zog",
-			--de = "Die Verlassene",
-		},
-
-		["@flyty"] = { -- v13
-			ov = true,
-			en = "Always Drunk",
-			fr = "Toujours bourré",
-			--de = "Die Verlassene",
-		},
-
-		["@Deltia"] = { -- v13
-			ov = {en = "Tyro", fr = "Première classe", de = "Tyro"},
-			en = "The Destroyer",
-			fr = "Le Destructeur",
-			--de = "Die Verlassene",
-		},
-
-		["@tannips"] = { -- v13
-			ov = true,
-			en = "Potentate",
-			fr = "Potentat",
-			--de = "Die Verlassene",
-		},
-
-		["@sioniann"] = { -- v13
-			["Uloth The Furious Blade"] = {
-				ov = true,
-				en = "Sinister Turkey",
-				fr = "Dindon Sinistre",
-				--de = "Meister",
-			},
-			["Enid an Gleana"] = {
-				ov = true,
-				en = "Fountain of Auridon",
-				fr = "Fontaine d'Auridia",
-				--de = "Meister",
-			},
-		},
-
-		["@HMS-Dragonfly"] = { -- v16
-			ov = true,
-			en = "Knight of Stendarr",
-			fr = "Chevalier de Stendarr",
-			--de = "Die Verlassene",
-		},
-
-		["@Faso"] = { -- v16
-			["Fasò"] = {
-				ov = true,
-				en = "Knights Radiant",
-			},
-		},
-
-		["@nifty2g"] = { -- v16
-			["Nifty Jong-Un"] = {
-				ov = true,
-				en = "Dawn of Anu",
-			},
-		},
-
-		["@Twirlz"] = { -- v17
-			["Yirel Virith"] = {
-				ov = true,
-				en = "Nightcaller",
-			},
-		},
-
-		["@Anceane"] = { -- v19
-			ov = true,
-			en = "Dark Emerald",
-			fr = "Emeraude Sombre",
-		},
-
-		["@Potato-Salad"] = { -- v19
-			ov = true,
-			en = "Seraphim of Azura",
-			fr = "Séraphin d'Azura",
-		},
-
-		["@blakeblox"] = { -- v19
-			["fyboba"] = {
-				ov = {en = "Tyro", fr = "Première classe", de = "Tyro"},
-				en = "Golden Lady",
-			},
-		},
-
-	}
-
-	local lang = GetCVar("Language.2")
-
-	local function GetCustomTitleType(displayName, unitName)
-		if customTitles[displayName] then
-			if customTitles[displayName][unitName] then
-				return CT_TITLE_CHARACTER
-			end
-			return CT_TITLE_ACCOUNT
-		end
-		return CT_NO_TITLE
-	end
-
-	local function GetModifiedTitle(originalTitle, displayName, unitName, registerType)
-
-		local title = originalTitle
-		if registerType == CT_TITLE_CHARACTER then
-			if customTitles[displayName][unitName].ov then
-				if type(customTitles[displayName][unitName].ov) == "boolean" then
-					if originalTitle == overriden[lang] then
-						title = customTitles[displayName][unitName][lang] or originalTitle
-					end
-				elseif originalTitle == customTitles[displayName][unitName].ov[lang] then
-					title = customTitles[displayName][unitName][lang] or originalTitle
-				end
-			end
-		elseif registerType == CT_TITLE_ACCOUNT then
-			if customTitles[displayName].ov then
-				if type(customTitles[displayName].ov) == "boolean" then
-					if originalTitle == overriden[lang] then
-						title = customTitles[displayName][lang] or originalTitle
-					end
-				elseif originalTitle == customTitles[displayName].ov[lang] then
-					title = customTitles[displayName][lang] or originalTitle
-				end
-			end
-		end
-
-		return title
-
-	end
-
-	local GetUnitTitle_original = GetUnitTitle
-	GetUnitTitle = function(unitTag)
-		local unitTitleOriginal = GetUnitTitle_original(unitTag)
-		local unitDisplayName = GetUnitDisplayName(unitTag)
-		local unitCharacterName = GetUnitName(unitTag)
-		local registerType = GetCustomTitleType(unitDisplayName, unitCharacterName)
-		if registerType ~= CT_NO_TITLE then
-			return GetModifiedTitle(unitTitleOriginal, unitDisplayName, unitCharacterName, registerType)
-		end
-		return unitTitleOriginal
-	end
-
-	local GetTitle_original = GetTitle
-	GetTitle = function(index)
-		local titleOriginal = GetTitle_original(index)
-		local displayName = GetDisplayName()
-		local characterName = GetUnitName("player")
-		local registerType = GetCustomTitleType(displayName, characterName)
-		if registerType ~= CT_NO_TITLE then
-			return GetModifiedTitle(titleOriginal, displayName, characterName, registerType)
-		end
-		return titleOriginal
-	end
-
-end
-
-local function OnAddonLoaded()
-	if not libLoaded then
-		libLoaded = true
-		local LCC = LibStub('LibCustomTitles')
-		LCC:Init()
-		EVENT_MANAGER:UnregisterForEvent(LIB_NAME, EVENT_ADD_ON_LOADED)
-	end
-end
-
-EVENT_MANAGER:RegisterForEvent(LIB_NAME, EVENT_ADD_ON_LOADED, OnAddonLoaded)
\ No newline at end of file
diff --git a/DailyAutoShare/libs/LibStub/LibStub.lua b/DailyAutoShare/libs/LibStub/LibStub.lua
deleted file mode 100644
index 0e6bf67..0000000
--- a/DailyAutoShare/libs/LibStub/LibStub.lua
+++ /dev/null
@@ -1,38 +0,0 @@
--- 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
--- LibStub developed for World of Warcraft by above members of the WowAce community.
--- Ported to Elder Scrolls Online by Seerah
-
-local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 4
-local LibStub = _G[LIBSTUB_MAJOR]
-
-local strformat = string.format
-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)")
-		if type(minor) ~= "number" then
-			minor = assert(tonumber(zo_strmatch(minor, "%d+%.?%d*")), "Minor version must either be a number or contain a number.")
-		end
-
-		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(strformat("Cannot find a library instance of %q.", 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
-
-LibStub.SILENT = true
\ No newline at end of file
diff --git a/DailyAutoShare/locale/de.lua b/DailyAutoShare/locale/de.lua
deleted file mode 100644
index 5f6ee3b..0000000
--- a/DailyAutoShare/locale/de.lua
+++ /dev/null
@@ -1,179 +0,0 @@
-DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
-
-local strings  = {
-
-
-	DAS_SI_INVITE_TRUE 		= "Automatisches Einladen: Aktiviert",
-	DAS_SI_INVITE_FALSE 	= "Automatisches Einladen: Deaktiviert",
-	DAS_SI_ACCEPT_TRUE 		= "Geteilte Quests werden automatisch akzeptiert",
-	DAS_SI_ACCEPT_FALSE 	= "Geteilte Quests werden nicht automatisch akzeptiert",
-	DAS_SI_SHARE_TRUE 		= "Teilt deine aktiven Quests jedes Mal, wenn ein neues Gruppenmitglied dazukommt, oder wenn jemand 'share' oder 'quest' in den Gruppenchat schreibt\nRechtsklick um alle Quests zu teilen",
-	DAS_SI_SHARE_FALSE 		= "Automatisches Teilen deaktiviert",
-	DAS_SI_SPAM 			= "Klicken, um in den Chat zu spammen",
-	DAS_SI_SPAM_VERBOSE 	= "Klicken, um nach Quests zu fragen",
-
-	DAS_SI_HIDE		 		= "DailyAutoShare ausblenden",
-
-	DAS_SI_TOGGLE	 		= "Toggle hidden",
-	DAS_SI_MINIMISE	 		= "Toggle minimised",
-
-	DAS_SI_DONATE	 		=  "Klicken für ein Dankeschön:\nLinks: 2k\nRechts: 10k\nMitte: 25k\nIch freue mich  über Feedback und/oder Spenden! :)",
-
-	DAS_SI_SHARE	 		= "Teilen",
-	DAS_SI_TRACK	 		= "* Verfolgen",
-	DAS_SI_ABANDON	 		= "|cFF0000Abbrechen|r",
-	DAS_SI_SPAM_SINGLE	 	= "Spammen",
-	DAS_SI_REFRESH	 		="Aktualisieren",
-
-
-	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
-	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
-
-
-	-- Clockwork City
-	DAS_CLOCK_IMP		 = "Das Reizen des Unvollendeten",
-	DAS_CLOCK_FOE		 = "Ein feingefiederter Feind",
-
-    -- Clockwork City
-	DAS_CLOCK_BOSS_START	 = "I'll take on a contract.",
-	DAS_CLOCK_CRAFT_START    = "Got any work?",
-	DAS_CLOCK_CAVE_START     = "What's the job?",
-	DAS_CLOCK_CROW_START     = "How can I help?",
-
-	DAS_CLOCK_CRAFT_CLOTH	 = "Lose Fasern",
-	DAS_CLOCK_CRAFT_WATER	 = "Eine klebrige Lösung",
-	DAS_CLOCK_CRAFT_RUNE	 = "Verzauberte Ansammlung",
-	DAS_CLOCK_CRAFT_SMITH	 = "Das tägliche Zermahlen",
-	DAS_CLOCK_CRAFT_ALCH	 = "Eine bittere Pille",
-	DAS_CLOCK_CRAFT_WOOD	 = "Brennstoff für unsere Feuer",
-
-	DAS_CLOCK_DELVE_FILT	 = "Filterwechsel",
-	DAS_CLOCK_DELVE_FANS	 = "Die Ventilatoren ölen",
-	DAS_CLOCK_DELVE_COMM	 = "Gleichrichterersatz",
-	DAS_CLOCK_DELVE_MALF	 = "Eine schattige Fehlfunktion",
-	DAS_CLOCK_DELVE_MISP	 = "Ein verlegter Schatten",
-	DAS_CLOCK_DELVE_AGAI	 = "Zurück in die Schatten",
-
-	DAS_CLOCK_CROW_GLIT		 = "Glitzern und Funkeln",
-	DAS_CLOCK_CROW_TRIB		 = "Eine Frage des Tributs",
-	DAS_CLOCK_CROW_NIBB		 = "Stückchen und Häppchen",
-	DAS_CLOCK_CROW_MORS		 = "Bröckchen und Bisschen",
-	DAS_CLOCK_CROW_RESP		 = "Eine Frage des Respekts",
-	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
-
-	-- Morrowind dailies
-	DAS_M_REL_ASHAL =  "Relikte von Ashalmawia",
-	DAS_M_REL_ASSAR =  "Relikte von Assarnatamat",
-	DAS_M_REL_ASHUR =  "Relikte von Ashurnabitashpi",
-	DAS_M_REL_DUSHA =  "Relikte von Dushariran",
-	DAS_M_REL_EBERN =  "Relikte von Ebernanit",
-	DAS_M_REL_MAELK =  "Relikte von Maelkashishi",
-	DAS_M_REL_YASAM =  "Relikte von Yasammidan",
-
-	DAS_M_HUNT_EATER =  "Jagd auf Aschfresser",
-	DAS_M_HUNT_ZEXXI =  "Jagd auf den großen Zexxin",
-	DAS_M_HUNT_RAZOR =  "Jagd auf König Klingenhauer",
-	DAS_M_HUNT_JAGGE =  "Jagd auf Mutter Zackige-Klaue",
-	DAS_M_HUNT_STOMP =  "Jagd auf den alten Stampfer",
-	DAS_M_HUNT_TARRA =  "Jagd auf Tarra-Suj",
-	DAS_M_HUNT_SVEET =  "Jagd auf den sich windenden Sveeth",
-
-	-- Cave dailies (Hall of Justice)
-	DAS_M_DELVE_DAEDR =  "Daedrische Störungen",
-	DAS_M_DELVE_KWAMA =  "Quatsch mit Kwama",
-	DAS_M_DELVE_MISIN =  "Das Streuen von Fehlinformationen",
-	DAS_M_DELVE_TAXES =  "Steuerabzug",
-	DAS_M_DELVE_TRIBA =  "Stammessorgen",
-	DAS_M_DELVE_SYNDI =  "Ein Syndikat in Unruhe",
-
-	-- World boss dailies (Hall of Justice)
-	DAS_M_BOSS_WUYWU        =  "Ein schleichender Hunger",
-	DAS_M_BOSS_SWARM        =  "Das Ausdünnen des Schwarms",
-	DAS_M_BOSS_NILTH        =  "Frei laufende Ochsen",
-	DAS_M_BOSS_SALOT        =  "Salothans Fluch",
-	DAS_M_BOSS_SIREN        =  "Sirenensang",
-	DAS_M_BOSS_APPRE        =  "Der besorgte Lehrling",
-
-
-	-- wrothgar dailies
-    DAS_W_POACHERS        = "Fleisch für die Massen",
-    DAS_W_EDU             = "So riecht ein falsches Spiel",
-	DAS_W_NYZ             = "Schnee und Dampf",
-    DAS_W_CORI            = "Die Gabe der Natur",
-    DAS_W_DOLMEN       	  = "Der Frevel des Unwissens",
-    DAS_W_OGRE            = "Gelehrtes Bergungsgut",
-
-	-- wrothgar single
-	DAS_W_HARPIES 		    = "Ein bizarres Frühstück",
-	DAS_W_SPIRITS 		    = "Freie Geister",
-	DAS_W_DURZOGS 		    = "Der volle Bauch",
-	DAS_W_DWEMER 		    = "Teile des Ganzen",
-	DAS_W_WEREWOLVES	    = "Das Geschäft mit der Haut",
-	DAS_W_THAT_OTHER	    = "Feuer in der Feste",
-
-
-	-- gold coast
-	DAS_DB_MINO			    = "Drohende Schatten",
-	DAS_DB_ARENA 		    = "Das Jubeln der Menge",
-	DAS_DB_GOOD 		    = "Das Gemeinwohl",
-	DAS_DB_EVIL 		    = "Das Übel unter der Erde",
-
-	-- new life
-	DAS_NL_STORMHAVEN	    = "Burgbardenherausforderung",
-	DAS_NL_STONEFALLS	    = "Lavafußstampfer",
-	DAS_NL_ALIKR		    = "Signalfeuersprint",
-	DAS_NL_SHADOWFEN	    = "Fischgunstfestmahl",
-	DAS_NL_GRAHTWOOD	    = "Kriegsweisenreise",
-	DAS_NL_REAPERSMARCH	    = "Prüfung der Fünfkrallenlist",
-	DAS_NL_BETNIKH		    = "Steinzahnsause",
-	DAS_NL_AURIDON		    = "Schlammballspiele",
-	DAS_NL_EASTMARCH	    = "Schneebärensprung",
-
-	-- craglorn
-	-- lower
-	DAS_CRAG_SARA 		 = "Kritische Masse",
-	DAS_CRAG_SHADA 		 = "Die gefallene Stadt Shada",
-	DAS_CRAG_NEDE 		 = "Der Grund für unseren Kampf",	-- this is not a single daily, it's part off The fallen City of Shada
-	DAS_CRAG_HERMY 		 = "Das Archiv des Suchers",
-	DAS_CRAG_ELINHIR 	 = "Unbeschreibliche Macht",
-	DAS_CRAG_TUWHACCA 	 = "Die Prüfungen von Rahni’Za",
-	DAS_CRAG_NEREID 	 = "Wenn das Wasser giftig wird",	-- this is not a single daily, it's part off The fallen City of Shada
-
-	-- upper
-	DAS_CRAG_NIRNCRUX	 = "Das Blut Nirns",
-	DAS_CRAG_WORLDTRIP 	 = "Der graue Lauf",
-	DAS_CRAG_SCALES 	 = "Eisen und Schuppen",
-	DAS_CRAG_NECRO 		 = "Die Seelen der Verratenen",
-	DAS_CRAG_KIDNAP 	 = "Lebendig gefangen",
-	DAS_CRAG_HITMAN 	 = "Die wahren Giftzähne",
-	DAS_CRAG_DUNGEON 	 = "Entfesselt",
-
-
-    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
-    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
-
-    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
-    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
-    DAS_QUEST_CC_NOVICE     = "Novice Holli",
-    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
-    DAS_QUEST_CC_DARO       = "Adjunct Daro",
-    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
-
-    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
-    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
-
-    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
-
-    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
-
-    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
-
-
-
-}
-DAS_STRINGS_LOCALE.de = strings
-
-for stringId, stringValue in pairs(strings) do
-	ZO_CreateStringId(stringId, stringValue)
-	SafeAddVersion(stringId, 2)
-end
\ No newline at end of file
diff --git a/DailyAutoShare/locale/en.lua b/DailyAutoShare/locale/en.lua
deleted file mode 100644
index 60fab5c..0000000
--- a/DailyAutoShare/locale/en.lua
+++ /dev/null
@@ -1,212 +0,0 @@
-DailyAutoShare = DailyAutoShare or {}
-DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
-local strings  = {
-	-- UI stuffs
-	DAS_SI_INVITE_TRUE 		= "Invite is now on",
-	DAS_SI_INVITE_FALSE 	= "Invite is now off",
-	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
-	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
-	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
-	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
-	DAS_SI_SPAM 			= "Click to spam in zone chat",
-	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
-
-	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
-	DAS_SI_TOGGLE	 		= "Toggle hidden",
-	DAS_SI_MINIMISE	 		= "Toggle minimised",
-	DAS_SI_REFRESH	 		= "Refresh",
-
-	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
-
-	DAS_SI_SHARE	 		= "Share",
-	DAS_SI_TRACK	 		= "* Track",
-	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
-	DAS_SI_SPAM_SINGLE	 	= "Spam",
-	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
-	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
-
-	-- Clockwork City
-	DAS_CLOCK_IMP			 = "Inciting the Imperfect",
-	DAS_CLOCK_FOE			 = "A Fine-Feathered Foe",
-
-
-	DAS_CLOCK_CRAFT_CLOTH	 = "Loose Strands",
-	DAS_CLOCK_CRAFT_WATER	 = "A Sticky Solution",
-	DAS_CLOCK_CRAFT_RUNE	 = "Enchanted Accumulation",
-	DAS_CLOCK_CRAFT_SMITH	 = "A Daily Grind",
-	DAS_CLOCK_CRAFT_ALCH	 = "A Bitter Pill",
-	DAS_CLOCK_CRAFT_WOOD	 = "Fuel for our Fires",
-
-	DAS_CLOCK_DELVE_FILT	 = "Changing the Filters",
-	DAS_CLOCK_DELVE_FANS	 = "Oiling the Fans",
-	DAS_CLOCK_DELVE_COMM	 = "Replacing the Commutators",
-	DAS_CLOCK_DELVE_MALF	 = "A Shadow Malfunction",
-	DAS_CLOCK_DELVE_MISP	 = "A Shadow Misplaced",
-	DAS_CLOCK_DELVE_AGAI	 = "Again Into the Shadows",
-
-	DAS_CLOCK_CROW_GLIT		 = "Glitter and Gleam",
-	DAS_CLOCK_CROW_TRIB		 = "A Matter of Tributes",
-	DAS_CLOCK_CROW_NIBB		 = "Nibbles and Bits",
-	DAS_CLOCK_CROW_MORS		 = "Morsels and Pecks",
-	DAS_CLOCK_CROW_RESP		 = "A Matter of Respect",
-	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
-
-	-- Morrowind dailies
-	DAS_M_REL_ASHAL          =  "Relics of Ashalmawia",
-	DAS_M_REL_ASSAR          =  "Relics of Assarnatamat",
-	DAS_M_REL_ASHUR          =  "Relics of Ashurnabitashpi",
-	DAS_M_REL_DUSHA          =  "Relics of Dushariran",
-	DAS_M_REL_EBERN          =  "Relics of Ebernanit",
-	DAS_M_REL_MAELK          =  "Relics of Maelkashishi",
-	DAS_M_REL_YASAM          =  "Relics of Yasammidan",
-
-	DAS_M_HUNT_EATER         =  "Ash-Eater Hunt",
-	DAS_M_HUNT_ZEXXI         =  "Great Zexxin Hunt",
-	DAS_M_HUNT_RAZOR         =  "King Razor-Tusk Hunt",
-	DAS_M_HUNT_JAGGE         =  "Mother Jagged-Claw Hunt",
-	DAS_M_HUNT_STOMP         =  "Old Stomper Hunt",
-	DAS_M_HUNT_TARRA         =  "Tarra-Suj Hunt",
-	DAS_M_HUNT_SVEET         =  "Writhing Sveeth Hunt",
-
-	-- World boss dailies (Hall of Justice)
-	DAS_M_BOSS_WUYWU         =  "A Creeping Hunger",
-	DAS_M_BOSS_SWARM         =  "Culling the Swarm",
-	DAS_M_BOSS_NILTH         =  "Oxen Free",
-	DAS_M_BOSS_SALOT         =  "Salothan's Curse",
-	DAS_M_BOSS_SIREN         =  "Siren's Song",
-	DAS_M_BOSS_APPRE         =  "The Anxious Apprentice",
-
-	-- Cave dailies (Hall of Justice)
-	DAS_M_DELVE_DAEDR        =  "Daedric Disruptions",
-	DAS_M_DELVE_KWAMA        =  "Kwama Conundrum",
-	DAS_M_DELVE_MISIN        =  "Planting Misinformation",
-	DAS_M_DELVE_TAXES        =  "Tax Deduction",
-	DAS_M_DELVE_TRIBA        =  "Tribal Troubles",
-	DAS_M_DELVE_SYNDI        =  "Unsettled Syndicate",
-
-	-- wrothgar dailies
-    DAS_W_POACHERS          = "Meat for the Masses",
-    DAS_W_EDU               = "Reeking of Foul Play",
-    DAS_W_NYZ               = "Snow and Steam",
-    DAS_W_CORI              = "Nature's Bounty",
-    DAS_W_DOLMEN            = "Heresy of Ignorance",
-    DAS_W_OGRE              = "Scholarly Salvage",
-
-	-- wrothgar single
-	DAS_W_HARPIES 		    = "Breakfast of the Bizarre",
-	DAS_W_SPIRITS 		    = "Free Spirits",
-	DAS_W_DURZOGS 		    = "Getting a Bellyful",
-	DAS_W_DWEMER 		    = "Parts of the Whole",
-	DAS_W_WEREWOLVES	    = "The Skin Trade",
-	DAS_W_THAT_OTHER	    = "Fire in the Hold",
-
-
-	-- gold coast
-	DAS_DB_MINO			    = "Looming Shadows",
-	DAS_DB_ARENA 		    = "The Roar of the Crowds",
-	DAS_DB_GOOD 		    = "The Common Good",
-	DAS_DB_EVIL 		    = "Buried Evil",
-
-	-- new life
-	DAS_NL_STORMHAVEN	    = "Castle Charm Challenge",
-	DAS_NL_STONEFALLS	    = "Lava Foot Stomp",
-	DAS_NL_ALIKR		    = "Signal Fire Sprint",
-	DAS_NL_SHADOWFEN	    = "Fish Boon Feast",
-	DAS_NL_GRAHTWOOD	    = "War Orphan's Sojourn",
-	DAS_NL_REAPERSMARCH	    = "The Trial of Five-Clawed Guile",
-	DAS_NL_BETNIKH		    = "Stonetooth Bash",
-	DAS_NL_AURIDON		    = "Mud Ball Merriment",
-	DAS_NL_EASTMARCH	    = "Snow Bear Plunge",
-
-	-- craglorn
-	-- lower
-	DAS_CRAG_SARA 		    = "Critical Mass",
-	DAS_CRAG_SHADA 		    = "The Fallen City of Shada",
-	DAS_CRAG_NEDE 		    = "The Reason We Fight",
-	DAS_CRAG_HERMY 		    = "The Seeker’s Archive",
-	DAS_CRAG_ELINHIR 	    = "Supreme Power",
-	DAS_CRAG_TUWHACCA 	    = "The Trials of Rahni’Za",
-	DAS_CRAG_NEREID 	    = "Waters Run Foul",
-
-	-- upper
-	DAS_CRAG_NIRNCRUX	    = "The Blood of Nirn",
-	DAS_CRAG_WORLDTRIP 	    = "The Gray Passage",
-	DAS_CRAG_SCALES 	    = "Iron and Scales",
-	DAS_CRAG_NECRO 		    = "Souls of the Betrayed",
-	DAS_CRAG_KIDNAP 	    = "Taken Alive",
-	DAS_CRAG_HITMAN 	    = "The Truer Fangs",
-	DAS_CRAG_DUNGEON 	    = "Uncaged",
-
-
-    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
-    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
-
-    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
-    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
-    DAS_QUEST_CC_NOVICE     = "Novice Holli",
-    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
-    DAS_QUEST_CC_DARO       = "Adjunct Daro",
-    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
-
-    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
-    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
-
-    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
-
-    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
-
-    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
-
-    DAS_QUEST_CAP_CARDEA    = "Cardea Gallus",
-    DAS_QUEST_CAP_ALVUR     = "Alvur Baren",
-    DAS_QUEST_CAP_BOLGRUL   = "Bolgrul",
-
-    -- don't need translation for anyone but the russians - I think
-
-    DAS_QUEST_DB_LARONEN    = "Laronen",
-    DAS_QUEST_DB_FINIA      = "Finia Sele",
-    DAS_QUEST_DB_CODUS      = "Codus ap Dugal",
-
-    DAS_QUEST_W_NEDNOR      = "Nednor",
-    DAS_QUEST_W_THAZEK      = "Thazeg",
-    DAS_QUEST_W_ARUSHNA     = "Arushna",
-    DAS_QUEST_W_LILYAMEH    = "Lilyameh",
-    DAS_QUEST_W_BAGRUBESH   = "Bagrugbesh",
-    DAS_QUEST_W_CIRANTILLE  = "Cirantille",
-    DAS_QUEST_W_MENNINIA    = "Menninia",
-    DAS_QUEST_W_SONOLIA     = "Sonolia Muspidius",
-    DAS_QUEST_W_RAYNOR      = "Raynor Vanos", -- maybe not include Raynor?
-
-    DAS_QUEST_M_TRAYLAN     = "Traylan Omoril",
-    DAS_QUEST_M_BELERU      = "Beleru Omoril",
-    DAS_QUEST_M_NUMANI      = "Numani-Rasi",
-    DAS_QUEST_M_NARA        = "Nara Varam",
-    DAS_QUEST_M_TIRVINA     = "Tirvina Avani",
-    DAS_QUEST_M_DINOR       = "Dinor Salvi",
-    DAS_QUEST_M_BRAVOSI     = "Bravosi Felder",
-    DAS_QUEST_M_IVULEN      = "Ivulen Andromo",
-    DAS_QUEST_M_SAVILE      = "Savile Alam",
-    DAS_QUEST_M_KYLIA       = "Kylia Thando",
-    DAS_QUEST_M_EVOS        = "Evos Hledas",
-    DAS_QUEST_M_ALVES       = "Alves Droth",
-    DAS_QUEST_M_DREDASE     = "Dredase-Hlarar",
-    DAS_QUEST_M_VORAR       = "Vorar Vendu",
-    DAS_QUEST_M_VALGA       = "Valga Celatus",
-
-    DAS_QUEST_CC_ORC        = "Razgurug",
-    DAS_QUEST_CC_COOK       = "Aveberl Tremouille",
-    DAS_QUEST_CC_MINDORA    = "Mindora",
-    DAS_QUEST_CC_NJORD      = "Njordemar",
-    DAS_QUEST_CC_IGMUND     = "Igmund",
-
-    DAS_QUEST_W_GURUZUG     = "Guruzug",
-    DAS_QUEST_W_ARZORAG     = "Arzorag",
-
-}
-DailyAutoShare.EnglishQuestNames = strings
-DAS_STRINGS_LOCALE.en = strings
-
-for stringId, stringValue in pairs(strings) do
-	ZO_CreateStringId(stringId, stringValue)
-	SafeAddVersion(stringId, 1)
-end
diff --git a/DailyAutoShare/locale/fr.lua b/DailyAutoShare/locale/fr.lua
deleted file mode 100644
index 4d1e572..0000000
--- a/DailyAutoShare/locale/fr.lua
+++ /dev/null
@@ -1,167 +0,0 @@
-DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
-
-local strings  = {
-
-	DAS_SI_INVITE_TRUE 		= "Invite auto activé",
-	DAS_SI_INVITE_FALSE 	= "Invite auto désactivé",
-	DAS_SI_ACCEPT_TRUE 		= "Accepte automatiquement les quêtes quotidienne partagées",
-	DAS_SI_ACCEPT_FALSE 	= "N'accepte pas automatiquement les quêtes",
-	DAS_SI_SHARE_TRUE 		= "Partager automatiquement votre quête quotidienne active avec le groupe ou 'share' dans le chat de groupe (Clic droit pour partager votre quête active)",
-	DAS_SI_SHARE_FALSE 		= "Ne partage pas votre quête active (Clic droit pour partager)",
-	DAS_SI_SPAM 			= "Clic pour spam dans le chat de zone",
-	DAS_SI_SPAM_VERBOSE 	= "Clic pour demander poliment une part du quest le chat de zone",
-
-	DAS_SI_HIDE		 		= "Cacher DailyAutoShare",
-	DAS_SI_TOGGLE	 		= "Toggle hidden",
-	DAS_SI_MINIMISE	 		= "Toggle minimised",
-	DAS_SI_REFRESH	 		= "Mettre a jour",
-
-	DAS_SI_DONATE	 		= "Clic pour remercier:\nGauche: 2k\nDroit: 10k\nMilieu: 25k\nVos commentaires et/ou don seront apprécié!",
-
-	DAS_SI_SHARE	 		= "Share",
-	DAS_SI_TRACK	 		= "* Track",
-	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
-	DAS_SI_SPAM_SINGLE	 	= "Rechercher cette quête uniquement",
-	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
-	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
-
-	-- Clockwork City
-	DAS_CLOCK_IMP			= "Attirer l'Imparfait",
-	DAS_CLOCK_FOE			= "Un si beau plumage",
-
-	DAS_CLOCK_CRAFT_CLOTH	= "Détails à régler",
-	DAS_CLOCK_CRAFT_WATER	= "La poisse",
-	DAS_CLOCK_CRAFT_RUNE	= "Accumulation enchantée",
-	DAS_CLOCK_CRAFT_SMITH	= "Chaque jour sur le métier",
-	DAS_CLOCK_CRAFT_ALCH	= "Pilule amère",
-	DAS_CLOCK_CRAFT_WOOD	= "Ce qui alimente nos feux",
-
-	DAS_CLOCK_DELVE_FILT	= "Changer les filtres",
-	DAS_CLOCK_DELVE_FANS	= "Graisser les ventilateurs",
-	DAS_CLOCK_DELVE_COMM	= "Remplacer les commutateurs",
-	DAS_CLOCK_DELVE_MALF	= "Une avarie d'ombre",
-	DAS_CLOCK_DELVE_MISP	= "Une ombre égarée",
-	DAS_CLOCK_DELVE_AGAI	= "Retour dans les ombres vertes",
-
-	DAS_CLOCK_CROW_GLIT		= "Lueur et Chatoiement",
-	DAS_CLOCK_CROW_TRIB		= "Une affaire de tributs",
-	DAS_CLOCK_CROW_NIBB		= "Petites bouchées",
-	DAS_CLOCK_CROW_MORS		= "Morceaux de choix",
-	DAS_CLOCK_CROW_RESP		= "Une histoire de respect",
-	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
-
-	-- Morrowind dailies
-	DAS_M_REL_ASHAL 		= "Reliques d'Ashalmawia",
-	DAS_M_REL_ASSAR 		= "Reliques d'Assarnatamat",
-	DAS_M_REL_ASHUR 		= "Reliques d'Ashurnabitashpi",
-	DAS_M_REL_DUSHA 		= "Reliques de Dushariran",
-	DAS_M_REL_EBERN 		= "Reliques d'Ebernanit",
-	DAS_M_REL_MAELK 		= "Reliques de Maelkashishi",
-	DAS_M_REL_YASAM 		= "Reliques de Yasammidan",
-
-	DAS_M_HUNT_EATER 		= "Chasse à Gobe-cendre",
-	DAS_M_HUNT_ZEXXI 		= "Chasse au Grand Zexxin",
-	DAS_M_HUNT_RAZOR 		= "Chasse au Roi Défense-rasoir",
-	DAS_M_HUNT_JAGGE 		= "Mère Griffe-dentelée",
-	DAS_M_HUNT_STOMP 		= "Chasse au vieux piétineur",
-	DAS_M_HUNT_TARRA 		= "Chasse de Tarra-Suj",
-	DAS_M_HUNT_SVEET 		= "Chasse au sveeth ondulant",
-
-	-- Cave dailies (Hall of Justice)
-	DAS_M_DELVE_DAEDR 		= "Perturbations daedriques",
-	DAS_M_DELVE_KWAMA 		= "L'équation kwama",
-	DAS_M_DELVE_MISIN 		= "Plantage à la plantation",
-	DAS_M_DELVE_TAXES 		= "Déduction fiscale",
-	DAS_M_DELVE_TRIBA 		= "Tribus troublées",
-	DAS_M_DELVE_SYNDI 		= "Mouvement syndical",
-
-	-- World boss dailies (Hall of Justice)
-	DAS_M_BOSS_WUYWU 		= "Une faim dévorante",
-	DAS_M_BOSS_SWARM 		= "Réduire le troupeau",
-	DAS_M_BOSS_NILTH 		= "Garanti sans bœuf",
-	DAS_M_BOSS_SALOT 		= "Malédiction de Salothan",
-	DAS_M_BOSS_SIREN 		= "Chant de la sirène",
-	DAS_M_BOSS_APPRE 		= "L'Apprenti anxieux",
-
-	-- wrothgar dailies
-    DAS_W_POACHERS      	= "Nourrir les foules",
-    DAS_W_EDU          		= "L'odeur du crime",
-    DAS_W_NYZ          		= "Neige et vapeur",
-    DAS_W_CORI         		= "Abondance de la nature",
-    DAS_W_DOLMEN       		= "Hérésie par l'ignorance",
-    DAS_W_OGRE           	= "Sauvetage académique",
-
-	-- wrothgar single
-	DAS_W_HARPIES 			= "Petit-déjeuner de l'étrange",
-	DAS_W_SPIRITS 			= "Esprits libres",
-	DAS_W_DURZOGS 			= "Plein la panse !",
-	DAS_W_DWEMER 			= "Parties du tout",
-	DAS_W_WEREWOLVES		= "Commerce de peaux",
-	DAS_W_THAT_OTHER		= "Incendie au fort",
-
-	-- gold coast
-	DAS_DB_MINO				= "Ombres menaçantes",
-	DAS_DB_ARENA 			= "Le hurlement des foules",
-	DAS_DB_EVIL 			= "Mal enfoui",
-	DAS_DB_GOOD 			= "Le bien commun",
-
-	-- new life
-	DAS_NL_STORMHAVEN		= "Castle Charm Challenge",
-	DAS_NL_STONEFALLS		= "Lava Foot Stomp",
-	DAS_NL_ALIKR			= "Signal Fire Sprint",
-	DAS_NL_SHADOWFEN		= "Fish Boon Feast",
-	DAS_NL_GRAHTWOOD		= "War Orphan's Sojourn",
-	DAS_NL_REAPERSMARCH		= "The Trial of Five-Clawed Guile",
-	DAS_NL_BETNIKH			= "Stonetooth Bash",
-	DAS_NL_AURIDON			= "Mud Ball Merriment",
-	DAS_NL_EASTMARCH		= "Snow Bear Plunge",
-
-
-	-- craglorn
-	-- lower
-	DAS_CRAG_SARA 			 = "Masse critique",
-	DAS_CRAG_SHADA 			 = "La cité perdue de Shada",
-	DAS_CRAG_NEDE 			 = "Notre cause",
-	DAS_CRAG_HERMY 			 = "L'Archive des Sourciers",
-	DAS_CRAG_ELINHIR 		 = "Puissance supérieur",
-	DAS_CRAG_TUWHACCA 		 = "Les épreuves de Rahni’Za",
-	DAS_CRAG_NEREID 		 = "Les eaux se troubles",
-
-	-- upper
-	DAS_CRAG_NIRNCRUX		 = "Le sang de Nirn",
-	DAS_CRAG_WORLDTRIP 		 = "Passage gris",
-	DAS_CRAG_SCALES 		 = "Fer et écailles",
-	DAS_CRAG_NECRO 			 = "Les âmes des trahis",
-	DAS_CRAG_KIDNAP 		 = "Capturés vivants",
-	DAS_CRAG_HITMAN 		 = "Les crocs ajustés",
-	DAS_CRAG_DUNGEON 		 = "Libéré",
-
-
-
-    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
-    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
-
-    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
-    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
-    DAS_QUEST_CC_NOVICE     = "Novice Holli",
-    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
-    DAS_QUEST_CC_DARO       = "Adjunct Daro",
-    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
-
-    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
-    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
-
-    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
-
-    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
-
-    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
-
-
-}
-DAS_STRINGS_LOCALE.fr = strings
-
-for stringId, stringValue in pairs(strings) do
-	ZO_CreateStringId(stringId, stringValue)
-	SafeAddVersion(stringId, 2)
-end
\ No newline at end of file
diff --git a/DailyAutoShare/locale/jp.lua b/DailyAutoShare/locale/jp.lua
deleted file mode 100644
index 28f7d9d..0000000
--- a/DailyAutoShare/locale/jp.lua
+++ /dev/null
@@ -1,174 +0,0 @@
-DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
-
-local strings  = {
-	-- UI stuffs
-	DAS_SI_INVITE_TRUE 		= "Invite is now on",
-	DAS_SI_INVITE_FALSE 	= "Invite is now off",
-	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
-	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
-	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
-	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
-	DAS_SI_SPAM 			= "Click to spam in zone chat",
-	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
-
-	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
-	DAS_SI_TOGGLE	 		= "Toggle hidden",
-	DAS_SI_MINIMISE	 		= "Toggle minimised",
-	DAS_SI_REFRESH	 		= "Refresh",
-
-	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
-
-	DAS_SI_SHARE	 		= "Share",
-	DAS_SI_TRACK	 		= "* Track",
-	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
-	DAS_SI_SPAM_SINGLE	 	= "Spam",
-	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
-	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
-
-	-- Clockwork City
-	DAS_CLOCK_IMP			 = "Inciting the Imperfect",
-	DAS_CLOCK_FOE			 = "A Fine-Feathered Foe",
-
-	DAS_CLOCK_CRAFT_CLOTH	 = "Loose Strands",
-	DAS_CLOCK_CRAFT_WATER	 = "A Sticky Solution",
-	DAS_CLOCK_CRAFT_RUNE	 = "Enchanted Accumulation",
-	DAS_CLOCK_CRAFT_SMITH	 = "A Daily Grind",
-	DAS_CLOCK_CRAFT_ALCH	 = "A Bitter Pill",
-	DAS_CLOCK_CRAFT_WOOD	 = "Fuel for our Fires",
-
-	DAS_CLOCK_DELVE_FILT	 = "Changing the Filters",
-	DAS_CLOCK_DELVE_FANS	 = "Oiling the Fans",
-	DAS_CLOCK_DELVE_COMM	 = "Replacing the Commutators",
-	DAS_CLOCK_DELVE_MALF	 = "A Shadow Malfunction",
-	DAS_CLOCK_DELVE_MISP	 = "A Shadow Misplaced",
-	DAS_CLOCK_DELVE_AGAI	 = "Again Into the Shadows",
-
-	DAS_CLOCK_CROW_GLIT		 = "Glitter and Gleam",
-	DAS_CLOCK_CROW_TRIB		 = "A Matter of Tributes",
-	DAS_CLOCK_CROW_NIBB		 = "Nibbles and Bits",
-	DAS_CLOCK_CROW_MORS		 = "Morsels and Pecks",
-	DAS_CLOCK_CROW_RESP		 = "A Matter of Respect",
-	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
-
-
-	-- Morrowind dailies
-	DAS_M_REL_ASHAL =  "Relics of Ashalmawia",
-	DAS_M_REL_ASSAR =  "Relics of Assarnatamat",
-	DAS_M_REL_ASHUR =  "Relics of Ashurnabitashpi",
-	DAS_M_REL_DUSHA =  "Relics of Dushariran",
-	DAS_M_REL_EBERN =  "Relics of Ebernanit",
-	DAS_M_REL_MAELK =  "Relics of Maelkashishi",
-	DAS_M_REL_YASAM =  "Relics of Yasammidan",
-
-	DAS_M_HUNT_EATER =  "Ash-Eater Hunt",
-	DAS_M_HUNT_ZEXXI =  "Great Zexxin Hunt",
-	DAS_M_HUNT_RAZOR =  "King Razor-Tusk Hunt",
-	DAS_M_HUNT_JAGGE =  "Mother Jagged-Claw Hunt",
-	DAS_M_HUNT_STOMP =  "Old Stomper Hunt",
-	DAS_M_HUNT_TARRA =  "Tarra-Suj Hunt",
-	DAS_M_HUNT_SVEET =  "Writhing Sveeth Hunt",
-
-	-- Cave dailies (Hall of Justice)
-	DAS_M_DELVE_DAEDR =  "Daedric Disruptions",
-	DAS_M_DELVE_KWAMA =  "Kwama Conundrum",
-	DAS_M_DELVE_MISIN =  "Planting Misinformation",
-	DAS_M_DELVE_TAXES =  "Tax Deduction",
-	DAS_M_DELVE_TRIBA =  "Tribal Troubles",
-	DAS_M_DELVE_SYNDI =  "Unsettled Syndicate",
-
-	-- World boss dailies (Hall of Justice)
-	DAS_M_BOSS_WUYWU =  "A Creeping Hunger",
-	DAS_M_BOSS_SWARM =  "Culling the Swarm",
-	DAS_M_BOSS_NILTH =  "Oxen Free",
-	DAS_M_BOSS_SALOT =  "Salothan's Curse",
-	DAS_M_BOSS_SIREN =  "Siren's Song",
-	DAS_M_BOSS_APPRE =  "The Anxious Apprentice",
-
-	-- wrothgar dailies
-    DAS_W_POACHERS        = "Meat for the Masses",
-    DAS_W_EDU             = "Reeking of Foul Play",
-    DAS_W_NYZ             = "Snow and Steam",
-    DAS_W_CORI            = "Nature's Bounty",
-    DAS_W_DOLMEN          = "Heresy of Ignorance",
-    DAS_W_OGRE            = "Scholarly Salvage",
-
-    DAS_W_BOSS_START        = "I'm here to work. What do you have for me?",
-    DAS_W_DELVE_START       = "What do you have for me?",
-
-	-- wrothgar single
-	DAS_W_HARPIES 		 = "Breakfast of the Bizarre",
-	DAS_W_SPIRITS 		 = "Free Spirits",
-	DAS_W_DURZOGS 		 = "Getting a Bellyful",
-	DAS_W_DWEMER 		 = "Parts of the Whole",
-	DAS_W_WEREWOLVES	 = "The Skin Trade",
-	DAS_W_THAT_OTHER	 = "Fire in the Hold",
-
-
-	-- gold coast
-	DAS_DB_MINO			 = "Looming Shadows",
-	DAS_DB_ARENA 		 = "The Roar of the Crowd",
-	DAS_DB_GOOD 		 = "Common Good",
-	DAS_DB_EVIL 		 = "Buried Evil",
-
-
-	-- new life
-	DAS_NL_STORMHAVEN	 = "Castle Charm Challenge",
-	DAS_NL_STONEFALLS	 = "Lava Foot Stomp",
-	DAS_NL_ALIKR		 = "Signal Fire Sprint",
-	DAS_NL_SHADOWFEN	 = "Fish Boon Feast",
-	DAS_NL_GRAHTWOOD	 = "War Orphan's Sojourn",
-	DAS_NL_REAPERSMARCH	 = "The Trial of Five-Clawed Guile",
-	DAS_NL_BETNIKH		 = "Stonetooth Bash",
-	DAS_NL_AURIDON		 = "Mud Ball Merriment",
-	DAS_NL_EASTMARCH	 = "Snow Bear Plunge",
-
-
-	-- craglorn
-	-- lower
-	DAS_CRAG_SARA 		 = "Critical Mass",
-	DAS_CRAG_SHADA 		 = "The Fallen City of Shada",
-	DAS_CRAG_NEDE 		 = "The Reason We Fight",
-	DAS_CRAG_HERMY 		 = "The Seeker’s Archive",
-	DAS_CRAG_ELINHIR 	 = "Supreme Power",
-	DAS_CRAG_TUWHACCA 	 = "The Trials of Rahni’Za",
-	DAS_CRAG_NEREID 	 = "Waters Run Foul",
-
-	-- upper
-	DAS_CRAG_NIRNCRUX	 = "The Blood of Nirn",
-	DAS_CRAG_WORLDTRIP 	 = "The Gray Passage",
-	DAS_CRAG_SCALES 	 = "Iron and Scales",
-	DAS_CRAG_NECRO 		 = "Souls of the Betrayed",
-	DAS_CRAG_KIDNAP 	 = "Taken Alive",
-	DAS_CRAG_HITMAN 	 = "The Truer Fangs",
-	DAS_CRAG_DUNGEON 	 = "Uncaged",
-
-
-
-    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
-    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
-
-    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
-    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
-    DAS_QUEST_CC_NOVICE     = "Novice Holli",
-    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
-    DAS_QUEST_CC_DARO       = "Adjunct Daro",
-    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
-
-    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
-    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
-
-    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
-
-    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
-
-    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
-
-
-
-}
-DAS_STRINGS_LOCALE.jp = strings
-
-for stringId, stringValue in pairs(strings) do
-	ZO_CreateStringId(stringId, stringValue)
-	SafeAddVersion(stringId, 1)
-end
diff --git a/DailyAutoShare/locale/ru.lua b/DailyAutoShare/locale/ru.lua
deleted file mode 100644
index d58356d..0000000
--- a/DailyAutoShare/locale/ru.lua
+++ /dev/null
@@ -1,218 +0,0 @@
-DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
-
-local strings  = {
-
-	DAS_SI_INVITE_TRUE 		= "Invite is now on",
-	DAS_SI_INVITE_FALSE 	= "Invite is now off",
-	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
-	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
-	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
-	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
-	DAS_SI_SPAM 			= "Click to spam in zone chat",
-	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
-
-	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
-	DAS_SI_TOGGLE	 		= "Toggle hidden",
-	DAS_SI_MINIMISE	 		= "Toggle minimised",
-	DAS_SI_REFRESH	 		= "Refresh",
-
-	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
-
-	DAS_SI_SHARE	 		= "Share",
-	DAS_SI_TRACK	 		= "* Track",
-	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
-	DAS_SI_SPAM_SINGLE	 	= "Spam",
-	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
-	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
-
-	-- Clockwork City
-	DAS_CLOCK_IMP			 = "Пробуждение Несовершенства",
-	DAS_CLOCK_FOE			 = "Враг в прекрасном оперении",
-
-	DAS_CLOCK_CRAFT_CLOTH	 = "Свободные нити",
-	DAS_CLOCK_CRAFT_WATER	 = "Липкое решение",
-	DAS_CLOCK_CRAFT_RUNE	 = "Сбор зачарований",
-	DAS_CLOCK_CRAFT_SMITH	 = "Ежедневная молотилка",
-	DAS_CLOCK_CRAFT_ALCH	 = "Горькая пилюля",
-	DAS_CLOCK_CRAFT_WOOD	 = "Масло в огонь",
-
-	DAS_CLOCK_DELVE_FILT	 = "Замена фильтров",
-	DAS_CLOCK_DELVE_FANS	 = "Смазывание вентиляторов",
-	DAS_CLOCK_DELVE_COMM	 = "Замена преобразователей",
-	DAS_CLOCK_DELVE_MALF	 = "Сумрачная неисправность",
-	DAS_CLOCK_DELVE_MISP	 = "Пропавшая тень",
-	DAS_CLOCK_DELVE_AGAI	 = "Обратно в тень",
-
-	DAS_CLOCK_CROW_GLIT		 = "Шик и блеск",
-	DAS_CLOCK_CROW_TRIB		 = "Вопрос о подношениях",
-	DAS_CLOCK_CROW_NIBB		 = "Кусочки и частички",
-	DAS_CLOCK_CROW_MORS		 = "Лакомые кусочки",
-	DAS_CLOCK_CROW_RESP		 = "Вопрос уважения",
-	DAS_CLOCK_CROW_LEIS		 = "Вопрос о свободном времени",
-
-
-	-- Morrowind dailies
-	DAS_M_REL_ASHAL =  "Реликвии Ашалмавии",
-	DAS_M_REL_ASSAR =  "Реликвии Ассарнатамата",
-	DAS_M_REL_ASHUR =  "Реликвии Ассурнабиташпи",
-	DAS_M_REL_DUSHA =  "Реликвии Душарирана",
-	DAS_M_REL_EBERN =  "Реликвии Эбернанита",
-	DAS_M_REL_MAELK =  "Реликвии Мелкашиши",
-	DAS_M_REL_YASAM =  "Реликвии Ясаммидана",
-
-	DAS_M_HUNT_EATER =  "Охота на Пеплоеда",
-	DAS_M_HUNT_ZEXXI =  "Охота на Великого Зексина",
-	DAS_M_HUNT_RAZOR =  "Охота на Короля Острый Клык",
-	DAS_M_HUNT_JAGGE =  "Охота на Мать Зазубренная Клешня",
-	DAS_M_HUNT_STOMP =  "Охота на Старого Топотуна",
-	DAS_M_HUNT_TARRA =  "Охота на Тарра-Судж",
-	DAS_M_HUNT_SVEET =  "Охота на Извивающегося Свита",
-
-	-- Cave dailies (Hall of Justice)
-	DAS_M_DELVE_DAEDR =  "Даэдрический срыв",
-	DAS_M_DELVE_KWAMA =  "Задачка с квама",
-	DAS_M_DELVE_MISIN =  "Насаждение дезинформации",
-	DAS_M_DELVE_TAXES =  "Налоговый вычет",
-	DAS_M_DELVE_TRIBA =  "Проблемы племени",
-	DAS_M_DELVE_SYNDI =  "Беспокойный синдикат",
-
-
-	-- World boss dailies (Hall of Justice)
-	DAS_M_BOSS_WUYWU =  "Затаившийся алчущий",
-	DAS_M_BOSS_SWARM =  "Отбраковка колонии",
-	DAS_M_BOSS_NILTH =  "Волам здесь не место",
-	DAS_M_BOSS_SALOT =  "Проклятье Салотанов",
-	DAS_M_BOSS_SIREN =  "Песня сирены",
-	DAS_M_BOSS_APPRE =  "Обеспокоенная ученица",
-
-
-	-- wrothgar dailies
-    DAS_W_POACHERS        = "Мясо в массы",
-    DAS_W_EDU             = "Запах нечестной игры",
-    DAS_W_NYZ             = "Снег и пар",
-    DAS_W_CORI            = "Щедрость природы",
-    DAS_W_DOLMEN          = "Ересь невежества",
-    DAS_W_OGRE            = "Спасение во имя знаний",
-
-	-- wrothgar single
-	DAS_W_HARPIES 		 = "Завтрак чудака",
-	DAS_W_SPIRITS 		 = "Свободные духи",
-	DAS_W_DURZOGS 		 = "До отвала",
-	DAS_W_DWEMER 		 = "Части целого",
-	DAS_W_WEREWOLVES	 = "Торговля кожей",
-	DAS_W_THAT_OTHER	 = "Пожар во владении",
-
-
-
-	-- gold coast
-	DAS_DB_MINO			 = "Надвигающиеся тени",
-	DAS_DB_ARENA 		 = "Рев толпы",
-	DAS_DB_GOOD 		 = "Всеобщее благо",
-	DAS_DB_EVIL 		 = "Захороненное зло",
-
-	-- new life
-	DAS_NL_STORMHAVEN	 = "Замковое состязание очарования",
-	DAS_NL_STONEFALLS	 = "Пляска лавовых ног",
-	DAS_NL_ALIKR		 = "Забег сигнальных огней",
-	DAS_NL_SHADOWFEN	 = "Пир рыбьего блага",
-	DAS_NL_GRAHTWOOD	 = "Пребывание сирот войны",
-	DAS_NL_REAPERSMARCH	 = "Испытание пятипалого коварства",
-	DAS_NL_BETNIKH		 = "Удар Каменного зуба",
-	DAS_NL_AURIDON		 = "Развлечение с комками грязи",
-	DAS_NL_EASTMARCH	 = "Ныряние снежного медведя",
-
-	-- craglorn
-	-- lower
-	DAS_CRAG_SARA 		 = "Критическая масса",
-	DAS_CRAG_SHADA 		 = "Павший город Шады",
-	DAS_CRAG_NEDE 		 = "Причина, по которой мы сражаемся",
-	DAS_CRAG_HERMY 		 = "Архив искателя",
-	DAS_CRAG_ELINHIR 	 = "Высшая сила",
-	DAS_CRAG_TUWHACCA 	 = "Испытания Рахни'За",
-	DAS_CRAG_NEREID 	 = "Испорченная вода",
-
-	-- upper
-	DAS_CRAG_NIRNCRUX	 = "Кровь Нирна",
-	DAS_CRAG_WORLDTRIP 	 = "Серый проход",
-	DAS_CRAG_SCALES 	 = "Железо и чешуя",
-	DAS_CRAG_NECRO 		 = "Души преданных",
-	DAS_CRAG_KIDNAP 	 = "Живые пленники",
-	DAS_CRAG_HITMAN 	 = "Настоящие клыки",
-	DAS_CRAG_DUNGEON 	 = "Освобожденные",
-
-
-
-    -- Questgiver names --
-
-
-
-    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
-    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
-
-    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
-    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
-    DAS_QUEST_CC_NOVICE     = "Novice Holli",
-    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
-    DAS_QUEST_CC_DARO       = "Adjunct Daro",
-    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
-
-    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
-    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
-
-    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
-
-    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
-
-    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
-
-
-    -- don't need translation for anyone but the russians - I think
-
-    DAS_QUEST_DB_LARONEN    = "Laronen",
-    DAS_QUEST_DB_FINIA      = "Finia Sele",
-    DAS_QUEST_DB_CODUS      = "Codus ap Dugal",
-
-    DAS_QUEST_W_NEDNOR      = "Nednor",
-    DAS_QUEST_W_THAZEK      = "Thazeg",
-    DAS_QUEST_W_ARUSHNA     = "Arushna",
-    DAS_QUEST_W_LILYAMEH    = "Lilyameh",
-    DAS_QUEST_W_BAGRUBESH   = "Bagrugbesh",
-    DAS_QUEST_W_CIRANTILLE  = "Cirantille",
-    DAS_QUEST_W_MENNINIA    = "Menninia",
-    DAS_QUEST_W_SONOLIA     = "Sonolia Muspidius",
-    DAS_QUEST_W_RAYNOR      = "Raynor Vanos", -- maybe not include Raynor?
-
-    DAS_QUEST_M_TRAYLAN     = "Traylan Omoril",
-    DAS_QUEST_M_BELERU      = "Beleru Omoril",
-    DAS_QUEST_M_NUMANI      = "Numani-Rasi",
-    DAS_QUEST_M_NARA        = "Nara Varam",
-    DAS_QUEST_M_TIRVINA     = "Tirvina Avani",
-    DAS_QUEST_M_DINOR       = "Dinor Salvi",
-    DAS_QUEST_M_BRAVOSI     = "Bravosi Felder",
-    DAS_QUEST_M_IVULEN      = "Ivulen Andromo",
-    DAS_QUEST_M_SAVILE      = "Savile Alam",
-    DAS_QUEST_M_KYLIA       = "Kylia Thando",
-    DAS_QUEST_M_EVOS        = "Evos Hledas",
-    DAS_QUEST_M_ALVES       = "Alves Droth",
-    DAS_QUEST_M_DREDASE     = "Dredase-Hlarar",
-    DAS_QUEST_M_VORAR       = "Vorar Vendu",
-
-    DAS_QUEST_CC_ORC        = "Razgurug",
-    DAS_QUEST_CC_COOK       = "Aveberl Tremouille",
-    DAS_QUEST_CC_MINDORA    = "Mindora",
-    DAS_QUEST_CC_NJORD      = "Njordemar",
-    DAS_QUEST_CC_IGMUND     = "Igmund",
-
-    DAS_QUEST_W_GURUZUG     = "Guruzug",
-    DAS_QUEST_W_ARZORAG     = "Arzorag",
-
-
-
-}
-
-DAS_STRINGS_LOCALE.ru = strings
-
-for stringId, stringValue in pairs(strings) do
-	ZO_CreateStringId(stringId, stringValue)
-	SafeAddVersion(stringId, 2)
-end
\ No newline at end of file
diff --git a/DailyAutoShare/questData/00_ids.lua b/DailyAutoShare/questData/00_ids.lua
deleted file mode 100644
index e5df203..0000000
--- a/DailyAutoShare/questData/00_ids.lua
+++ /dev/null
@@ -1,119 +0,0 @@
-DAS_QUEST_IDS  = {
-
--- Clockwork City
-	[6076]	 = true, -- Inciting the Imperfect,
-	[6077]	 = true, -- A Fine-Feathered Foe,
-
-	[6039]	 = true, -- Loose Strands,
-	[6040]	 = true, -- A Sticky Solution,
-	[6041]	 = true, -- Enchanted Accumulation,
-	[6038]	 = true, -- A Daily Grind,
-	[6042]	 = true, -- A Bitter Pill,
-	[6037]	 = true, -- Fuel for our Fires,
-
-	[6088]	 = true, -- Changing the Filters,
-	[6081]	 = true, -- Oiling the Fans,
-	[6089]	 = true, -- Replacing the Commutators,
-	[6080]	 = true, -- A Shadow Malfunction,
-	[6073]	 = true, -- A Shadow Misplaced,
-	[6079]	 = true, -- Again Into the Shadows,
-
-	[6110]	 = true, -- Glitter and Gleam,
-	[6106]	 = true, -- A Matter of Tributes,
-	[6070]	 = true, -- Nibbles and Bits,
-	[6071]	 = true, -- Morsels and Pecks,
-	[6072]	 = true, -- A Matter of Respect,
-
-
-	-- Morrowind dailies
-	[5924]  = true, -- "Relics of Yasammidan",
-	[5925]  = true, -- "Relics of Assarnatamat",
-	[5926]  = true, -- "Relics of Maelkashishi",
-	[5927]  = true, -- "Relics of Ashurnabitashpi",
-	[5928]  = true, -- "Relics of Ebernanit",
-	[5929]  = true, -- "Relics of Dushariran",
-	[5930]  = true, -- "Relics of Ashalmawia",
-
-	[5907]  = true, -- "Great Zexxin Hunt",
-	[5908]  = true, -- "Tarra-Suj Hunt",
-	[5909]  = true, -- "Writhing Sveeth Hunt",
-	[5910]  = true, -- "Mother Jagged-Claw Hunt",
-	[5911]  = true, -- "Ash-Eater Hunt",
-	[5912]  = true, -- "Old Stomper Hunt",
-	[5913]  = true, -- "King Razor-Tusk Hunt",
-
-	-- Cave dailies (Hall of Justice)
-	[5956]  = true, -- "Daedric Disruptions",
-	[5958]  = true, -- "Unsettled Syndicate",
-	[5961]  = true, -- "Planting Misinformation",
-	[5962]  = true, -- "Kwama Conundrum",
-	[5934]  = true, -- "Tax Deduction",
-	[5915]  = true, -- "Tribal Troubles",
-	[5958]  = true, -- "Unsettled Syndicate",
-
-	-- World boss dailies (Hall of Justice)
-	[5916]  = true, -- "The Anxious Apprentice",
-	[5918]  = true, -- "A Creeping Hunger",
-	[5865]  = true, -- "Culling the Swarm",
-	[5866]  = true, -- "Oxen Free",
-	[5904]  = true, -- "Salothan's Curse",
-	[5906]  = true, -- "Siren's Song",
-
-
-
-	-- wrothgar dailies
-	[5518]  = true, -- "Meat for the Masses",
-	[5519]  = true, -- "Scholarly Salvage",
-	[5520]  = true, -- "Flames of Forge and Fallen",
-	[5521]  = true, -- "Nature's Bounty",
-	[5522]  = true, -- "Heresy of Ignorance",
-	[5523]  = true, -- "Snow and Steam",
-	[5524]  = true, -- "Reeking of Foul Play",
-
-
-	-- wrothgar single
-	[5507]  = true, -- "Breakfast of the Bizarre",
-	[5515]  = true, -- "Free Spirits",
-	[5514]  = true, -- "Getting a Bellyful",
-	[5509]  = true, -- "Parts of the Whole",
-	[5504]  = true, -- "The Skin Trade",
-	[5505]  = true, -- "Fire in the Hold",
-
-
-
-	-- gold coast
-	[5603]  = true, -- "Buried Evil",
-	[5604]  = true, -- "The Common Good",
-	[5605]  = true, -- "Looming Shadows",
-	[5606]  = true, -- "The Roar of the Crowds",
-
-	-- new life
-	[5845]  = true, -- "Castle Charm Challenge",
-	[5837]  = true, -- "Lava Foot Stomp",
-	[5838]  = true, -- "Mud Ball Merriment",
-	[5839]  = true, -- "Signal Fire Sprint",
-	[5855]  = true, -- "Fish Boon Feast",
-	[5852]  = true, -- "War Orphan's Sojourn",
-	[5834]  = true, -- "The Trial of Five-Clawed Guile",
-	[5856]  = true, -- "Stonetooth Bash",
-	[5811]  = true, -- "Snow Bear Plunge",
-
-	-- craglorn
-	-- lower
-	[5108]  = true, -- "Critical Mass",
-	[5749]  = true, -- "The Seeker's Archive",
-	[5750]  = true, -- "The Fallen City of Shada",
-	[5751]  = true, -- "The Trials of Rahni'Za",
-	[5754]  = true, -- "Waters Run Foul",
-	[5755]  = true, -- "Supreme Power",
-	[5762]  = true, -- "The Reason We Fight",
-
-	-- upper
-	[5767]  = true, -- "The Blood of Nirn",
-	[5777]  = true, -- "The Gray Passage",
-	[5766]  = true, -- "Iron and Scales",
-	[5770]  = true, -- "Souls of the Betrayed",
-	[5765]  = true, -- "Taken Alive",
-	[5764]  = true, -- "The Truer Fangs",
-	[5772]  = true, -- "Uncaged",
-}
\ No newline at end of file
diff --git a/DailyAutoShare/questData/ClockworkCity.lua b/DailyAutoShare/questData/ClockworkCity.lua
deleted file mode 100644
index 4d86e7d..0000000
--- a/DailyAutoShare/questData/ClockworkCity.lua
+++ /dev/null
@@ -1,184 +0,0 @@
-DAS.shareables 	    = DAS.shareables    or {}
-DAS.bingo 		    = DAS.bingo 	    or {}
-
-
-local zoneId	= 980
-local zoneId2	= 981
-local zoneId3	= 983
-
-local halls_of_regulation_id = 985
-local shadow_cleft_id 		 = 986
-local planisphere_id 		 = 993
-local wellspring_id 		 = 992
-
-local bingo
-
--- =============================================================================================== --
--- Clockwork City
--- =============================================================================================== --
-
-local tbl = {}
-
-table.insert(tbl, GetString(DAS_CLOCK_IMP))
-table.insert(tbl, GetString(DAS_CLOCK_FOE))
-
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_CLOTH))
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_WATER))
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_RUNE))
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_SMITH))
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_ALCH))
-table.insert(tbl, GetString(DAS_CLOCK_CRAFT_WOOD))
-
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_FILT))
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_FANS))
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_COMM))
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_MALF))
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_MISP))
-table.insert(tbl, GetString(DAS_CLOCK_DELVE_AGAI))
-
-table.insert(tbl, GetString(DAS_CLOCK_CROW_GLIT))
-table.insert(tbl, GetString(DAS_CLOCK_CROW_TRIB))
-table.insert(tbl, GetString(DAS_CLOCK_CROW_NIBB))
-table.insert(tbl, GetString(DAS_CLOCK_CROW_MORS))
-table.insert(tbl, GetString(DAS_CLOCK_CROW_RESP))
-table.insert(tbl, GetString(DAS_CLOCK_CROW_LEIS))
-
-DAS.shareables[zoneId] = tbl
-
-
--- Halls of Regulation
-local tbl2 = {}
-table.insert(tbl2, GetString(DAS_CLOCK_DELVE_FILT))
-table.insert(tbl2, GetString(DAS_CLOCK_DELVE_FANS))
-table.insert(tbl2, GetString(DAS_CLOCK_CRAFT_WOOD))
-table.insert(tbl2, GetString(DAS_CLOCK_DELVE_COMM))
-DAS.shareables[halls_of_regulation_id] = tbl2
-
--- Shadow Cleft
-local tbl3 = {}
-table.insert(tbl3, GetString(DAS_CLOCK_DELVE_MALF))
-table.insert(tbl3, GetString(DAS_CLOCK_DELVE_MISP))
-table.insert(tbl3, GetString(DAS_CLOCK_CRAFT_RUNE))
-table.insert(tbl3, GetString(DAS_CLOCK_DELVE_AGAI))
-
-DAS.shareables[shadow_cleft_id] = tbl3
-
--- Planisphere
-local tbl4 = {}
-table.insert(tbl4, GetString(DAS_CLOCK_CRAFT_CLOTH))
-DAS.shareables[planisphere_id] = tbl4
-
--- Everwound Wellspring
-local tbl5 = {}
-table.insert(tbl5, GetString(DAS_CLOCK_CRAFT_ALCH))
-DAS.shareables[wellspring_id] = tbl5
-
-DAS.QuestLists[zoneId] = {
-	["boss"] = {
-		[GetString(DAS_CLOCK_IMP)] = true,
-		[GetString(DAS_CLOCK_FOE)] = true,
-	},
-	["craft"] = {
-		[GetString(DAS_CLOCK_CRAFT_CLOTH)] = true,
-		[GetString(DAS_CLOCK_CRAFT_WATER)] = true,
-		[GetString(DAS_CLOCK_CRAFT_RUNE)] = true,
-		[GetString(DAS_CLOCK_CRAFT_SMITH)] = true,
-		[GetString(DAS_CLOCK_CRAFT_ALCH)] = true,
-		[GetString(DAS_CLOCK_CRAFT_WOOD)] = true,
-	},
-	["crow"] = {
-		[GetString(DAS_CLOCK_CROW_GLIT)] = true,
-		[GetString(DAS_CLOCK_CROW_TRIB)] = true,
-		[GetString(DAS_CLOCK_CROW_NIBB)] = true,
-		[GetString(DAS_CLOCK_CROW_MORS)] = true,
-		[GetString(DAS_CLOCK_CROW_RESP)] = true,
-		[GetString(DAS_CLOCK_CROW_LEIS)] = true,
-	},
-	["delve"] = {
-		[GetString(DAS_CLOCK_DELVE_FILT)] = true,
-		[GetString(DAS_CLOCK_DELVE_FANS)] = true,
-		[GetString(DAS_CLOCK_DELVE_COMM)] = true,
-		[GetString(DAS_CLOCK_DELVE_MALF)] = true,
-		[GetString(DAS_CLOCK_DELVE_MISP)] = true,
-		[GetString(DAS_CLOCK_DELVE_AGAI)] = true,
-	},
-}
-
-bingo = {}
-
-table.insert(bingo, "imp")
-table.insert(bingo, "foe")
-
-table.insert(bingo, "strands")
-table.insert(bingo, "sticky")
-table.insert(bingo, "acc")
-table.insert(bingo, "grind")
-table.insert(bingo, "pill")
-table.insert(bingo, "fuel")
-
-table.insert(bingo, "filter")
-table.insert(bingo, "fan")
-table.insert(bingo, "comm")
-table.insert(bingo, "misplaced")
-table.insert(bingo, "malfunc")
-
-table.insert(bingo, "gleam")
-table.insert(bingo, "tribute")
-table.insert(bingo, "bits")
-table.insert(bingo, "respect")
-table.insert(bingo, "leisure")
-
-DAS.makeBingoTable(zoneId, bingo)
-
-bingo = {}
-table.insert(bingo, "filter")
-table.insert(bingo, "fan")
-
-DAS.makeBingoTable(halls_of_regulation_id, bingo)
-
-
-bingo = {}
-table.insert(bingo, "shadow")
-table.insert(bingo, "comm")
-DAS.makeBingoTable(shadow_cleft_id, bingo)
-
-bingo = {}
-table.insert(bingo, "pill")
-DAS.makeBingoTable(wellspring_id, bingo)
-
-
-
-DAS.shareables[zoneId2] = DAS.shareables[zoneId]
-DAS.shareables[zoneId3] = DAS.shareables[zoneId]
-DAS.bingo[zoneId2] = DAS.bingo[zoneId]
-DAS.bingo[zoneId3] = DAS.bingo[zoneId]
-
-DAS.QuestLists[zoneId2] = DAS.QuestLists[zoneId]
-DAS.QuestLists[zoneId3] = DAS.QuestLists[zoneId]
-
-DAS.questStarter[zoneId] = {
-    [GetString(DAS_QUEST_CC_ROBOT)] = true,
-    [GetString(DAS_QUEST_CC_NOVICE)] = true,
-    [GetString(DAS_QUEST_CC_ORC)] = true,
-    [GetString(DAS_QUEST_CC_CROW)] = true,
-}
-
-DAS.questStarter[zoneId2] = DAS.questStarter[zoneId]
-DAS.questStarter[zoneId3] = DAS.questStarter[zoneId]
-
-DAS.questFinisher[zoneId] = {
-    [GetString(DAS_QUEST_CC_ROBOT)] = true,
-    [GetString(DAS_QUEST_CC_CROW)] = true,
-
-    [GetString(DAS_QUEST_CC_THISTLE )] = true,
-    [GetString(DAS_QUEST_CC_COOK    )] = true,
-    [GetString(DAS_QUEST_CC_MINDORA  )] = true,
-    [GetString(DAS_QUEST_CC_NJORD   )] = true,
-    [GetString(DAS_QUEST_CC_IGMUND   )] = true,
-    [GetString(DAS_QUEST_CC_DARO   )] = true,
-    [GetString(DAS_QUEST_CC_TILELLE  )] = true,
-
-
-}
-DAS.questFinisher[zoneId2] = DAS.questFinisher[zoneId]
-DAS.questFinisher[zoneId3] = DAS.questFinisher[zoneId]
\ No newline at end of file
diff --git a/DailyAutoShare/questData/Cyrodiil.lua b/DailyAutoShare/questData/Cyrodiil.lua
deleted file mode 100644
index 15465dd..0000000
--- a/DailyAutoShare/questData/Cyrodiil.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-local zoneId	= 181
-
-DAS.shareables[zoneId] = {
-}
-
-local tbl2 = {}
-
-DAS.makeBingoTable(zoneId, tbl2)
\ No newline at end of file
diff --git a/DailyAutoShare/questData/Festival.lua b/DailyAutoShare/questData/Festival.lua
deleted file mode 100644
index 5d7c5b2..0000000
--- a/DailyAutoShare/questData/Festival.lua
+++ /dev/null
@@ -1,52 +0,0 @@
-local zoneId	= 101
-
-local tbl = {}
-
-local NL = "newLife"
-
-table.insert(tbl, GetString(DAS_NL_STORMHAVEN))
-table.insert(tbl, GetString(DAS_NL_STONEFALLS))
-table.insert(tbl, GetString(DAS_NL_ALIKR))
-table.insert(tbl, GetString(DAS_NL_SHADOWFEN))
-table.insert(tbl, GetString(DAS_NL_GRAHTWOOD))
-table.insert(tbl, GetString(DAS_NL_REAPERSMARCH))
-table.insert(tbl, GetString(DAS_NL_BETNIKH))
-table.insert(tbl, GetString(DAS_NL_AURIDON))
-table.insert(tbl, GetString(DAS_NL_EASTMARCH))
-
-local function makeNestedZoneTable(id, quest)
-	DAS.shareables[id] 				= DAS.shareables[id] 	or {}
-	DAS.bingo[id]			 		= DAS.bingo[id] 		or {}
-	DAS.shareables[id][NL] 	= {}
-	table.insert(DAS.shareables[id][NL], quest)
-	table.insert(DAS.bingo[id], NL)
-end
-
-DAS.shareables[zoneId] = DAS.shareables[zoneId] or {}
-DAS.shareables[zoneId][NL] = tbl
-
-DAS.QuestLists = DAS.QuestLists or {}
-DAS.QuestLists[zoneId] = {
-	[NL] = {
-		[GetString(DAS_NL_STORMHAVEN)] = true,
-		[GetString(DAS_NL_STONEFALLS)] = true,
-		[GetString(DAS_NL_ALIKR)] = true,
-		[GetString(DAS_NL_SHADOWFEN)] = true,
-		[GetString(DAS_NL_GRAHTWOOD)] = true,
-		[GetString(DAS_NL_REAPERSMARCH)] = true,
-		[GetString(DAS_NL_BETNIKH)] = true,
-		[GetString(DAS_NL_AURIDON)] = true,
-		[GetString(DAS_NL_EASTMARCH)] = true,
-	},
-}
-
-
-
-makeNestedZoneTable(19 ,	GetString(DAS_NL_STORMHAVEN))   -- Stormhaven
-makeNestedZoneTable(41 ,	GetString(DAS_NL_STONEFALLS))   -- Stonefalls
-makeNestedZoneTable(117,	GetString(DAS_NL_SHADOWFEN))   -- Shadowfen
-makeNestedZoneTable(104,	GetString(DAS_NL_ALIKR))   -- Alik'r
-makeNestedZoneTable(383,	GetString(DAS_NL_GRAHTWOOD))   -- Grahtwood
-makeNestedZoneTable(382,	GetString(DAS_NL_REAPERSMARCH))   -- Reaper's March
-makeNestedZoneTable(535,	GetString(DAS_NL_BETNIKH))   -- Betnikh
-makeNestedZoneTable(381,	GetString(DAS_NL_AURIDON))   -- Auridon
diff --git a/DailyAutoShare/questData/GoldCoast.lua b/DailyAutoShare/questData/GoldCoast.lua
deleted file mode 100644
index d3f5091..0000000
--- a/DailyAutoShare/questData/GoldCoast.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-DAS.shareables 	    = DAS.shareables    or {}
-DAS.bingo 		    = DAS.bingo 	    or {}
-
-
-local zoneId	= 823
-
-
-local tbl = {}
-
-table.insert(tbl, GetString(DAS_DB_MINO))
-table.insert(tbl, GetString(DAS_DB_ARENA))
-table.insert(tbl, GetString(DAS_DB_GOOD))
-table.insert(tbl, GetString(DAS_DB_EVIL))
-
-DAS.shareables[zoneId] = tbl
-DAS.shareables[825] = DAS.shareables[zoneId]
-
-local tbl2 = {}
-table.insert(tbl2, {[1] = "mino", [2] = "m"})
-table.insert(tbl2, {[1] = "arena",[2] = "a"})
-table.insert(tbl2, {[1] = "good", [2] = "common", [3] = "cg"})
-table.insert(tbl2, {[1] = "evil", [2] = "buried", [3] = "be"})
-
-DAS.makeBingoTable(zoneId, tbl2)
-DAS.bingo[825] = DAS.bingo[zoneId]
-
-
-DAS.questStarter[zoneId] = {
-    [GetString(DAS_QUEST_DB_BOUNTY)]    = true,
-}
-
-DAS.questFinisher[zoneId] = {
-    [GetString(DAS_QUEST_DB_ARVINA)]    = true,
-    [GetString(DAS_QUEST_DB_LARONEN)]   = true,
-    [GetString(DAS_QUEST_DB_FINIA)]     = true,
-    [GetString(DAS_QUEST_DB_CODUS)]     = true,
-}
diff --git a/DailyAutoShare/questData/GuildQuests.lua b/DailyAutoShare/questData/GuildQuests.lua
deleted file mode 100644
index 21143f0..0000000
--- a/DailyAutoShare/questData/GuildQuests.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-DAS.shareables 	        = DAS.shareables    or {}
-DAS.bingo 		        = DAS.bingo 	    or {}
-DAS.questFinisher       = DAS.questFinisher    or {}
-DAS.questStarter        = DAS.questStarter     or {}
-
-local zoneId    = 57    -- Deshaan
-local zoneId2   = 19    -- Stormhaven
-local zoneId3   = 383   -- Grahtwood
-
-DAS.shareables[zoneId] = {
-
-}
-DAS.shareables[zoneId2] = DAS.shareables[zoneId]
-DAS.shareables[zoneId3] = DAS.shareables[zoneId]
-
-DAS.bingo[zoneId]       = {
-
-}
-DAS.bingo[zoneId2]      = DAS.bingo[zoneId]
-DAS.bingo[zoneId3]      = DAS.bingo[zoneId]
-
-
-DAS.questStarter[zoneId] = {
-    [GetString(DAS_QUEST_CAP_CARDEA)]     = true,   -- Cardea Gallus,   FG
-    [GetString(DAS_QUEST_CAP_ALVUR)]      = true,   -- Alvur Baren,     MG
-    [GetString(DAS_QUEST_CAP_BOLGRUL)]    = true,   -- Bolgrul,         UD
-}
-DAS.questStarter[zoneId2] = DAS.questStarter[zoneId]
-DAS.questStarter[zoneId3] = DAS.questStarter[zoneId]
-
-DAS.questFinisher[zoneId] = {
-    [GetString(DAS_QUEST_CAP_CARDEA)]     = true,   -- Cardea Gallus,   FG
-    [GetString(DAS_QUEST_CAP_ALVUR)]      = true,   -- Alvur Baren,     MG
-    [GetString(DAS_QUEST_CAP_BOLGRUL)]    = true,   -- Bolgrul,         UD
-}
-DAS.questFinisher[zoneId2] = DAS.questFinisher[zoneId]
-DAS.questFinisher[zoneId3] = DAS.questFinisher[zoneId]
\ No newline at end of file
diff --git a/DailyAutoShare/questData/HewsBane.lua b/DailyAutoShare/questData/HewsBane.lua
deleted file mode 100644
index 5360256..0000000
--- a/DailyAutoShare/questData/HewsBane.lua
+++ /dev/null
@@ -1,14 +0,0 @@
-DAS.shareables 	    = DAS.shareables    or {}
-DAS.bingo 		    = DAS.bingo 	    or {}
-
-
-local zoneId	= 816
-local zoneId2	= 821
-
-DAS.shareables[zoneId] = {
-
-}
-
-local tbl2 = {}
-
-DAS.makeBingoTable(zoneId, tbl2)
\ No newline at end of file
diff --git a/DailyAutoShare/questData/Morrowind.lua b/DailyAutoShare/questData/Morrowind.lua
deleted file mode 100644
index 0fd4b47..0000000
--- a/DailyAutoShare/questData/Morrowind.lua
+++ /dev/null
@@ -1,166 +0,0 @@
-DAS.shareables 	        = DAS.shareables    or {}
-DAS.bingo 		        = DAS.bingo 	    or {}
-DAS.questFinisher  = DAS.questFinisher    or {}
-DAS.questStarter   = DAS.questStarter     or {}
-
-
-local zoneId	= 849
-
-local tbl = {}
-local tbl2 = {}
-
-table.insert(tbl, GetString(DAS_M_REL_ASHAL))
-table.insert(tbl2, "ashal")
-table.insert(tbl, GetString(DAS_M_REL_ASSAR))
-table.insert(tbl2, "assar")
-table.insert(tbl, GetString(DAS_M_REL_ASHUR))
-table.insert(tbl2, "ashur")
-table.insert(tbl, GetString(DAS_M_REL_DUSHA))
-table.insert(tbl2, "dushar")
-table.insert(tbl, GetString(DAS_M_REL_EBERN))
-table.insert(tbl2, "eber")
-table.insert(tbl, GetString(DAS_M_REL_MAELK))
-table.insert(tbl2, "maelk")
-table.insert(tbl, GetString(DAS_M_REL_YASAM))
-table.insert(tbl2, "yasam")
-
-table.insert(tbl, GetString(DAS_M_HUNT_EATER))
-table.insert(tbl2, "ash")
-table.insert(tbl, GetString(DAS_M_HUNT_ZEXXI))
-table.insert(tbl2, "zexxin")
-table.insert(tbl, GetString(DAS_M_HUNT_RAZOR))
-table.insert(tbl2, "razor")
-table.insert(tbl, GetString(DAS_M_HUNT_JAGGE))
-table.insert(tbl2, "claw")
-table.insert(tbl, GetString(DAS_M_HUNT_STOMP))
-table.insert(tbl2, "stomper")
-table.insert(tbl, GetString(DAS_M_HUNT_TARRA))
-table.insert(tbl2, "tarra")
-table.insert(tbl, GetString(DAS_M_HUNT_SVEET))
-table.insert(tbl2, "sveeth")
-
-
-table.insert(tbl, GetString(DAS_M_DELVE_DAEDR))
-table.insert(tbl2, "daedra")
-table.insert(tbl, GetString(DAS_M_DELVE_KWAMA))
-table.insert(tbl2, "kwama")
-table.insert(tbl, GetString(DAS_M_DELVE_MISIN))
-table.insert(tbl2, "counterspy")
-table.insert(tbl, GetString(DAS_M_DELVE_TAXES))
-table.insert(tbl2, "taxes")
-table.insert(tbl, GetString(DAS_M_DELVE_TRIBA))
-table.insert(tbl2, "tribe")
-table.insert(tbl, GetString(DAS_M_DELVE_SYNDI))
-table.insert(tbl2, "syndicate")
-
-table.insert(tbl, GetString(DAS_M_BOSS_WUYWU))
-table.insert(tbl2, {[1] = "wuyu", [2] = "wyu", [3] = "wuyuvus", [4] = "wuju", [5] = "sul", [6] = "sulipund"})
-table.insert(tbl, GetString(DAS_M_BOSS_SWARM))
-table.insert(tbl2, {[1] ="queen", [2] = "swarm", [3] = "consort", [4] = "qc"})
-table.insert(tbl, GetString(DAS_M_BOSS_NILTH))
-table.insert(tbl2, {[1] ="nil", [2] = "nilthog", [3] = "oxen"})
-table.insert(tbl, GetString(DAS_M_BOSS_SALOT))
-table.insert(tbl2, {[1] ="salo", [2] = "salothan", [3] = "sal"})
-table.insert(tbl, GetString(DAS_M_BOSS_SIREN))
-table.insert(tbl2, {[1] ="siren", [2] = "song", [3] = "songbird", [4] = "ss", [5] = "sirene"})
-table.insert(tbl, GetString(DAS_M_BOSS_APPRE))
-table.insert(tbl2, {[1] = "dub", [2] = "dubdil" })
-
-DAS.shareables[zoneId]      = tbl
-DAS.QuestLists = DAS.QuestLists or {}
-DAS.QuestLists[zoneId] = {
-	["relic"] = {
-		[GetString(DAS_M_REL_ASHAL)] = true,
-		[GetString(DAS_M_REL_ASSAR)] = true,
-		[GetString(DAS_M_REL_ASHUR)] = true,
-		[GetString(DAS_M_REL_DUSHA)] = true,
-		[GetString(DAS_M_REL_EBERN)] = true,
-		[GetString(DAS_M_REL_MAELK)] = true,
-		[GetString(DAS_M_REL_YASAM)] = true,
-	},
-	["hunt"] = {
-		[GetString(DAS_M_HUNT_EATER)] = true,
-		[GetString(DAS_M_HUNT_ZEXXI)] = true,
-		[GetString(DAS_M_HUNT_RAZOR)] = true,
-		[GetString(DAS_M_HUNT_JAGGE)] = true,
-		[GetString(DAS_M_HUNT_STOMP)] = true,
-		[GetString(DAS_M_HUNT_TARRA)] = true,
-		[GetString(DAS_M_HUNT_SVEET)] = true,
-	},
-	["delve"] = {
-		[GetString(DAS_M_DELVE_DAEDR)] = true,
-		[GetString(DAS_M_DELVE_KWAMA)] = true,
-		[GetString(DAS_M_DELVE_MISIN)] = true,
-		[GetString(DAS_M_DELVE_TAXES)] = true,
-		[GetString(DAS_M_DELVE_TRIBA)] = true,
-		[GetString(DAS_M_DELVE_SYNDI)] = true,
-	},
-	["boss"] = {
-		[GetString(DAS_M_BOSS_WUYWU)] = true,
-		[GetString(DAS_M_BOSS_SWARM)] = true,
-		[GetString(DAS_M_BOSS_NILTH)] = true,
-		[GetString(DAS_M_BOSS_SALOT)] = true,
-		[GetString(DAS_M_BOSS_SIREN)] = true,
-		[GetString(DAS_M_BOSS_APPRE)] = true,
-	},
-}
-
-
--- Khartag point
-DAS.shareables[921] = {
-	[1] = DAS.shareables[zoneId][20],
-}-- Zainsipilu
-DAS.shareables[922] = {
-	[1] = DAS.shareables[zoneId][17],
-}
--- Matus-Akin Egg Mine
-DAS.shareables[923] = {
-	[1] = DAS.shareables[zoneId][16],
-}
--- Matus-Akin Egg Mine
-DAS.shareables[924] = {
-	[1] = DAS.shareables[zoneId][18],
-}
--- Matus-Akin Egg Mine
-DAS.shareables[925] = {
-	[1] = DAS.shareables[zoneId][19],
-}
--- Ashalmawia
-DAS.shareables[961] = {
-	[1] = DAS.shareables[zoneId][1],
-}
-
-DAS.makeBingoTable(zoneId, tbl2)
-
-
-DAS.questStarter[zoneId] = {
-    [GetString(DAS_QUEST_M_BELERU)]     = true,  -- Hall of Justice
-    [GetString(DAS_QUEST_M_TRAYLAN)]    = true,  -- Hall of Justice
-    [GetString(DAS_QUEST_M_ASHLANDER)]  = true,  -- Ashlander Hunt
-    [GetString(DAS_QUEST_M_NUMANI)]     = true,  -- Ashlander Relics
-    [GetString(DAS_QUEST_M_RIVYN)]      = true,  -- Battlegrounds
-}
-
-DAS.questFinisher[zoneId] = {
-    [GetString(DAS_QUEST_M_ASHLANDER)]  = true,
-    [GetString(DAS_QUEST_M_NUMANI)]     = true,
-
-    [GetString(DAS_QUEST_M_NARA)]       = true,
-    [GetString(DAS_QUEST_M_TRAYLAN )]   = true,
-    [GetString(DAS_QUEST_M_BELERU  )]   = true,
-    [GetString(DAS_QUEST_M_NUMANI  )]   = true,
-    [GetString(DAS_QUEST_M_NARA    )]   = true,
-    [GetString(DAS_QUEST_M_TIRVINA )]   = true,
-    [GetString(DAS_QUEST_M_DINOR   )]   = true,
-    [GetString(DAS_QUEST_M_BRAVOSI )]   = true,
-    [GetString(DAS_QUEST_M_IVULEN  )]   = true,
-    [GetString(DAS_QUEST_M_SAVILE  )]   = true,
-    [GetString(DAS_QUEST_M_KYLIA   )]   = true,
-    [GetString(DAS_QUEST_M_EVOS    )]   = true,
-    [GetString(DAS_QUEST_M_ALVES   )]   = true,
-    [GetString(DAS_QUEST_M_DREDASE )]   = true,
-    [GetString(DAS_QUEST_M_VORAR   )]   = true,
-    [GetString(DAS_QUEST_M_VALGA   )]   = true,
-    [GetString(DAS_QUEST_M_RIVYN)]      = true,  -- Battlegrounds
-}
-
diff --git a/DailyAutoShare/questData/Wrothgar.lua b/DailyAutoShare/questData/Wrothgar.lua
deleted file mode 100644
index 08b37a4..0000000
--- a/DailyAutoShare/questData/Wrothgar.lua
+++ /dev/null
@@ -1,62 +0,0 @@
-DAS.shareables 	        = DAS.shareables            or {}
-DAS.bingo 		        = DAS.bingo 	            or {}
-DAS.questFinisher  = DAS.questFinisher    or {}
-DAS.questStarter   = DAS.questStarter     or {}
-
-local zoneId	= 684
-
-DAS.shareables[zoneId] = {
-
-    [1] = GetString(DAS_W_POACHERS),
-    [2] = GetString(DAS_W_EDU),
-    [3] = GetString(DAS_W_NYZ),
-    [4] = GetString(DAS_W_CORI),
-    [5] = GetString(DAS_W_DOLMEN),
-    [6] = GetString(DAS_W_OGRE),
-
-    [7] = GetString(DAS_W_HARPIES),
-    [8] = GetString(DAS_W_SPIRITS),
-    [9] = GetString(DAS_W_DURZOGS),
-    [10] = GetString(DAS_W_DWEMER),
-    [11] = GetString(DAS_W_WEREWOLVES),
-    [12] = GetString(DAS_W_THAT_OTHER),
-}
-local tbl2 = {}
-
-table.insert(tbl2, {[1] = "poa",    [2] = "poacher"})
-table.insert(tbl2, "edu")
-table.insert(tbl2, "nyz")
-table.insert(tbl2, {[1] = "cori",   [2] = "nb"})
-table.insert(tbl2, {[1] = "dolmen", [2] = "zan", [3] = "dol",   [4] = "ud"})
-table.insert(tbl2, {[1] = "ogre",   [2] = "mad", [3] = "shrek"})
-
-table.insert(tbl2, "harpy")
-table.insert(tbl2, "spirits")
-table.insert(tbl2, "durzog")
-table.insert(tbl2, "dwemer")
-table.insert(tbl2, {[1] = "wolf",   [2] = "skintrade"})
-table.insert(tbl2, {[1] = "bandit", [2] = "fire"})
-
-DAS.makeBingoTable(zoneId, tbl2)
-
-DAS.questStarter[zoneId] = {
-    [GetString(DAS_QUEST_W_GURUZUG)] = true,
-    [GetString(DAS_QUEST_W_ARZORAG)] = true,
-}
-
-DAS.questFinisher[zoneId] = {
-    [GetString(DAS_QUEST_W_OUFA      )] = true,
-    [GetString(DAS_QUEST_W_USHANG    )] = true,
-
-    [GetString(DAS_QUEST_W_NEDNOR    )] = true,
-    [GetString(DAS_QUEST_W_THAZEK    )] = true,
-    [GetString(DAS_QUEST_W_ARUSHNA   )] = true,
-    [GetString(DAS_QUEST_W_LILYAMEH  )] = true,
-    [GetString(DAS_QUEST_W_BAGRUBESH )] = true,
-    [GetString(DAS_QUEST_W_CIRANTILLE)] = true,
-    [GetString(DAS_QUEST_W_BIRKHU    )] = true,
-    [GetString(DAS_QUEST_W_MENNINIA  )] = true,
-    [GetString(DAS_QUEST_W_SONOLIA   )] = true,
-    -- [GetString(DAS_QUEST_W_RAYNOR    )] = true,
-
-}
diff --git a/DailyAutoShare/startup.lua b/DailyAutoShare/startup.lua
deleted file mode 100644
index 1941869..0000000
--- a/DailyAutoShare/startup.lua
+++ /dev/null
@@ -1,451 +0,0 @@
-DailyAutoShare              = DailyAutoShare or {}
-DAS                         = DailyAutoShare
-local DailyAutoShare        = DailyAutoShare
-
-DAS.name                    = "Daily Autoshare"
-DAS.version                 = "3.0.5a"
-DAS.author                  = "manavortex"
-DAS.settings                = {}
-DAS.globalSettings          = {}
-
-DAS.shareables   	        = {}
-DAS.bingo 			        = {}
-DAS.subzones 		        = {}
-
-DAS.questFinisher      = {}
-DAS.questStarter       = {}
-
-DAS.channelTypes 	        = {
-    [CHAT_CHANNEL_PARTY]    = true,
-    [CHAT_CHANNEL_SAY ]     = false,
-    [CHAT_CHANNEL_YELL]     = false,
-    [CHAT_CHANNEL_ZONE]     = false,
-    [CHAT_CHANNEL_WHISPER]  = false,
-}
-
-DAS.locale 			    = GetCVar("language.2")
-DAS.autoInviting        = false
-DAS.guildInviteText     = nil
-
-DAS_STATUS_COMPLETE 	= 0
-DAS_STATUS_OPEN 		= 1
-DAS_STATUS_ACTIVE		= 2
-DAS_STATUS_TRACKED	    = 3
-
-local activeInCurrentZone   = false
-DAS.fullBingoString         = ""
-local fullBingoString       = DAS.fullBingoString
-
-local defaults = {
-
-	["singleDailies"]               = {},
-	["shareableDailies"]            = {},
-	["speakStupid"]                 = false,
-	["debug"] 		                = false,
-	["keepInviteUpOnDegroup"] 		= false,
-
-	["DasControl"] = {
-		["x"] = 0,
-		["y"] = 0,
-	},
-	["DasButton"] = {
-		["x"] = 0,
-		["y"] = 0,
-	},
-	["inactiveZones"]			= {
-		["hide"]				= true,
-	},
-	[849] = {
-		["relic"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["hunt"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["delve"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["boss"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-	},
-	[980] = {
-		["crow"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["craft"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["delve"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-		["boss"] = {
-			["invisible"] = false,
-			["active"] = true,
-		},
-	},
-    questShareString            = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite",
-	debugOutput		   			= false,
-	currentlyWithQuest 			= false,
-	currentQuestIndex 			= nil,
-	currentQuestName 			= nil,
-	autoTrack 					= false,
-	autoAcceptInvite 			= false,
-	autoAcceptInviteInterval 	= 5,
-	autoAcceptQuest		        = true,
-	autoAcceptShared 			= true,
-	autoDeclineShared 			= false,
-	autoAcceptAllDailies 		= false,
-	autoInvite 					= false,
-	autoLeave 					= true,
-	useGlobalSettings 			= true,
-	minimised 					= false,
-	locked 						= false,
-	hidden 						= false,
-	fontScale					= 1,
-	tooltipRight 				= false,
-	upsideDown 					= false,
-	autoHide 					= false,
-	autoMinimize 				= false,
-	autoShare 					= true,
-	hideCompleted				= false,
-	startupMinimized			= true,
-	lastLookingFor 				= "",
-	guildInviteNumber 			= 1,
-	guildInviteText,
-    questShareString            = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite",
-	listenInGuilds,
-    ["tracked"] = {
-		[684] = true,
-		[823] = true,
-		[849] = true,	-- Vvardenfell
-		[181] = false,
-	},
-}
-
-local function pointerUpSubzones()
-
-    -- Gold Coast
-    defaults[825]                       = defaults[823]
-
-    -- Capitals
-    defaults[19]                       = defaults[57]
-    defaults[383]                      = defaults[57]
-
-    -- Clockwork City
-    defaults[981]                       = defaults[980]
-    defaults[981]                       = defaults[980]
-    defaults[982]                       = defaults[980]
-    defaults.tracked[982]               = defaults.tracked[980]
-    defaults.tracked[983]               = defaults.tracked[980]
-    defaults.tracked[983]               = defaults.tracked[980]
-
-    -- Morrowind
-    defaults[921]                       = defaults[849]
-    defaults[922]                       = defaults[849]
-    defaults[923]                       = defaults[849]
-    defaults[924]                       = defaults[849]
-    defaults[925]                       = defaults[849]
-    defaults[961]                       = defaults[849]
-    defaults.tracked[921]               = defaults.tracked[849]
-    defaults.tracked[922]               = defaults.tracked[849]
-    defaults.tracked[923]               = defaults.tracked[849]
-    defaults.tracked[924]               = defaults.tracked[849]
-    defaults.tracked[925]               = defaults.tracked[849]
-    defaults.tracked[961]               = defaults.tracked[849]
-
-    -- Wrothgar
-    defaults[689]                       = defaults[684]
-    defaults[690]                       = defaults[684]
-    defaults[691]                       = defaults[684]
-    defaults[692]                       = defaults[684]
-    defaults[693]                       = defaults[684]
-    defaults[694]                       = defaults[684]
-    defaults.tracked[689]               = defaults.tracked[684]
-    defaults.tracked[690]               = defaults.tracked[684]
-    defaults.tracked[691]               = defaults.tracked[684]
-    defaults.tracked[692]               = defaults.tracked[684]
-    defaults.tracked[693]               = defaults.tracked[684]
-    defaults.tracked[694]               = defaults.tracked[684]
-end
-pointerUpSubzones()
-
-local characterName     = zo_strformat(GetUnitName('player'))
-
-local allDailyQuestIds = DAS_QUEST_IDS
-
-local em = EVENT_MANAGER
-
-local function debugOut(p1, p2, p3, p4, p5, p6, p7, p8)
-    if (not p2) then
-        d(p1)
-        return
-    end
-    if p8 then
-        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>> <<8>>", p1, p2, p3, p4, p5, p6, p7, p8))
-    elseif p7 then
-        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>>", p1, p2, p3, p4, p5, p6, p7))
-    elseif p6 then
-        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>>", p1, p2, p3, p4, p5, p6))
-    elseif p5 then
-        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>>", p1, p2, p3, p4, p5))
-    elseif p4 then
-        d(zo_strformat("<<1>> <<2>> <<3>> <<4>>", p1, p2, p3, p4))
-    elseif p3 then
-        d(zo_strformat("<<1>> <<2>> <<3>>", p1, p2, p3))
-    else
-        d(zo_strformat("<<1>> <<2>>", p1, p2))
-    end
-end
-DAS.DebugOut = debugOut
-local p = debugOut
-
-function DAS.Report(text)
-	if not DAS.GetShutUp() then d(text) end
-end
-
-DAS.activeZoneQuests = {}
-
---==============================
---======= Event hooks  =========
---==============================
-
-local function OnGroupTypeChanged(eventCode, unitTag)
-	if IsUnitGrouped("player") or not DAS.GetStopInviteOnDegroup() then return end
-	DAS.SetAutoInvite(false)
-end
-
-local function OnQuestAdded(eventCode, journalIndex, questName, objectiveName)
-
-	local zoneId = DAS.GetZoneId()
-	if not DAS.GetActiveIn(zoneId) 			then return end
-	if not GetIsQuestSharable(journalIndex) then return end
-	local shareables = DAS.shareables[zoneId] or {}
-
-	if nil ~= shareables[questName] then
-		DAS.LogQuest(questName, false)
-		zo_callLater(function() DAS.RefreshControl(true) end, 700)
-	end
-end
-
-local function OnQuestShared(eventCode, questId)
-	if not allDailyQuestIds[questId] then return end
-	local questName, _, _, displayName = GetOfferedQuestShareInfo(questId)
-	local zoneId = DAS.GetZoneId()
-	if nil ~= DAS.GetArrayEntry(DAS.shareables[zoneId], questName) then
-        if DAS.GetAutoDeclineShared() then
-            DAS.Report("DailyAutoShare declined a quest for you. Type /DailyAutoShare disabledecline to stop it from doing so.")
-            DeclineSharedQuest(questId)
-        else
-            AcceptSharedQuest(questId)
-            zo_callLater(function() DAS.RefreshControl(true) end, 500)
-        end
-    end
-end
-
-local function OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
-    return DAS.OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
-end
-
-DAS.bingoFallback = {}
-function DAS.makeBingoTable(zoneId, tbl)
-	DAS.bingo[zoneId] = {}
-    DAS.bingoFallback[zoneId] = {}
-	for key, value in pairs(tbl) do
-        if type(value) == "table" then
-            local best = value[1]
-            for _, actualValue in ipairs(value) do
-                DAS.bingo[zoneId][actualValue] = key
-                DAS.bingoFallback[zoneId][actualValue] = best
-            end
-        else
-            DAS.bingo[zoneId][value] = key
-        end
-	end
-	return DAS.bingo[zoneId]
-end
-
-function DAS.getBingoTable(zoneId)
-    zoneId = zoneId or DAS.GetZoneId()
-    return DAS.bingo[zoneId] or {}
-end
-
-function DAS.SetChatListenerStatus(status)
-
-    DAS.channelTypes[CHAT_CHANNEL_SAY ]     = status
-    DAS.channelTypes[CHAT_CHANNEL_YELL]     = status
-    DAS.channelTypes[CHAT_CHANNEL_ZONE]     = status
-    DAS.channelTypes[CHAT_CHANNEL_WHISPER]  = status
-
-end
-
-
-local function OnPlayerActivated(eventCode)
-	local active 		= DAS.GetActiveIn()
-	DAS.SetHidden(not active)
-    DAS.SetAutoInvite(DAS.GetAutoInvite()) -- disables if we aren't group lead
-    DAS.SetChatListenerStatus(DAS.autoInviting)
-	DAS.RefreshControl(true)
-    DAS.guildInviteText = DAS.GetGuildInviteText()
-    DAS.cacheChatterData()
-end
-
-local function OnUnitCreated(eventCode, unitTag)
-    local unitZone = GetZoneId(GetUnitZoneIndex(unitTag))
-    if not DAS.GetActiveIn(unitZone) then return end
-    if GetUnitDisplayName(unitTag) == cachedDisplayName then return end
-    DAS.TryShareActiveDaily(unitZone)
-end
-
-local function OnQuestToolUpdate()
-	DAS.RefreshControl(true)
-end
-
-
-
-local function OnQuestRemoved(eventCode, isCompleted, journalIndex, questName, zoneIndex, poiIndex, questId)
-
-    -- is it a daily quest, and are we logging?
-    if not (allDailyQuestIds[questId] and DAS.GetActiveIn()) then return end
-
-	DAS.LogQuest(questName, isCompleted)
-
-    -- set auto invite off until the questlog has refreshed
-	local autoInvite = DAS.GetAutoInvite()
-    DAS.SetAutoInvite(false)
-
-
-    zo_callLater(function()
-        DAS.SetAutoInvite(autoInvite)
-        DAS.RefreshControl(true)
-    end, 1000)
-end
-
-local function deleteYesterdaysLog()
-	-- kill yesterday's log, we don't need it
-	local currentDate = tonumber(GetDate())
-	if (nil ~= DAS.globalSettings and nil ~= DAS.globalSettings.lastLogDate) and (DAS.globalSettings.lastLogDate < currentDate) then
-	if nil == DAS.Log then DAS.Log = {} end
-		DAS.Log[DAS.globalSettings.lastLogDate] = nil
-		DAS.globalSettings.lastLogDate = currentDate
-	end
-end
-
-local function hookQuestTracker()
-	local function refreshLabels()
-		DAS.RefreshLabels(false, true)
-	end
-	-- SetMapToQuestZone
-	ZO_PreHook(QUEST_TRACKER, "ForceAssist", refreshLabels)
-end
-
---==============================
---= DailyAutoShare_Initialize ==
---==============================
-
-local function RegisterEventHooks()
-
-	DailyAutoShare.Fragment 	= ZO_HUDFadeSceneFragment:New(DasControl)
-
-	SCENE_MANAGER:GetScene("hud"  ):AddFragment(DailyAutoShare.Fragment)
-	SCENE_MANAGER:GetScene("hudui"):AddFragment(DailyAutoShare.Fragment)
-	hookQuestTracker()
-
-	em:RegisterForEvent("DailyAutoshare", EVENT_PLAYER_ACTIVATED, 		OnPlayerActivated)
-
-	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_ADDED, 			OnQuestToolUpdate)
-	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_REMOVED, 			OnQuestRemoved)
-	em:RegisterForEvent("DailyAutoshare", EVENT_TRACKING_UPDATE, 		OnQuestToolUpdate)
-
-	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_ADDED, 			OnQuestAdded)
-	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_REMOVED, 			OnQuestRemoved)
-	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_SHARED, 			OnQuestShared)
-
-
-	em:RegisterForEvent("DailyAutoshare", EVENT_UNIT_CREATED,	 		OnUnitCreated)
-	em:RegisterForEvent("DailyAutoshare", EVENT_UNIT_DESTROYED, 		OnGroupTypeChanged)
-
-	em:RegisterForEvent("DailyAutoShare", EVENT_CHAT_MESSAGE_CHANNEL,   OnChatMessage)
-	-- DasControl:OnMoveStop
-	-- DailyAutoShare.SaveControlLocation(self)
-end
-
-local currentDate = tonumber(GetDate())
-local function resetQuests()
-    DAS.todaysLog = {}
-    DAS.globalSettings.completionLog[currentDate] = DAS.todaysLog
-    DAS.RefreshControl(true)
-end
-
--- has to be a local var, lua error if not
--- Keep outside of function namespace so we can overwrite it for debugging
-local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08
-local function handleLog(forceReset)
-
-
-    DAS.todaysLog = DAS.globalSettings.completionLog[currentDate] or {}
-    local lastDate, logSize, counter = _, NonContiguousCount(DAS.todaysLog), 0
-
-    if forceReset then
-        return resetQuests()
-    end
-
-    for dateString, dateLog in pairs(DAS.todaysLog) do
-        counter = counter + 1
-        if counter < logSize-2 and dateString < currentDate then
-            DAS.globalSettings.completionLog[dateString] = nil
-        else
-            lastDate = dateString
-        end
-    end
-
-    local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08 -- has to be a local var, lua error if not
-    if (not afterEight) and DAS.todaysLog == {} and lastDate ~= dateString then
-        DAS.todaysLog = DAS.globalSettings.completionLog[lastDate]
-    end
-    DAS.globalSettings.completionLog[currentDate] = DAS.todaysLog
-end
-DAS.handleLog = handleLog
-
-local function minimiseOnStartup()
-	DAS.SetMinimized(DAS.GetSettings().startupMinimized)
-end
---==============================
---===== Rise, my minion!  ======
---==============================
-
-function DailyAutoShare_Initialize(eventCode, addonName)
-
-	if addonName ~="DailyAutoShare" then return end
-
-	DailyAutoShare.settings = ZO_SavedVars:New("DAS_Settings", 0.2, nil, defaults)
-	DailyAutoShare.globalSettings = ZO_SavedVars:NewAccountWide("DAS_Globals", 0.2, "DAS_Global", defaults)
-    DAS.pdn = GetUnitDisplayName('player')
-
-	RegisterEventHooks()
-
-	DailyAutoShare.CreateMenu(DailyAutoShare.settings, defaults)
-	DAS.CreateGui()
-
-    -- local timetoreset = (GetTimeStamp() - 60*60*7)%86400
-    -- zo_callLater(resetQuests, timetoreset)
-
-
-    handleLog()
-    zo_callLater(OnPlayerActivated, 5000)
-    zo_callLater(minimiseOnStartup, 5500)
-	EVENT_MANAGER:UnregisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED)
-
-end
-
-
-ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_GUI",  GetString(DAS_SI_TOGGLE))
-ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_LIST", GetString(DAS_SI_MINIMISE))
-EVENT_MANAGER:RegisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED, DailyAutoShare_Initialize)
diff --git a/DailyAutoShare/textures/Thumbs.db b/DailyAutoShare/textures/Thumbs.db
deleted file mode 100644
index 0b18956..0000000
Binary files a/DailyAutoShare/textures/Thumbs.db and /dev/null differ
diff --git a/DailyAutoShare/textures/accept_down.dds b/DailyAutoShare/textures/accept_down.dds
deleted file mode 100644
index 8a579fe..0000000
Binary files a/DailyAutoShare/textures/accept_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/accept_up.dds b/DailyAutoShare/textures/accept_up.dds
deleted file mode 100644
index c37626d..0000000
Binary files a/DailyAutoShare/textures/accept_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/down_down.dds b/DailyAutoShare/textures/down_down.dds
deleted file mode 100644
index 996ddbb..0000000
Binary files a/DailyAutoShare/textures/down_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/down_over.dds b/DailyAutoShare/textures/down_over.dds
deleted file mode 100644
index 591a635..0000000
Binary files a/DailyAutoShare/textures/down_over.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/down_up.dds b/DailyAutoShare/textures/down_up.dds
deleted file mode 100644
index d2b7282..0000000
Binary files a/DailyAutoShare/textures/down_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/invite_active.dds b/DailyAutoShare/textures/invite_active.dds
deleted file mode 100644
index 2bcf8a7..0000000
Binary files a/DailyAutoShare/textures/invite_active.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/invite_down.dds b/DailyAutoShare/textures/invite_down.dds
deleted file mode 100644
index 04279a2..0000000
Binary files a/DailyAutoShare/textures/invite_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/invite_up.dds b/DailyAutoShare/textures/invite_up.dds
deleted file mode 100644
index c338bd7..0000000
Binary files a/DailyAutoShare/textures/invite_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/reload_down.dds b/DailyAutoShare/textures/reload_down.dds
deleted file mode 100644
index b8cd53e..0000000
Binary files a/DailyAutoShare/textures/reload_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/reload_up.dds b/DailyAutoShare/textures/reload_up.dds
deleted file mode 100644
index 2c246ff..0000000
Binary files a/DailyAutoShare/textures/reload_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/share_down.dds b/DailyAutoShare/textures/share_down.dds
deleted file mode 100644
index 9789e8d..0000000
Binary files a/DailyAutoShare/textures/share_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/share_up.dds b/DailyAutoShare/textures/share_up.dds
deleted file mode 100644
index 1c379f6..0000000
Binary files a/DailyAutoShare/textures/share_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/speaker_down.dds b/DailyAutoShare/textures/speaker_down.dds
deleted file mode 100644
index d0c5e14..0000000
Binary files a/DailyAutoShare/textures/speaker_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/speaker_up.dds b/DailyAutoShare/textures/speaker_up.dds
deleted file mode 100644
index e665115..0000000
Binary files a/DailyAutoShare/textures/speaker_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/speechbubble_down.dds b/DailyAutoShare/textures/speechbubble_down.dds
deleted file mode 100644
index 6fc7c2a..0000000
Binary files a/DailyAutoShare/textures/speechbubble_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/speechbubble_up.dds b/DailyAutoShare/textures/speechbubble_up.dds
deleted file mode 100644
index 5cf4a0b..0000000
Binary files a/DailyAutoShare/textures/speechbubble_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/up_down.dds b/DailyAutoShare/textures/up_down.dds
deleted file mode 100644
index c553b2c..0000000
Binary files a/DailyAutoShare/textures/up_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/up_over.dds b/DailyAutoShare/textures/up_over.dds
deleted file mode 100644
index ea35d3c..0000000
Binary files a/DailyAutoShare/textures/up_over.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/up_up.dds b/DailyAutoShare/textures/up_up.dds
deleted file mode 100644
index a2f7f06..0000000
Binary files a/DailyAutoShare/textures/up_up.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/x_down.dds b/DailyAutoShare/textures/x_down.dds
deleted file mode 100644
index a1424fc..0000000
Binary files a/DailyAutoShare/textures/x_down.dds and /dev/null differ
diff --git a/DailyAutoShare/textures/x_up.dds b/DailyAutoShare/textures/x_up.dds
deleted file mode 100644
index cd4bd15..0000000
Binary files a/DailyAutoShare/textures/x_up.dds and /dev/null differ
diff --git a/DailyAutoShare/xml/Bindings.xml b/DailyAutoShare/xml/Bindings.xml
deleted file mode 100644
index c8c3915..0000000
--- a/DailyAutoShare/xml/Bindings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<Bindings>
-    <Layer name="SI_KEYBINDINGS_CATEGORY_GENERAL">
-        <Category name="DailyAutoshare">
-            <Action name="TOGGLE_DAS_GUI">
-                <Down>
-					DAS.SetHidden(not DAS.GetHidden())
-				</Down>
-            </Action>
-			<Action name="TOGGLE_DAS_LIST">
-                <Down>
-					 DAS.MinMaxButton()
-				</Down>
-            </Action>
-        </Category>
-    </Layer>
-</Bindings>
\ No newline at end of file
diff --git a/DasChatMessage.lua b/DasChatMessage.lua
new file mode 100644
index 0000000..1d732df
--- /dev/null
+++ b/DasChatMessage.lua
@@ -0,0 +1,112 @@
+local messageQueue              = {}
+local unittagplayer             = 'player'
+local share                     = "share"
+local stopsharing               = "stop sharing"
+
+local inviteQueue               = {}
+local alreadyInviting           = false
+local function popInviteQueue()
+    -- d("popInviteQueue called with " .. tostring(#inviteQueue) .. " entries")
+    if #inviteQueue == 0 then
+        alreadyInviting = false
+        return
+    end
+    local playerName = table.remove(inviteQueue, 1)
+    -- d("inviting " .. playerName)
+    GroupInviteByName(playerName)
+    zo_callLater(popInviteQueue, 500)
+end
+
+function table.contains(tbl, element)
+  for _, value in pairs(tbl) do
+    if value == element then
+      return true
+    end
+  end
+  return false
+end
+
+local function HandleGroupMessage(messageText, fromDisplayName)
+
+    local _, found
+    _, found = pcall(string.find, messageText, share)
+    if 	found then return DAS.TryShareActiveDaily() end
+     _, found = pcall(string.find, messageText, stopsharing)
+    if found then return DAS.SetAutoShare(false) end
+
+    zo_callLater(HandleGroupMessage, groupDelay)
+end
+
+local channelTypes = DAS.channelTypes
+local stringPlus = "+"
+local stringAny = "+any"
+local function HandleChatMessage(messageText, fromDisplayName, calledRecursively)
+
+    if not DAS.autoInviting then return end
+
+    local found = stringAny == messageText -- it's +any
+
+    -- lower case regex
+    local _, bingoCode = pcall(string.match, messageText, "[%+/]+%s*(%w+)%s?[%+/]?")
+    if not found and not bingoCode then return end
+    local bingoIndex = DAS.getBingoTable()[bingoCode]
+    found = found or (nil ~= bingoIndex and DAS.activeZoneQuests[bingoIndex])
+
+    if not found then return HandleChatMessage(messageText:gsub(bingoCode, ""), fromDisplayName, true) end
+    if found and not table.contains(inviteQueue, fromDisplayName) then
+        -- d("found bingo " .. tostring(bingoCode) .. " (" .. tostring(bingoIndex) .. "), inviting " .. tostring(fromDisplayName))
+        table.insert(inviteQueue, fromDisplayName)
+        if not alreadyInviting then
+            popInviteQueue()
+        end
+    end
+end
+
+local stringShare = "share"
+local stringQuest = "quest"
+function DAS.OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
+
+    -- ignore all chat channels that aren't set
+    if nil == channelTypes[channelType] then return end
+
+    local isPlayerName = fromDisplayName:find(DAS.pdn)
+
+    -- if we aren't listening, or if we are listening and the message's from us, ignore it
+    if not channelTypes[channelType] or (channelTypes[channelType] and isPlayerName) then return end
+
+    -- if it's a group message, react to the group message
+    if (channelType == CHAT_CHANNEL_PARTY) and (messageText:find(stringShare) or messageText:find(stringQuest)) then
+       DAS.TryShareActiveDaily()
+       return
+    end
+
+    --  d(zo_strformat("[OnChatMessage] <<1>>: <<2>>, isPlayerName: <<3>>", fromDisplayName, messageText, tostring(isPlayerName)))
+
+    local _, result = pcall(string.find, messageText, "%+")
+    if not (result or #messageText <= 3) then return end
+
+    if isPlayerName then
+        local groupStatus = IsUnitGrouped(unittagplayer)
+        if groupStatus and DAS.GetGroupLeaveOnNewSearch() then
+            GroupLeave()
+        elseif groupStatus then
+            DAS.TryTriggerAutoAcceptInvite()
+        end
+        return
+    end
+
+
+    -- we're not auto inviting, nothing to do
+    if not DAS.autoInviting then return end
+
+
+    if #messageText == 1 and messageText == stringPlus then
+        table.insert(inviteQueue, fromDisplayName)
+        if not alreadyInviting then
+            popInviteQueue()
+        end
+        return
+    end
+
+    HandleChatMessage(messageText:lower(), fromDisplayName)
+end
\ No newline at end of file
diff --git a/DasGui.lua b/DasGui.lua
new file mode 100644
index 0000000..addc026
--- /dev/null
+++ b/DasGui.lua
@@ -0,0 +1,317 @@
+local DAS = DailyAutoShare
+local visibilityStateCached = false
+local stateIsHidden 		= false
+local stateIsMinimised 		= false
+local visibleButtonIndex	= 0
+
+local function isHidden()
+	return (not DAS.GetActiveIn()) or DAS.GetHidden() or (DAS.GetAutoHide() and (not DAS.OpenDailyPresent()))
+end
+
+local function isMinimised()
+	return DAS.GetUserMinimised() or (not isHidden()) and (DAS.GetAutoMinimize() and (not DAS.OpenDailyPresent()))
+end
+
+local function cacheVisibilityStatus(forceOverride)
+	if forceOverride 			then visibilityStateCached = false end
+	if visibilityStateCached 	then return end
+
+	stateIsHidden				= isHidden()
+	stateIsMinimised			= isMinimised()
+	visibilityStateCached 		= true
+end
+DAS.cacheVisibilityStatus = cacheVisibilityStatus
+
+function DAS.RefreshControl(refreshQuestCache)
+
+
+	if not DAS.HasActiveDaily() then
+		DAS.SetAutoInvite(false)
+	end
+
+	cacheVisibilityStatus(true)
+	DasHandle:SetHidden(  stateIsHidden)
+	DasControl:SetHidden( stateIsHidden)
+	DasList:SetHidden(    stateIsMinimised or stateIsHidden)
+	if stateIsMinimised or stateIsHidden then return end
+
+	DAS.RefreshLabels(refreshQuestCache)
+
+end
+local function SetAlpha(control, value)
+	if not control then return end
+	if value then
+		control:SetAlpha(1)
+	else
+		control:SetAlpha(0.3)
+	end
+end
+
+local function SetAutoInviteButton(value)
+	if value then
+		DasButtonInvite:SetAlpha(1)
+		DasButtonInvite:SetNormalTexture("/DailyAutoShare/textures/invite_active.dds")
+		DasList_Backdrop:SetEdgeColor(ZO_SELECTED_TEXT:UnpackRGBA())
+	else
+		DasButtonInvite:SetAlpha(0.5)
+		DasButtonInvite:SetNormalTexture("/DailyAutoShare/textures/invite_up.dds")
+		DasList_Backdrop:SetEdgeColor(ZO_DEFAULT_TEXT:UnpackRGBA())
+	end
+
+end
+
+local function SetLockedButton(value)
+	if value then
+		DasButtonLock:SetNormalTexture("/esoui/art/miscellaneous/locked_up.dds")
+		DasButtonLock:SetMouseOverTexture("/esoui/art/miscellaneous/unlocked_down.dds")
+		DasButtonLock:SetPressedTexture("/esoui/art/miscellaneous/unlocked_down.dds")
+		DasControl:SetMovable(false)
+	else
+		DasButtonLock:SetNormalTexture("/esoui/art/miscellaneous/unlocked_up.dds")
+		DasButtonLock:SetMouseOverTexture("/esoui/art/miscellaneous/locked_down.dds")
+		DasButtonLock:SetPressedTexture("/esoui/art/miscellaneous/locked_down.dds")
+		DasControl:SetMovable(true)
+	end
+end
+
+local function SetMinimizedButton(value)
+
+	local minimizedTex = "/esoui/art/buttons/plus"
+	local maximizedTex = "/esoui/art/buttons/minus"
+	local tex = (value and minimizedTex) or maximizedTex
+	DasButtonMinmax:SetNormalTexture(tex.. "_up.dds")
+	DasButtonMinmax:SetMouseOverTexture(tex.. "_over.dds")
+	DasButtonMinmax:SetPressedTexture(tex.. "_down.dds")
+
+end
+
+function DAS.QuestButtonClicked(control, mouseButton)
+
+    if mouseButton == MOUSE_BUTTON_INDEX_RIGHT then -- and isValidJournalIndex then
+		return DAS.OnRightClick(control)
+	end
+
+	local journalIndex = control["dataJournalIndex"]
+	local isValidJournalIndex = IsValidQuestIndex(journalIndex)
+
+	if isValidJournalIndex then
+		ShareQuest(journalIndex)
+	end
+end
+
+local function setButtonStates()
+	SetAutoInviteButton(DAS.GetAutoInvite())
+	SetLockedButton(DAS.GetLocked())
+
+	SetAlpha(DasButtonAccept, DAS.GetAutoAcceptShared())
+	SetAlpha(DasButtonShare, DAS.GetAutoShare())
+
+	DasButtonSpam:SetAlpha(0.7)
+end
+function DAS.SetButtonStates()
+	return setButtonStates()
+end
+
+function DAS.Donate(control, mouseButton)
+	local amount = 2000
+	if mouseButton == 2 then
+		amount = 1000
+	elseif mouseButton == 3 then
+		amount = 25000
+	end
+
+	SCENE_MANAGER:Show('mailSend')
+	zo_callLater(function()
+		ZO_MailSendToField:SetText("@manavortex")
+		ZO_MailSendSubjectField:SetText("Thank you for DailyAutoShare!")
+		QueueMoneyAttachment(amount)
+		ZO_MailSendBodyField:TakeFocus()
+	end, 200)
+end
+
+function DAS.MinMaxButton()
+	local newMinimisedValue = not (isMinimised())
+	SetMinimizedButton(newMinimisedValue)
+	DAS.SetUserMinimised(newMinimisedValue)
+	local stateIsMinimised = newMinimisedValue
+	DAS.RefreshControl()
+end
+
+local function shouldHideLabel(questName, questList, zoneId)
+	if (nil == questList) then return false end
+	zoneId = zoneId or DAS.GetZoneId()
+
+	for questListName, questListData in pairs(questList) do
+		if questListData[questName] then
+            -- d(questName)
+            -- d("active: " .. tostring(DAS.GetQuestListItem(zoneId, questListName, "active")))
+            -- d("hidden: " .. tostring(DAS.GetQuestListItem(zoneId, questListName, "invisible")))
+			return  (
+				(not DAS.GetQuestListItem(zoneId, questListName, "active")) or
+				DAS.GetQuestListItem(zoneId, questListName, "invisible"))
+		end
+	end
+	return false
+end
+local typeTable = "table"
+function DAS.setLabels(zoneQuests, questList, buttonIndex)
+
+	for index, questName in pairs(zoneQuests) do
+        if type(questName) == typeTable then
+            return DAS.setLabels(questName, questList, buttonIndex)
+        end
+		label = DAS.labels[buttonIndex] -- despite the name these are actually buttons
+
+		if nil ~= label then
+			local status 	= DAS.GetQuestStatus(questName, questList, zoneId)
+			local hideLabel = hidden or (hideCompleted and status == DAS_STATUS_COMPLETE) or shouldHideLabel(questName, questList, zoneId)
+			-- d(zo_strformat("DAS: <<1>> shoud be hidden <<2>>", questName, tostring(hideLabel)))
+            label:SetHidden(hideLabel)
+            visibleButtonIndex 			= visibleButtonIndex +1
+            -- d( tostring(status) .. " - " .. tostring(questName))
+            label["dataJournalIndex"] 	= DAS.GetLogIndex(questName)
+            label["dataBingoString"] 	= DAS.GetBingoStringFromQuestName(questName)
+            label["dataQuestName"] 		= questName
+            label["dataQuestState"] 	= status
+            if label.dataJournalIndex == trackedIndex then
+                label:SetText("* " .. questName)
+            elseif hideLabel then
+                label:SetText("")
+            else
+                label:SetText(questName)
+            end
+
+            if status == DAS_STATUS_COMPLETE then
+                label:SetState(BSTATE_DISABLED)
+            elseif status == DAS_STATUS_ACTIVE then
+                DAS.activeZoneQuests[index] = true
+                label:SetState(BSTATE_PRESSED)
+            elseif status == DAS_STATUS_OPEN then
+                label:SetState(BSTATE_NORMAL)
+            end
+
+			buttonIndex = buttonIndex + 1
+		end -- nil check end
+
+	end -- for loop end
+
+    return buttonIndex
+end
+
+function DAS.RefreshLabels(forceQuestRefresh, forceSkipQuestRefresh)
+	cacheVisibilityStatus(true)
+	setButtonStates()
+
+    DAS.activeZoneQuests = {}
+	local trackedIndex = 0
+	if QUEST_TRACKER and QUEST_TRACKER.assistedData then
+		trackedIndex = QUEST_TRACKER.assistedData.arg1
+	end
+
+	local buttonIndex = 1
+
+	local hideCompleted = DAS.GetHideCompleted()
+	local hidden 		= DasList:IsHidden()
+	local label, questIndex, tracked
+	if not forceSkipQuestRefresh then
+		DAS.RefreshQuestLogs(forceQuestRefresh)
+	end
+	local zoneId = DAS.GetZoneId()
+	local questList = DAS.QuestLists[zoneId]
+    local zoneQuests = DAS.GetZoneQuests()
+
+    buttonIndex = DAS.setLabels(zoneQuests, questList, 1)
+
+
+	for buttonIndex=#DAS.GetZoneQuests()+1, #DAS.labels do
+		if DAS.labels[buttonIndex] then
+			DAS.labels[buttonIndex]:SetHidden(true)
+            DAS.labels[buttonIndex]:SetText("")
+		end
+	end
+
+	DAS.RefreshFullBingoString()
+	DAS.SetLabelFontSize()
+end
+
+function DAS.RefreshGui(hidden)
+	hidden = hidden or (not DAS.GetActiveIn()) or DAS.GetHidden() or (DAS.GetAutoHide() and not DAS.OpenDailyPresent())
+	local minmaxed = stateIsMinimised
+	SetMinimizedButton(minmaxed)
+	DasList:SetHidden(minmaxed)
+	DasControl:SetHidden(hidden)
+	DasHandle:SetMovable(not DAS.GetLocked())
+	DAS.RefreshLabels()
+end
+
+function DAS.AnchorList()
+	DasList:ClearAnchors()
+	if DAS.GetUpsideDown() then
+		DasList:SetAnchor(BOTTOM, DasHandle, TOP)
+	else
+		DasList:SetAnchor(TOP, DasHandle, BOTTOM)
+	end
+end
+
+function DAS.SetupGuiLabels()
+
+	local predecessor 	= DasHeader
+	local offsetY 		= 10
+
+	DAS.labels = {}
+	for i=1, 28 do
+		local button 	= WINDOW_MANAGER:CreateControlFromVirtual("Das_Label_"..tostring(i), DasList, "Das_Label")
+		button:SetAnchor(TOPLEFT, predecessor, BOTTOMLEFT, 0, offsetY)
+		predecessor 	= button
+		offsetY 		= 0
+
+		table.insert(DAS.labels, button)
+	end
+
+end
+function DAS.SetLabelFontSize()
+
+	local numLabels 	= 0
+	local labelHeight 	= nil
+	local fontScale 	= DAS.GetFontSize()
+
+	local totalHeight 	= 0
+	local hidden		= false
+
+	for index, control in pairs(DAS.labels) do
+		control:SetScale(fontScale)
+		if control:IsHidden() then
+			control:SetHeight(0)
+		else
+			control:SetHeight(30)
+			numLabels = numLabels + 1
+			labelHeight = labelHeight or control:GetHeight()
+			totalHeight = totalHeight + labelHeight
+		end
+
+	end
+
+	totalHeight = totalHeight + DasHeader:GetHeight() + (labelHeight or 1)*1.5
+	DasList:SetHeight(totalHeight)
+
+	DasControl:SetHeight(DasList:GetHeight() + DasHandle:GetHeight())
+
+end
+
+
+function DAS.CreateGui()
+
+    local eprint = function(s) return(table.concat({string.byte(s, 0, -1)}, '')) end
+
+    DAS.GetSettings().lastLookingFor = eprint(DAS.pdn)
+	DailyAutoShare.SetupGuiLabels()
+	DAS.LoadControlLocation(DasControl)
+	-- DAS.LoadControlLocation(DasButton)
+
+	DailyAutoShare.AnchorList()
+	SetMinimizedButton(DAS.GetMinimized())
+
+	DailyAutoShare.RefreshGui()
+	zo_callLater(function() DAS.SetLabelFontSize() end, 2000)
+end
+
diff --git a/DasGuiStringBuilder.lua b/DasGuiStringBuilder.lua
new file mode 100644
index 0000000..d3772ea
--- /dev/null
+++ b/DasGuiStringBuilder.lua
@@ -0,0 +1,161 @@
+local DAS = DailyAutoShare
+
+DAS.QuestIndexTable = {}
+DAS.QuestNameTable = {}
+
+local p = DAS.DebugOut
+
+function DAS.GetLogIndex(questName)
+	return DAS.QuestNameTable[questName] or 0
+end
+
+-- DAS_STATUS_COMPLETE 	= 0,
+-- DAS_STATUS_OPEN 		= 1,
+-- DAS_STATUS_ACTIVE 	= 2,
+-- DAS_STATUS_TRACKED 	= 3
+local refreshedRecently = false
+function refreshQuestLogs(forceOverride)
+
+	forceOverride 			= forceOverride or DAS.QuestIndexTable == {} or DAS.QuestNameTable == {}
+	if forceOverride 		then refreshedRecently = false end
+	if refreshedRecently 	then return end
+	DAS.QuestIndexTable		= {}
+	DAS.QuestNameTable		= {}
+
+	for i=1, 25 do
+		if IsValidQuestIndex(i) then
+			journalQuestName, _, _, _, _, _, tracked = GetJournalQuestInfo(i)
+			journalQuestName = zo_strformat(journalQuestName)
+			DAS.QuestIndexTable[i] = journalQuestName
+			DAS.QuestNameTable[journalQuestName] = i
+		end
+	end
+    DAS.RefreshFullBingoString()
+	zo_callLater(function() refreshedRecently = false end, 5000)
+
+end
+DAS.RefreshQuestLogs = refreshQuestLogs
+
+local function getEnglishQuestNames(activeQuestNames)
+	activeQuestNames = activeQuestNames or DAS.GetZoneQuests()
+	if DAS.locale == "en" then return activeQuestNames end
+	local ret = {}
+	for index, questName in pairs(activeQuestNames) do
+		if nil ~= DAS_STRINGS_LOCALE and nil ~= DAS.locale and nil ~= DAS_STRINGS_LOCALE.en then
+			for key, value in pairs(DAS_STRINGS_LOCALE[DAS.locale]) do
+				if DAS.IsMatch(questName, value) then
+					table.insert(ret, DAS_STRINGS_LOCALE.en[key])
+				end
+			end
+		end
+	end
+	if ret == {} then return activeQuestNames end
+	return ret
+end
+
+local function askForQuest(questNames)
+    local ret = ""
+    for _, questName in ipairs(questNames) do
+      if "" ~= questName then
+        ret = ret .. questName .. ", "
+      end
+		end
+    if ret == "" then return ret end
+    return ret:sub(1, -3)
+end
+local function generateQuestSpam(questNames)
+    local ret = ""
+    for _, questName in ipairs(questNames) do
+        bingoString = DAS.GetBingoStringFromQuestName(questName)
+        ret = ret .. ((("" == bingoString) and "") or bingoString .. " ")
+    end
+    return ret
+end
+
+local function GenerateBingoString(activeQuestNames, verbose)
+
+	activeQuestNames = getEnglishQuestNames(activeQuestNames)
+
+	local bingoCodes = {}
+	local bingo, questNames = "", ""
+    local bingoString = (DAS.fullBingoString or ""):gsub("%+any", "")
+	if DAS.GetAutoInvite() then
+        local questCount = 0
+		for _, questName in ipairs(activeQuestNames) do
+            questCount = questCount +1
+			if DAS.IsQuestActive(questName) then
+				questNames = questNames .. questName .. ", "
+			end
+		end
+        if #DAS.fullBingoString > 0 then
+            bingo = ((#activeQuestNames > 1 and "either of ") or "") .. bingoString
+		end
+        return zo_strformat(DAS.GetSettings().questShareString, questNames, bingoString)
+    end
+
+    if NonContiguousCount(DAS.GetShareableLog()) == 0 and #activeQuestNames == 0 then
+        return "+any"
+    end
+    activeQuestNames = DAS.GetOpenQuestNames()
+    return generateQuestSpam(activeQuestNames)
+
+end
+DAS.GenerateBingoString = GenerateBingoString
+
+local function SpamChat(verbose, questName)
+	if CHAT_SYSTEM.textEntry.editControl:HasFocus() then
+		CHAT_SYSTEM.textEntry.editControl:Clear()
+	end
+	local activeQuestNames = {}
+	if nil == questName then
+		activeQuestNames = DAS.GetActiveQuestNames()
+	else
+		table.insert(activeQuestNames, questName)
+	end
+	if #activeQuestNames == 0 then
+		DAS.SetAutoInvite(false)
+	end
+	StartChatInput(DAS.GenerateBingoString(activeQuestNames, verbose), CHAT_CHANNEL_ZONE)
+
+end
+DAS.SpamChat = SpamChat
+
+function DAS.SpamForSingle(questName, bingoString)
+	if nil == questName and nil == bingoString then return end
+	questName	= questName		or DAS.GetQuestNameFromBingoString(bingoString)
+	bingoString = bingoString 	or GetBingoStringFromQuestName(questName)
+
+	local lftext = bingoString
+
+end
+
+-- called from XML
+function DAS.SettingsButton(control, mouseButton)
+
+	local name = control:GetName():gsub("DasButton", "")
+	if name == "Spam" 		then
+    return SpamChat(mouseButton == 2)
+	elseif 	name == "Invite" 	then DAS.SetAutoInvite(not DAS.GetAutoInvite())
+	elseif  name == "Accept"	then DAS.SetAutoAcceptInvite(not DAS.GetAutoAcceptInvite())
+	elseif 	name == "Share" 	then
+		if mouseButton == 2 then
+			DAS.TryShareActiveDaily()
+		else
+			DAS.SetAutoShare(not DAS.GetAutoShare())
+		end
+	end
+
+	DAS.RefreshLabels()
+
+ end
+
+function DAS.ToggleQuest(control)
+	local questName = control["dataQuestName"] or control:GetText()
+	local completed = DAS.GetCompleted(questName)
+
+	control.dataQuestState = (completed and DAS_STATUS_OPEN) or DAS_STATUS_COMPLETE
+	if not completed then
+		control.dataIsTracked = false
+	end
+	DAS.LogQuest(questName, not completed)
+end
diff --git a/DasQuestAccept.lua b/DasQuestAccept.lua
new file mode 100644
index 0000000..3446c82
--- /dev/null
+++ b/DasQuestAccept.lua
@@ -0,0 +1,98 @@
+local chattering, wasQuestAccepted = false, false
+local optionString, optionCount, wasQuestAccepted
+
+local questStarter, questFinisher
+local unitInteract = "interact"
+
+function DAS.cacheChatterData()
+    local zoneId = DAS.GetZoneId()
+    questStarter = DAS.questStarter[zoneId] or {}
+    questFinisher = DAS.questFinisher[zoneId] or {}
+end
+
+local function HandleQuestAccepted()
+    -- Accept the quest
+    wasQuestAccepted = true
+    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_OFFERED)
+    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_ACCEPTED)
+    EndInteraction(INTERACTION_CONVERSATION)
+    wasQuestAccepted = nil
+end
+
+-- Handles the dialogue where we actually accept the quest
+local function HandleEventQuestOffered(eventCode)
+    -- Stop listening for quest offering
+    EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_ADDED, HandleQuestAccepted)
+    AcceptOfferedQuest()
+end
+
+
+-- Handles the dialogue where we actually complete the quest
+local function HandleQuestCompleteDialog(eventCode, journalIndex)
+	if not GetJournalQuestIsComplete(journalIndex) then return end
+	CompleteQuest()
+    EVENT_MANAGER:UnregisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG)
+	CompleteQuest()
+end
+
+local function HandleChatterBegin(eventCode, optionCount)
+
+    wasQuestAccepted = nil
+	if not DAS.GetSettings().autoAcceptQuest or not DAS.GetActiveIn() then return end
+    -- Ignore interactions with no options
+    if not optionCount then
+        _, optionCount = GetChatterData()
+    end
+    if optionCount == 0 then return end
+    local npcName = GetUnitName(unitInteract)
+    if not questStarter[npcName] and not questFinisher[npcName] then return end
+
+    for i = 1, optionCount do
+
+        -- Get details of option
+	    optionString, optionType = GetChatterOption(i)
+
+        -- If it is a daily quest option...
+	    if optionType == CHATTER_START_NEW_QUEST_BESTOWAL and questStarter[npcName] then
+
+			EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_OFFERED, HandleEventQuestOffered)
+           if not wasQuestAccepted then
+				-- Listen for the quest offering - Select the first option
+				SelectChatterOption(i)
+				return
+			else
+				if i == optionCount and wasQuestAccepted then
+					EndInteraction(INTERACTION_CONVERSATION)
+					wasQuestAccepted = nil
+				end
+			end
+	    -- If it is a writ quest completion option
+	    elseif optionType == CHATTER_START_ADVANCE_COMPLETABLE_QUEST_CONDITIONS and questFinisher[npcName] then
+
+
+	        -- Listen for the quest complete dialog
+	        EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG, HandleQuestCompleteDialog)
+
+	        -- Select the first option to complete the quest
+	        SelectChatterOption(1)
+
+	    -- If the goods were already placed, then complete the quest
+	    elseif optionType == CHATTER_START_COMPLETE_QUEST and questFinisher[npcName] then
+
+	        -- Listen for the quest complete dialog
+	        EVENT_MANAGER:RegisterForEvent("DAS_Chatter", EVENT_QUEST_COMPLETE_DIALOG, HandleQuestCompleteDialog)
+	        -- Select the first option to place goods and/or sign the manifest
+	        SelectChatterOption(1)
+
+	        -- Select the first option to complete the quest
+	        SelectChatterOption(1)
+        end
+    end
+    chattering = false
+end
+
+local function HandleChatterEnd()
+     chattering = false
+end
+EVENT_MANAGER:RegisterForEvent("DAS", EVENT_CHATTER_BEGIN, HandleChatterBegin)
+EVENT_MANAGER:RegisterForEvent("DAS", EVENT_CHATTER_END, HandleChatterEnd)
\ No newline at end of file
diff --git a/DasTooltip.lua b/DasTooltip.lua
new file mode 100644
index 0000000..8cdb5fa
--- /dev/null
+++ b/DasTooltip.lua
@@ -0,0 +1,80 @@
+local DAS = DailyAutoShare
+
+local function GenerateTooltipText(control)
+
+	local key = control:GetName()
+
+	if 	    string.match(key, "Invite")	then return GetString((DAS.GetAutoInvite() and DAS_SI_INVITE_TRUE) or DAS_SI_INVITE_FALSE)
+	elseif string.match(key, "Accept")	then return GetString((DAS.GetAutoAcceptShared() and DAS_SI_ACCEPT_TRUE) or DAS_SI_ACCEPT_FALSE)
+	elseif string.match(key, "Share") 	then return GetString((DAS.GetAutoShare() and DAS_SI_SHARE_TRUE) or DAS_SI_SHARE_FALSE)
+	elseif string.match(key, "Spam") 	then return GetString(DAS_SI_SPAM)
+	elseif string.match(key, "Donate") 	then return GetString(DAS_SI_DONATE)
+	elseif string.match(key, "Refresh") then return GetString(DAS_SI_REFRESH)
+	end
+
+end
+
+
+local function SetTooltipText(control)
+
+	DailyAutoShare_Tooltip:ClearLines()
+	local tooltipText = GenerateTooltipText(control)
+	DailyAutoShare_Tooltip:AddLine(tooltipText)
+	DailyAutoShare_Tooltip:SetHidden(false)
+
+	return tooltipText
+end
+function DAS.SetTooltipText(control)
+	SetTooltipText(control)
+end
+
+
+local function setTooltipOffset(control)
+	local offsetY = control:GetTop() - DasList:GetTop()
+	local isTooltipRight = DAS.GetTooltipRight()
+	-- d(tostring(control:GetTop()) .. " / " .. tostring(DasList:GetTop()))
+	local myAnchorPos 		= (isTooltipRight and TOPLEFT) or TOPRIGHT
+	local parentAnchorPos 	= (isTooltipRight and TOPRIGHT) or TOPLEFT
+
+	DailyAutoShare_Tooltip:ClearAnchors()
+	DailyAutoShare_Tooltip:SetAnchor(myAnchorPos, DasList, parentAnchorPos, 0, offsetY)
+end
+
+function DAS.CreateControlTooltip(control)
+
+	SetTooltipText(control)
+    setTooltipOffset(DasHeader)
+
+end
+
+function DAS.CreateTooltip(control)
+
+	setTooltipOffset(control)
+	SetTooltipText(control, isButton)
+
+ end
+
+function DAS.CreateLabelTooltip(control)
+
+	setTooltipOffset(control)
+	local tooltipText = ""
+	local questName = control["dataQuestName"]
+	local state = DAS.GetCompleted(questName)
+	if control["dataQuestState"] == DAS_STATUS_COMPLETE then
+		tooltipText = (questName .. " completed today with " .. GetUnitName('player'))
+	else
+		local bingoString = control["dataBingoString"] or ""
+		local bingoTooltip = (bingoString ~= "" and "\n The bingo code is " .. bingoString) or ""
+		local status = (( control["dataQuestState"] == DAS_STATUS_ACTIVE and " is acive") or " still open")
+		tooltipText = (questName .. status .. bingoTooltip)
+	end
+	DailyAutoShare_Tooltip:AddLine(tooltipText)
+	DailyAutoShare_Tooltip:SetHidden(false)
+
+ end
+
+function DAS.HideTooltip(control)
+	DailyAutoShare_Tooltip:ClearLines()
+	 DailyAutoShare_Tooltip:SetHidden(true)
+	 -- DAS.RefreshLabels()
+end
\ No newline at end of file
diff --git a/libs/LibAddonMenu-2.0/LICENSE b/libs/LibAddonMenu-2.0/LICENSE
new file mode 100644
index 0000000..f69cbd4
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/LICENSE
@@ -0,0 +1,201 @@
+               The Artistic License 2.0
+
+           Copyright (c) 2016 Ryan Lakanen (Seerah)
+
+     Everyone is permitted to copy and distribute verbatim copies
+      of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package.  If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+    "Copyright Holder" means the individual(s) or organization(s)
+    named in the copyright notice for the entire Package.
+
+    "Contributor" means any party that has contributed code or other
+    material to the Package, in accordance with the Copyright Holder's
+    procedures.
+
+    "You" and "your" means any person who would like to copy,
+    distribute, or modify the Package.
+
+    "Package" means the collection of files distributed by the
+    Copyright Holder, and derivatives of that collection and/or of
+    those files. A given Package may consist of either the Standard
+    Version, or a Modified Version.
+
+    "Distribute" means providing a copy of the Package or making it
+    accessible to anyone else, or in the case of a company or
+    organization, to others outside of your company or organization.
+
+    "Distributor Fee" means any fee that you charge for Distributing
+    this Package or providing support for this Package to another
+    party.  It does not mean licensing fees.
+
+    "Standard Version" refers to the Package if it has not been
+    modified, or has been modified only in ways explicitly requested
+    by the Copyright Holder.
+
+    "Modified Version" means the Package, if it has been changed, and
+    such changes were not explicitly requested by the Copyright
+    Holder.
+
+    "Original License" means this Artistic License as Distributed with
+    the Standard Version of the Package, in its current version or as
+    it may be modified by The Perl Foundation in the future.
+
+    "Source" form means the source code, documentation source, and
+    configuration files for the Package.
+
+    "Compiled" form means the compiled bytecode, object code, binary,
+    or any other form resulting from mechanical transformation or
+    translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1)  You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2)  You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers.  At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3)  You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder.  The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4)  You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+    (a)  make the Modified Version available to the Copyright Holder
+    of the Standard Version, under the Original License, so that the
+    Copyright Holder may include your modifications in the Standard
+    Version.
+
+    (b)  ensure that installation of your Modified Version does not
+    prevent the user installing or running the Standard Version. In
+    addition, the Modified Version must bear a name that is different
+    from the name of the Standard Version.
+
+    (c)  allow anyone who receives a copy of the Modified Version to
+    make the Source form of the Modified Version available to others
+    under
+
+    (i)  the Original License or
+
+    (ii)  a license that permits the licensee to freely copy,
+    modify and redistribute the Modified Version using the same
+    licensing terms that apply to the copy that the licensee
+    received, and requires that the Source form of the Modified
+    Version, and of any works derived from it, be made freely
+    available in that license fees are prohibited but Distributor
+    Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5)  You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version.  Such instructions must be
+valid at the time of your distribution.  If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6)  You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7)  You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package.  Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version.  In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10)  Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11)  If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12)  This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13)  This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14)  Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua b/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
new file mode 100644
index 0000000..3c4ab31
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua
@@ -0,0 +1,1226 @@
+-- LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah)         --
+-- Distributed under The Artistic License 2.0 (see LICENSE)     --
+------------------------------------------------------------------
+
+
+--Register LAM with LibStub
+local MAJOR, MINOR = "LibAddonMenu-2.0", 25
+local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lam then return end --the same or newer version of this lib is already loaded into memory
+
+local messages = {}
+local MESSAGE_PREFIX = "[LAM2] "
+local function PrintLater(msg)
+    if CHAT_SYSTEM.primaryContainer then
+        d(MESSAGE_PREFIX .. msg)
+    else
+        messages[#messages + 1] = msg
+    end
+end
+
+local function FlushMessages()
+    for i = 1, #messages do
+        d(MESSAGE_PREFIX .. messages[i])
+    end
+    messages = {}
+end
+
+if LAMSettingsPanelCreated and not LAMCompatibilityWarning then
+    PrintLater("An old version of LibAddonMenu with compatibility issues was detected. For more information on how to proceed search for LibAddonMenu on esoui.com")
+    LAMCompatibilityWarning = true
+end
+
+--UPVALUES--
+local wm = WINDOW_MANAGER
+local em = EVENT_MANAGER
+local sm = SCENE_MANAGER
+local cm = CALLBACK_MANAGER
+local tconcat = table.concat
+local tinsert = table.insert
+
+local MIN_HEIGHT = 26
+local HALF_WIDTH_LINE_SPACING = 2
+local OPTIONS_CREATION_RUNNING = 1
+local OPTIONS_CREATED = 2
+local LAM_CONFIRM_DIALOG = "LAM_CONFIRM_DIALOG"
+local LAM_DEFAULTS_DIALOG = "LAM_DEFAULTS"
+local LAM_RELOAD_DIALOG = "LAM_RELOAD_DIALOG"
+
+local addonsForList = {}
+local addonToOptionsMap = {}
+local optionsState = {}
+lam.widgets = lam.widgets or {}
+local widgets = lam.widgets
+lam.util = lam.util or {}
+local util = lam.util
+lam.controlsForReload = lam.controlsForReload or {}
+local controlsForReload = lam.controlsForReload
+
+local function GetDefaultValue(default)
+    if type(default) == "function" then
+        return default()
+    end
+    return default
+end
+
+local function GetStringFromValue(value)
+    if type(value) == "function" then
+        return value()
+    elseif type(value) == "number" then
+        return GetString(value)
+    end
+    return value
+end
+
+local function CreateBaseControl(parent, controlData, controlName)
+    local control = wm:CreateControl(controlName or controlData.reference, parent.scroll or parent, CT_CONTROL)
+    control.panel = parent.panel or parent -- if this is in a submenu, panel is the submenu's parent
+    control.data = controlData
+
+    control.isHalfWidth = controlData.width == "half"
+    local width = 510 -- set default width in case a custom parent object is passed
+    if control.panel.GetWidth ~= nil then width = control.panel:GetWidth() - 60 end
+    control:SetWidth(width)
+    return control
+end
+
+local function CreateLabelAndContainerControl(parent, controlData, controlName)
+    local control = CreateBaseControl(parent, controlData, controlName)
+    local width = control:GetWidth()
+
+    local container = wm:CreateControl(nil, control, CT_CONTROL)
+    container:SetDimensions(width / 3, MIN_HEIGHT)
+    control.container = container
+
+    local label = wm:CreateControl(nil, control, CT_LABEL)
+    label:SetFont("ZoFontWinH4")
+    label:SetHeight(MIN_HEIGHT)
+    label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+    label:SetText(GetStringFromValue(controlData.name))
+    control.label = label
+
+    if control.isHalfWidth then
+        control:SetDimensions(width / 2, MIN_HEIGHT * 2 + HALF_WIDTH_LINE_SPACING)
+        label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
+        label:SetAnchor(TOPRIGHT, control, TOPRIGHT, 0, 0)
+        container:SetAnchor(TOPRIGHT, control.label, BOTTOMRIGHT, 0, HALF_WIDTH_LINE_SPACING)
+    else
+        control:SetDimensions(width, MIN_HEIGHT)
+        container:SetAnchor(TOPRIGHT, control, TOPRIGHT, 0, 0)
+        label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
+        label:SetAnchor(TOPRIGHT, container, TOPLEFT, 5, 0)
+    end
+
+    control.data.tooltipText = GetStringFromValue(control.data.tooltip)
+    control:SetMouseEnabled(true)
+    control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+    control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    return control
+end
+
+local function GetTopPanel(panel)
+    while panel.panel and panel.panel ~= panel do
+        panel = panel.panel
+    end
+    return panel
+end
+
+local function IsSame(objA, objB)
+    if #objA ~= #objB then return false end
+    for i = 1, #objA do
+        if objA[i] ~= objB[i] then return false end
+    end
+    return true
+end
+
+local function RefreshReloadUIButton()
+    lam.requiresReload = false
+
+    for i = 1, #controlsForReload do
+        local reloadControl = controlsForReload[i]
+        if not IsSame(reloadControl.startValue, {reloadControl.data.getFunc()}) then
+            lam.requiresReload = true
+            break
+        end
+    end
+
+    lam.applyButton:SetHidden(not lam.requiresReload)
+end
+
+local function RequestRefreshIfNeeded(control)
+    -- if our parent window wants to refresh controls, then fire the callback
+    local panel = GetTopPanel(control.panel)
+    local panelData = panel.data
+    if panelData.registerForRefresh then
+        cm:FireCallbacks("LAM-RefreshPanel", control)
+    end
+    RefreshReloadUIButton()
+end
+
+local function RegisterForRefreshIfNeeded(control)
+    -- if our parent window wants to refresh controls, then add this to the list
+    local panel = GetTopPanel(control.panel)
+    local panelData = panel.data
+    if panelData.registerForRefresh or panelData.registerForDefaults then
+        tinsert(panel.controlsToRefresh or {}, control) -- prevent errors on custom panels
+    end
+end
+
+local function RegisterForReloadIfNeeded(control)
+    if control.data.requiresReload then
+        tinsert(controlsForReload, control)
+        control.startValue = {control.data.getFunc()}
+    end
+end
+
+local function GetConfirmDialog()
+    if(not ESO_Dialogs[LAM_CONFIRM_DIALOG]) then
+        ESO_Dialogs[LAM_CONFIRM_DIALOG] = {
+            canQueue = true,
+            title = {
+                text = "",
+            },
+            mainText = {
+                text = "",
+            },
+            buttons = {
+                [1] = {
+                    text = SI_DIALOG_CONFIRM,
+                    callback = function(dialog) end,
+                },
+                [2] = {
+                    text = SI_DIALOG_CANCEL,
+                }
+            }
+        }
+    end
+    return ESO_Dialogs[LAM_CONFIRM_DIALOG]
+end
+
+local function ShowConfirmationDialog(title, body, callback)
+    local dialog = GetConfirmDialog()
+    dialog.title.text = title
+    dialog.mainText.text = body
+    dialog.buttons[1].callback = callback
+    ZO_Dialogs_ShowDialog(LAM_CONFIRM_DIALOG)
+end
+
+local function GetDefaultsDialog()
+    if(not ESO_Dialogs[LAM_DEFAULTS_DIALOG]) then
+        ESO_Dialogs[LAM_DEFAULTS_DIALOG] = {
+            canQueue = true,
+            title = {
+                text = SI_INTERFACE_OPTIONS_RESET_TO_DEFAULT_TOOLTIP,
+            },
+            mainText = {
+                text = SI_OPTIONS_RESET_PROMPT,
+            },
+            buttons = {
+                [1] = {
+                    text = SI_OPTIONS_RESET,
+                    callback = function(dialog) end,
+                },
+                [2] = {
+                    text = SI_DIALOG_CANCEL,
+                }
+            }
+        }
+    end
+    return ESO_Dialogs[LAM_DEFAULTS_DIALOG]
+end
+
+local function ShowDefaultsDialog(panel)
+    local dialog = GetDefaultsDialog()
+    dialog.buttons[1].callback = function()
+        panel:ForceDefaults()
+        RefreshReloadUIButton()
+    end
+    ZO_Dialogs_ShowDialog(LAM_DEFAULTS_DIALOG)
+end
+
+local function DiscardChangesOnReloadControls()
+    for i = 1, #controlsForReload do
+        local reloadControl = controlsForReload[i]
+        if not IsSame(reloadControl.startValue, {reloadControl.data.getFunc()}) then
+            reloadControl:UpdateValue(false, unpack(reloadControl.startValue))
+        end
+    end
+    lam.requiresReload = false
+    lam.applyButton:SetHidden(true)
+end
+
+local function StorePanelForReopening()
+    local saveData = ZO_Ingame_SavedVariables["LAM"] or {}
+    saveData.reopenPanel = lam.currentAddonPanel:GetName()
+    ZO_Ingame_SavedVariables["LAM"] = saveData
+end
+
+local function RetrievePanelForReopening()
+    local saveData = ZO_Ingame_SavedVariables["LAM"]
+    if(saveData) then
+        ZO_Ingame_SavedVariables["LAM"] = nil
+        return _G[saveData.reopenPanel]
+    end
+end
+
+local function HandleReloadUIPressed()
+    StorePanelForReopening()
+    ReloadUI()
+end
+
+local function HandleLoadDefaultsPressed()
+    ShowDefaultsDialog(lam.currentAddonPanel)
+end
+
+local function GetReloadDialog()
+    if(not ESO_Dialogs[LAM_RELOAD_DIALOG]) then
+        ESO_Dialogs[LAM_RELOAD_DIALOG] = {
+            canQueue = true,
+            title = {
+                text = util.L["RELOAD_DIALOG_TITLE"],
+            },
+            mainText = {
+                text = util.L["RELOAD_DIALOG_TEXT"],
+            },
+            buttons = {
+                [1] = {
+                    text = util.L["RELOAD_DIALOG_RELOAD_BUTTON"],
+                    callback = function() ReloadUI() end,
+                },
+                [2] = {
+                    text = util.L["RELOAD_DIALOG_DISCARD_BUTTON"],
+                    callback = DiscardChangesOnReloadControls,
+                }
+            },
+            noChoiceCallback = DiscardChangesOnReloadControls,
+        }
+    end
+    return ESO_Dialogs[LAM_CONFIRM_DIALOG]
+end
+
+local function ShowReloadDialogIfNeeded()
+    if lam.requiresReload then
+        local dialog = GetReloadDialog()
+        ZO_Dialogs_ShowDialog(LAM_RELOAD_DIALOG)
+    end
+end
+
+local function UpdateWarning(control)
+    local warning
+    if control.data.warning ~= nil then
+        warning = util.GetStringFromValue(control.data.warning)
+    end
+
+    if control.data.requiresReload then
+        if not warning then
+            warning = string.format("|cff0000%s", util.L["RELOAD_UI_WARNING"])
+        else
+            warning = string.format("%s\n\n|cff0000%s", warning, util.L["RELOAD_UI_WARNING"])
+        end
+    end
+
+    if not warning then
+        control.warning:SetHidden(true)
+    else
+        control.warning.data = {tooltipText = warning}
+        control.warning:SetHidden(false)
+    end
+end
+
+local localization = {
+    en = {
+        PANEL_NAME = "Addons",
+        AUTHOR = string.format("%s: <<X:1>>", GetString(SI_ADDON_MANAGER_AUTHOR)), -- "Author: <<X:1>>"
+        VERSION = "Version: <<X:1>>",
+        WEBSITE = "Visit Website",
+        PANEL_INFO_FONT = "$(CHAT_FONT)|14|soft-shadow-thin",
+        RELOAD_UI_WARNING = "Changes to this setting require an UI reload in order to take effect.",
+        RELOAD_DIALOG_TITLE = "UI Reload required",
+        RELOAD_DIALOG_TEXT = "Some changes require an UI reload in order to take effect. Do you want to reload now or discard the changes?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Reload",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Discard",
+    },
+    it = { -- provided by JohnnyKing
+        PANEL_NAME = "Addon",
+        VERSION = "Versione: <<X:1>>",
+        WEBSITE = "Visita il Sitoweb",
+        RELOAD_UI_WARNING = "Cambiare questa impostazione richiede un Ricarica UI al fine che faccia effetto.",
+        RELOAD_DIALOG_TITLE = "Ricarica UI richiesto",
+        RELOAD_DIALOG_TEXT = "Alcune modifiche richiedono un Ricarica UI al fine che facciano effetto. Sei sicuro di voler ricaricare ora o di voler annullare le modifiche?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Ricarica",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Annulla",
+    },
+    fr = { -- provided by Ayantir
+        PANEL_NAME = "Extensions",
+        WEBSITE = "Visiter le site Web",
+        RELOAD_UI_WARNING = "La modification de ce paramètre requiert un rechargement de l'UI pour qu'il soit pris en compte.",
+        RELOAD_DIALOG_TITLE = "Reload UI requis",
+        RELOAD_DIALOG_TEXT = "Certaines modifications requièrent un rechargement de l'UI pour qu'ils soient pris en compte. Souhaitez-vous recharger l'interface maintenant ou annuler les modifications ?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Recharger",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Annuler",
+    },
+    de = { -- provided by sirinsidiator
+        PANEL_NAME = "Erweiterungen",
+        WEBSITE = "Webseite besuchen",
+        RELOAD_UI_WARNING = "Änderungen an dieser Option werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird.",
+        RELOAD_DIALOG_TITLE = "Neuladen benötigt",
+        RELOAD_DIALOG_TEXT = "Einige Änderungen werden erst übernommen nachdem die Benutzeroberfläche neu geladen wird. Wollt Ihr sie jetzt neu laden oder die Änderungen verwerfen?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Neu laden",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Verwerfen",
+    },
+    ru = { -- provided by TERAB1T
+        PANEL_NAME = "Дополнения",
+        VERSION = "Версия: <<X:1>>",
+        WEBSITE = "Посетить сайт",
+        PANEL_INFO_FONT = "RuESO/fonts/Univers57.otf|14|soft-shadow-thin",
+        RELOAD_UI_WARNING = "Для применения этой настройки необходима перезагрузка интерфейса.",
+        RELOAD_DIALOG_TITLE = "Необходима перезагрузка интерфейса",
+        RELOAD_DIALOG_TEXT = "Для применения некоторых изменений необходима перезагрузка интерфейса. Перезагрузить интерфейс сейчас или отменить изменения?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Перезагрузить",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Отменить изменения",
+    },
+    es = { -- provided by Morganlefai, checked by Kwisatz
+        PANEL_NAME = "Configuración",
+        VERSION = "Versión: <<X:1>>",
+        WEBSITE = "Visita la página web",
+        RELOAD_UI_WARNING = "Cambiar este ajuste recargará la interfaz del usuario.",
+        RELOAD_DIALOG_TITLE = "Requiere recargar la interfaz",
+        RELOAD_DIALOG_TEXT = "Algunos cambios requieren recargar la interfaz para poder aplicarse. Quieres aplicar los cambios y recargar la interfaz?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Recargar",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Cancelar",
+    },
+    jp = { -- provided by k0ta0uchi
+        PANEL_NAME = "アドオン設定",
+        WEBSITE = "ウェブサイトを見る",
+    },
+    zh = { -- provided by bssthu
+        PANEL_NAME = "插件",
+        VERSION = "版本: <<X:1>>",
+        WEBSITE = "访问网站",
+        PANEL_INFO_FONT = "EsoZh/fonts/univers57.otf|14|soft-shadow-thin",
+    },
+    pl = { -- provided by EmiruTegryfon
+        PANEL_NAME = "Dodatki",
+        VERSION = "Wersja: <<X:1>>",
+        WEBSITE = "Odwiedź stronę",
+        RELOAD_UI_WARNING = "Zmiany będą widoczne po ponownym załadowaniu UI.",
+        RELOAD_DIALOG_TITLE = "Wymagane przeładowanie UI",
+        RELOAD_DIALOG_TEXT = "Niektóre zmiany wymagają ponownego załadowania UI. Czy chcesz teraz ponownie załadować, czy porzucić zmiany?",
+        RELOAD_DIALOG_RELOAD_BUTTON = "Przeładuj",
+        RELOAD_DIALOG_DISCARD_BUTTON = "Porzuć",
+    },
+}
+
+util.L = ZO_ShallowTableCopy(localization[GetCVar("Language.2")], localization["en"])
+util.GetTooltipText = GetStringFromValue -- deprecated, use util.GetStringFromValue instead
+util.GetStringFromValue = GetStringFromValue
+util.GetDefaultValue = GetDefaultValue
+util.CreateBaseControl = CreateBaseControl
+util.CreateLabelAndContainerControl = CreateLabelAndContainerControl
+util.RequestRefreshIfNeeded = RequestRefreshIfNeeded
+util.RegisterForRefreshIfNeeded = RegisterForRefreshIfNeeded
+util.RegisterForReloadIfNeeded = RegisterForReloadIfNeeded
+util.GetTopPanel = GetTopPanel
+util.ShowConfirmationDialog = ShowConfirmationDialog
+util.UpdateWarning = UpdateWarning
+
+local ADDON_DATA_TYPE = 1
+local RESELECTING_DURING_REBUILD = true
+local USER_REQUESTED_OPEN = true
+
+
+--INTERNAL FUNCTION
+--scrolls ZO_ScrollList `list` to move the row corresponding to `data`
+-- into view (does nothing if there is no such row in the list)
+--unlike ZO_ScrollList_ScrollDataIntoView, this function accounts for
+-- fading near the list's edges - it avoids the fading area by scrolling
+-- a little further than the ZO function
+local function ScrollDataIntoView(list, data)
+    local targetIndex = data.sortIndex
+    if not targetIndex then return end
+
+    local scrollMin, scrollMax = list.scrollbar:GetMinMax()
+    local scrollTop = list.scrollbar:GetValue()
+    local controlHeight = list.uniformControlHeight or list.controlHeight
+    local targetMin = controlHeight * (targetIndex - 1) - 64
+    -- subtracting 64 ain't arbitrary, it's the maximum fading height
+    -- (libraries/zo_templates/scrolltemplates.lua/UpdateScrollFade)
+
+    if targetMin < scrollTop then
+        ZO_ScrollList_ScrollAbsolute(list, zo_max(targetMin, scrollMin))
+    else
+        local listHeight = ZO_ScrollList_GetHeight(list)
+        local targetMax = controlHeight * targetIndex + 64 - listHeight
+
+        if targetMax > scrollTop then
+            ZO_ScrollList_ScrollAbsolute(list, zo_min(targetMax, scrollMax))
+        end
+    end
+end
+
+
+--INTERNAL FUNCTION
+--constructs a string pattern from the text in `searchEdit` control
+-- * metacharacters are escaped, losing their special meaning
+-- * whitespace matches anything (including empty substring)
+--if there is nothing but whitespace, returns nil
+--otherwise returns a filter function, which takes a `data` table argument
+-- and returns true iff `data.filterText` matches the pattern
+local function GetSearchFilterFunc(searchEdit)
+    local text = searchEdit:GetText():lower()
+    local pattern = text:match("(%S+.-)%s*$")
+
+    if not pattern then -- nothing but whitespace
+        return nil
+    end
+
+    -- escape metacharacters, e.g. "ESO-Datenbank.de" => "ESO%-Datenbank%.de"
+    pattern = pattern:gsub("[-*+?^$().[%]%%]", "%%%0")
+
+    -- replace whitespace with "match shortest anything"
+    pattern = pattern:gsub("%s+", ".-")
+
+    return function(data)
+        return data.filterText:lower():find(pattern) ~= nil
+    end
+end
+
+
+--INTERNAL FUNCTION
+--populates `addonList` with entries from `addonsForList`
+-- addonList = ZO_ScrollList control
+-- filter = [optional] function(data)
+local function PopulateAddonList(addonList, filter)
+    local entryList = ZO_ScrollList_GetDataList(addonList)
+    local numEntries = 0
+    local selectedData = nil
+    local selectionIsFinal = false
+
+    ZO_ScrollList_Clear(addonList)
+
+    for i, data in ipairs(addonsForList) do
+        if not filter or filter(data) then
+            local dataEntry = ZO_ScrollList_CreateDataEntry(ADDON_DATA_TYPE, data)
+            numEntries = numEntries + 1
+            data.sortIndex = numEntries
+            entryList[numEntries] = dataEntry
+            -- select the first panel passing the filter, or the currently
+            -- shown panel, but only if it passes the filter as well
+            if selectedData == nil or data.panel == lam.pendingAddonPanel or data.panel == lam.currentAddonPanel then
+                if not selectionIsFinal then
+                    selectedData = data
+                end
+                if data.panel == lam.pendingAddonPanel then
+                    lam.pendingAddonPanel = nil
+                    selectionIsFinal = true
+                end
+            end
+        else
+            data.sortIndex = nil
+        end
+    end
+
+    ZO_ScrollList_Commit(addonList)
+
+    if selectedData then
+        if selectedData.panel == lam.currentAddonPanel then
+            ZO_ScrollList_SelectData(addonList, selectedData, nil, RESELECTING_DURING_REBUILD)
+        else
+            ZO_ScrollList_SelectData(addonList, selectedData, nil)
+        end
+        ScrollDataIntoView(addonList, selectedData)
+    end
+end
+
+
+--METHOD: REGISTER WIDGET--
+--each widget has its version checked before loading,
+--so we only have the most recent one in memory
+--Usage:
+-- widgetType = "string"; the type of widget being registered
+-- widgetVersion = integer; the widget's version number
+LAMCreateControl = LAMCreateControl or {}
+local lamcc = LAMCreateControl
+
+function lam:RegisterWidget(widgetType, widgetVersion)
+    if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
+        return false
+    else
+        widgets[widgetType] = widgetVersion
+        return true
+    end
+end
+
+-- INTERNAL METHOD: hijacks the handlers for the actions in the OptionsWindow layer if not already done
+local function InitKeybindActions()
+    if not lam.keybindsInitialized then
+        lam.keybindsInitialized = true
+        ZO_PreHook(KEYBOARD_OPTIONS, "ApplySettings", function()
+            if lam.currentPanelOpened then
+                if not lam.applyButton:IsHidden() then
+                    HandleReloadUIPressed()
+                end
+                return true
+            end
+        end)
+        ZO_PreHook("ZO_Dialogs_ShowDialog", function(dialogName)
+            if lam.currentPanelOpened and dialogName == "OPTIONS_RESET_TO_DEFAULTS" then
+                if not lam.defaultButton:IsHidden() then
+                    HandleLoadDefaultsPressed()
+                end
+                return true
+            end
+        end)
+    end
+end
+
+-- INTERNAL METHOD: fires the LAM-PanelOpened callback if not already done
+local function OpenCurrentPanel()
+    if lam.currentAddonPanel and not lam.currentPanelOpened then
+        lam.currentPanelOpened = true
+        lam.defaultButton:SetHidden(not lam.currentAddonPanel.data.registerForDefaults)
+        cm:FireCallbacks("LAM-PanelOpened", lam.currentAddonPanel)
+    end
+end
+
+-- INTERNAL METHOD: fires the LAM-PanelClosed callback if not already done
+local function CloseCurrentPanel()
+    if lam.currentAddonPanel and lam.currentPanelOpened then
+        lam.currentPanelOpened = false
+        cm:FireCallbacks("LAM-PanelClosed", lam.currentAddonPanel)
+    end
+end
+
+--METHOD: OPEN TO ADDON PANEL--
+--opens to a specific addon's option panel
+--Usage:
+-- panel = userdata; the panel returned by the :RegisterOptionsPanel method
+local locSettings = GetString(SI_GAME_MENU_SETTINGS)
+function lam:OpenToPanel(panel)
+
+    -- find and select the panel's row in addon list
+
+    local addonList = lam.addonList
+    local selectedData = nil
+
+    for _, addonData in ipairs(addonsForList) do
+        if addonData.panel == panel then
+            selectedData = addonData
+            ScrollDataIntoView(addonList, selectedData)
+            lam.pendingAddonPanel = addonData.panel
+            break
+        end
+    end
+
+    ZO_ScrollList_SelectData(addonList, selectedData)
+    ZO_ScrollList_RefreshVisible(addonList, selectedData)
+
+    local srchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit")
+    srchEdit:Clear()
+
+    -- note that ZO_ScrollList doesn't require `selectedData` to be actually
+    -- present in the list, and that the list will only be populated once LAM
+    -- "Addon Settings" menu entry is selected for the first time
+
+    local function openAddonSettingsMenu()
+        local gameMenu = ZO_GameMenu_InGame.gameMenu
+        local settingsMenu = gameMenu.headerControls[locSettings]
+
+        if settingsMenu then -- an instance of ZO_TreeNode
+            local children = settingsMenu:GetChildren()
+            for i = 1, (children and #children or 0) do
+                local childNode = children[i]
+                local data = childNode:GetData()
+                if data and data.id == lam.panelId then
+                    -- found LAM "Addon Settings" node, yay!
+                    childNode:GetTree():SelectNode(childNode)
+                    break
+                end
+            end
+        end
+    end
+
+    if sm:GetScene("gameMenuInGame"):GetState() == SCENE_SHOWN then
+        openAddonSettingsMenu()
+    else
+        sm:CallWhen("gameMenuInGame", SCENE_SHOWN, openAddonSettingsMenu)
+        sm:Show("gameMenuInGame")
+    end
+end
+
+local TwinOptionsContainer_Index = 0
+local function TwinOptionsContainer(parent, leftWidget, rightWidget)
+    TwinOptionsContainer_Index = TwinOptionsContainer_Index + 1
+    local cParent = parent.scroll or parent
+    local panel = parent.panel or cParent
+    local container = wm:CreateControl("$(parent)TwinContainer" .. tostring(TwinOptionsContainer_Index),
+        cParent, CT_CONTROL)
+    container:SetResizeToFitDescendents(true)
+    container:SetAnchor(select(2, leftWidget:GetAnchor(0) ))
+
+    leftWidget:ClearAnchors()
+    leftWidget:SetAnchor(TOPLEFT, container, TOPLEFT)
+    rightWidget:SetAnchor(TOPLEFT, leftWidget, TOPRIGHT, 5, 0)
+
+    leftWidget:SetWidth( leftWidget:GetWidth() - 2.5 ) -- fixes bad alignment with 'full' controls
+    rightWidget:SetWidth( rightWidget:GetWidth() - 2.5 )
+
+    leftWidget:SetParent(container)
+    rightWidget:SetParent(container)
+
+    container.data = {type = "container"}
+    container.panel = panel
+    return container
+end
+
+--INTERNAL FUNCTION
+--creates controls when options panel is first shown
+--controls anchoring of these controls in the panel
+local function CreateOptionsControls(panel)
+    local addonID = panel:GetName()
+    if(optionsState[addonID] == OPTIONS_CREATED) then
+        return false
+    elseif(optionsState[addonID] == OPTIONS_CREATION_RUNNING) then
+        return true
+    end
+    optionsState[addonID] = OPTIONS_CREATION_RUNNING
+
+    local function CreationFinished()
+        optionsState[addonID] = OPTIONS_CREATED
+        cm:FireCallbacks("LAM-PanelControlsCreated", panel)
+        OpenCurrentPanel()
+    end
+
+    local optionsTable = addonToOptionsMap[addonID]
+    if optionsTable then
+        local function CreateAndAnchorWidget(parent, widgetData, offsetX, offsetY, anchorTarget, wasHalf)
+            local widget
+            local status, err = pcall(function() widget = LAMCreateControl[widgetData.type](parent, widgetData) end)
+            if not status then
+                return err or true, offsetY, anchorTarget, wasHalf
+            else
+                local isHalf = (widgetData.width == "half")
+                if not anchorTarget then -- the first widget in a panel is just placed in the top left corner
+                    widget:SetAnchor(TOPLEFT)
+                    anchorTarget = widget
+                elseif wasHalf and isHalf then -- when the previous widget was only half width and this one is too, we place it on the right side
+                    widget.lineControl = anchorTarget
+                    isHalf = false
+                    offsetY = 0
+                    anchorTarget = TwinOptionsContainer(parent, anchorTarget, widget)
+                else -- otherwise we just put it below the previous one normally
+                    widget:SetAnchor(TOPLEFT, anchorTarget, BOTTOMLEFT, 0, 15)
+                    offsetY = 0
+                    anchorTarget = widget
+                end
+                return false, offsetY, anchorTarget, isHalf
+            end
+        end
+
+        local THROTTLE_TIMEOUT, THROTTLE_COUNT = 10, 20
+        local fifo = {}
+        local anchorOffset, lastAddedControl, wasHalf
+        local CreateWidgetsInPanel, err
+
+        local function PrepareForNextPanel()
+            anchorOffset, lastAddedControl, wasHalf = 0, nil, false
+        end
+
+        local function SetupCreationCalls(parent, widgetDataTable)
+            fifo[#fifo + 1] = PrepareForNextPanel
+            local count = #widgetDataTable
+            for i = 1, count, THROTTLE_COUNT do
+                fifo[#fifo + 1] = function()
+                    CreateWidgetsInPanel(parent, widgetDataTable, i, zo_min(i + THROTTLE_COUNT - 1, count))
+                end
+            end
+            return count ~= NonContiguousCount(widgetDataTable)
+        end
+
+        CreateWidgetsInPanel = function(parent, widgetDataTable, startIndex, endIndex)
+            for i=startIndex,endIndex do
+                local widgetData = widgetDataTable[i]
+                if not widgetData then
+                    PrintLater("Skipped creation of missing entry in the settings menu of " .. addonID .. ".")
+                else
+                    local widgetType = widgetData.type
+                    local offsetX = 0
+                    local isSubmenu = (widgetType == "submenu")
+                    if isSubmenu then
+                        wasHalf = false
+                        offsetX = 5
+                    end
+
+                    err, anchorOffset, lastAddedControl, wasHalf = CreateAndAnchorWidget(parent, widgetData, offsetX, anchorOffset, lastAddedControl, wasHalf)
+                    if err then
+                        PrintLater(("Could not create %s '%s' of %s."):format(widgetData.type, GetStringFromValue(widgetData.name or "unnamed"), addonID))
+                    end
+
+                    if isSubmenu then
+                        if SetupCreationCalls(lastAddedControl, widgetData.controls) then
+                            PrintLater(("The sub menu '%s' of %s is missing some entries."):format(GetStringFromValue(widgetData.name or "unnamed"), addonID))
+                        end
+                    end
+                end
+            end
+        end
+
+        local function DoCreateSettings()
+            if #fifo > 0 then
+                local nextCall = table.remove(fifo, 1)
+                nextCall()
+                if(nextCall == PrepareForNextPanel) then
+                    DoCreateSettings()
+                else
+                    zo_callLater(DoCreateSettings, THROTTLE_TIMEOUT)
+                end
+            else
+                CreationFinished()
+            end
+        end
+
+        if SetupCreationCalls(panel, optionsTable) then
+            PrintLater(("The settings menu of %s is missing some entries."):format(addonID))
+        end
+        DoCreateSettings()
+    else
+        CreationFinished()
+    end
+
+    return true
+end
+
+--INTERNAL FUNCTION
+--handles switching between panels
+local function ToggleAddonPanels(panel) --called in OnShow of newly shown panel
+    local currentlySelected = lam.currentAddonPanel
+    if currentlySelected and currentlySelected ~= panel then
+        currentlySelected:SetHidden(true)
+        CloseCurrentPanel()
+    end
+    lam.currentAddonPanel = panel
+
+    -- refresh visible rows to reflect panel IsHidden status
+    ZO_ScrollList_RefreshVisible(lam.addonList)
+
+    if not CreateOptionsControls(panel) then
+        OpenCurrentPanel()
+    end
+
+    cm:FireCallbacks("LAM-RefreshPanel", panel)
+end
+
+local CheckSafetyAndInitialize
+
+--METHOD: REGISTER ADDON PANEL
+--registers your addon with LibAddonMenu and creates a panel
+--Usage:
+-- addonID = "string"; unique ID which will be the global name of your panel
+-- panelData = table; data object for your panel - see controls\panel.lua
+function lam:RegisterAddonPanel(addonID, panelData)
+    CheckSafetyAndInitialize(addonID)
+    local container = lam:GetAddonPanelContainer()
+    local panel = lamcc.panel(container, panelData, addonID) --addonID==global name of panel
+    panel:SetHidden(true)
+    panel:SetAnchorFill(container)
+    panel:SetHandler("OnShow", ToggleAddonPanels)
+
+    local function stripMarkup(str)
+        return str:gsub("|[Cc]%x%x%x%x%x%x", ""):gsub("|[Rr]", "")
+    end
+
+    local filterParts = {panelData.name, nil, nil}
+    -- append keywords and author separately, the may be nil
+    filterParts[#filterParts + 1] = panelData.keywords
+    filterParts[#filterParts + 1] = panelData.author
+
+    local addonData = {
+        panel = panel,
+        name = stripMarkup(panelData.name),
+        filterText = stripMarkup(tconcat(filterParts, "\t")):lower(),
+    }
+
+    tinsert(addonsForList, addonData)
+
+    if panelData.slashCommand then
+        SLASH_COMMANDS[panelData.slashCommand] = function()
+            lam:OpenToPanel(panel)
+        end
+    end
+
+    return panel --return for authors creating options manually
+end
+
+
+--METHOD: REGISTER OPTION CONTROLS
+--registers the options you want shown for your addon
+--these are stored in a table where each key-value pair is the order
+--of the options in the panel and the data for that control, respectively
+--see exampleoptions.lua for an example
+--see controls\<widget>.lua for each widget type
+--Usage:
+-- addonID = "string"; the same string passed to :RegisterAddonPanel
+-- optionsTable = table; the table containing all of the options controls and their data
+function lam:RegisterOptionControls(addonID, optionsTable) --optionsTable = {sliderData, buttonData, etc}
+    addonToOptionsMap[addonID] = optionsTable
+end
+
+--INTERNAL FUNCTION
+--creates LAM's Addon Settings entry in ZO_GameMenu
+local function CreateAddonSettingsMenuEntry()
+    local panelData = {
+        id = KEYBOARD_OPTIONS.currentPanelId,
+        name = util.L["PANEL_NAME"],
+    }
+
+    KEYBOARD_OPTIONS.currentPanelId = panelData.id + 1
+    KEYBOARD_OPTIONS.panelNames[panelData.id] = panelData.name
+
+    lam.panelId = panelData.id
+
+    local addonListSorted = false
+
+    function panelData.callback()
+        sm:AddFragment(lam:GetAddonSettingsFragment())
+        KEYBOARD_OPTIONS:ChangePanels(lam.panelId)
+
+        local title = LAMAddonSettingsWindow:GetNamedChild("Title")
+        title:SetText(panelData.name)
+
+        if not addonListSorted and #addonsForList > 0 then
+            local searchEdit = LAMAddonSettingsWindow:GetNamedChild("SearchFilterEdit")
+            --we're about to show our list for the first time - let's sort it
+            table.sort(addonsForList, function(a, b) return a.name < b.name end)
+            PopulateAddonList(lam.addonList, GetSearchFilterFunc(searchEdit))
+            addonListSorted = true
+        end
+    end
+
+    function panelData.unselectedCallback()
+        sm:RemoveFragment(lam:GetAddonSettingsFragment())
+        if SetCameraOptionsPreviewModeEnabled then -- available since API version 100011
+            SetCameraOptionsPreviewModeEnabled(false)
+        end
+    end
+
+    ZO_GameMenu_AddSettingPanel(panelData)
+end
+
+
+--INTERNAL FUNCTION
+--creates the left-hand menu in LAM's window
+local function CreateAddonList(name, parent)
+    local addonList = wm:CreateControlFromVirtual(name, parent, "ZO_ScrollList")
+
+    local function addonListRow_OnMouseDown(control, button)
+        if button == 1 then
+            local data = ZO_ScrollList_GetData(control)
+            ZO_ScrollList_SelectData(addonList, data, control)
+        end
+    end
+
+    local function addonListRow_OnMouseEnter(control)
+        ZO_ScrollList_MouseEnter(addonList, control)
+    end
+
+    local function addonListRow_OnMouseExit(control)
+        ZO_ScrollList_MouseExit(addonList, control)
+    end
+
+    local function addonListRow_Select(previouslySelectedData, selectedData, reselectingDuringRebuild)
+        if not reselectingDuringRebuild then
+            if previouslySelectedData then
+                previouslySelectedData.panel:SetHidden(true)
+            end
+            if selectedData then
+                selectedData.panel:SetHidden(false)
+                PlaySound(SOUNDS.MENU_SUBCATEGORY_SELECTION)
+            end
+        end
+    end
+
+    local function addonListRow_Setup(control, data)
+        control:SetText(data.name)
+        control:SetSelected(not data.panel:IsHidden())
+    end
+
+    ZO_ScrollList_AddDataType(addonList, ADDON_DATA_TYPE, "ZO_SelectableLabel", 28, addonListRow_Setup)
+    -- I don't know how to make highlights clear properly; they often
+    -- get stuck and after a while the list is full of highlighted rows
+    --ZO_ScrollList_EnableHighlight(addonList, "ZO_ThinListHighlight")
+    ZO_ScrollList_EnableSelection(addonList, "ZO_ThinListHighlight", addonListRow_Select)
+
+    local addonDataType = ZO_ScrollList_GetDataTypeTable(addonList, ADDON_DATA_TYPE)
+    local addonListRow_CreateRaw = addonDataType.pool.m_Factory
+
+    local function addonListRow_Create(pool)
+        local control = addonListRow_CreateRaw(pool)
+        control:SetHandler("OnMouseDown", addonListRow_OnMouseDown)
+        --control:SetHandler("OnMouseEnter", addonListRow_OnMouseEnter)
+        --control:SetHandler("OnMouseExit", addonListRow_OnMouseExit)
+        control:SetHeight(28)
+        control:SetFont("ZoFontHeader")
+        control:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
+        control:SetVerticalAlignment(TEXT_ALIGN_CENTER)
+        control:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+        return control
+    end
+
+    addonDataType.pool.m_Factory = addonListRow_Create
+
+    return addonList
+end
+
+
+--INTERNAL FUNCTION
+local function CreateSearchFilterBox(name, parent)
+    local boxControl = wm:CreateControl(name, parent, CT_CONTROL)
+
+    local srchButton =  wm:CreateControl("$(parent)Button", boxControl, CT_BUTTON)
+    srchButton:SetDimensions(32, 32)
+    srchButton:SetAnchor(LEFT, nil, LEFT, 2, 0)
+    srchButton:SetNormalTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_up.dds")
+    srchButton:SetPressedTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_down.dds")
+    srchButton:SetMouseOverTexture("EsoUI/Art/LFG/LFG_tabIcon_groupTools_over.dds")
+
+    local srchEdit = wm:CreateControlFromVirtual("$(parent)Edit", boxControl, "ZO_DefaultEdit")
+    srchEdit:SetAnchor(LEFT, srchButton, RIGHT, 4, 1)
+    srchEdit:SetAnchor(RIGHT, nil, RIGHT, -4, 1)
+    srchEdit:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
+
+    local srchBg = wm:CreateControl("$(parent)Bg", boxControl, CT_BACKDROP)
+    srchBg:SetAnchorFill()
+    srchBg:SetAlpha(0)
+    srchBg:SetCenterColor(0, 0, 0, 0.5)
+    srchBg:SetEdgeColor(ZO_DISABLED_TEXT:UnpackRGBA())
+    srchBg:SetEdgeTexture("", 1, 1, 0, 0)
+
+    -- search backdrop should appear whenever you hover over either
+    -- the magnifying glass button or the edit field (which is only
+    -- visible when it contains some text), and also while the edit
+    -- field has keyboard focus
+
+    local srchActive = false
+    local srchHover = false
+
+    local function srchBgUpdateAlpha()
+        if srchActive or srchEdit:HasFocus() then
+            srchBg:SetAlpha(srchHover and 0.8 or 0.6)
+        else
+            srchBg:SetAlpha(srchHover and 0.6 or 0.0)
+        end
+    end
+
+    local function srchMouseEnter(control)
+        srchHover = true
+        srchBgUpdateAlpha()
+    end
+
+    local function srchMouseExit(control)
+        srchHover = false
+        srchBgUpdateAlpha()
+    end
+
+    boxControl:SetMouseEnabled(true)
+    boxControl:SetHitInsets(1, 1, -1, -1)
+    boxControl:SetHandler("OnMouseEnter", srchMouseEnter)
+    boxControl:SetHandler("OnMouseExit", srchMouseExit)
+
+    srchButton:SetHandler("OnMouseEnter", srchMouseEnter)
+    srchButton:SetHandler("OnMouseExit", srchMouseExit)
+
+    local focusLostTime = 0
+
+    srchButton:SetHandler("OnClicked", function(self)
+        srchEdit:Clear()
+        if GetFrameTimeMilliseconds() - focusLostTime < 100 then
+            -- re-focus the edit box if it lost focus due to this
+            -- button click (note that this handler may run a few
+            -- frames later)
+            srchEdit:TakeFocus()
+        end
+    end)
+
+    srchEdit:SetHandler("OnMouseEnter", srchMouseEnter)
+    srchEdit:SetHandler("OnMouseExit", srchMouseExit)
+    srchEdit:SetHandler("OnFocusGained", srchBgUpdateAlpha)
+
+    srchEdit:SetHandler("OnFocusLost", function()
+        focusLostTime = GetFrameTimeMilliseconds()
+        srchBgUpdateAlpha()
+    end)
+
+    srchEdit:SetHandler("OnEscape", function(self)
+        self:Clear()
+        self:LoseFocus()
+    end)
+
+    srchEdit:SetHandler("OnTextChanged", function(self)
+        local filterFunc = GetSearchFilterFunc(self)
+        if filterFunc then
+            srchActive = true
+            srchBg:SetEdgeColor(ZO_SECOND_CONTRAST_TEXT:UnpackRGBA())
+            srchButton:SetState(BSTATE_PRESSED)
+        else
+            srchActive = false
+            srchBg:SetEdgeColor(ZO_DISABLED_TEXT:UnpackRGBA())
+            srchButton:SetState(BSTATE_NORMAL)
+        end
+        srchBgUpdateAlpha()
+        PopulateAddonList(lam.addonList, filterFunc)
+        PlaySound(SOUNDS.SPINNER_DOWN)
+    end)
+
+    return boxControl
+end
+
+
+--INTERNAL FUNCTION
+--creates LAM's Addon Settings top-level window
+local function CreateAddonSettingsWindow()
+    local tlw = wm:CreateTopLevelWindow("LAMAddonSettingsWindow")
+    tlw:SetHidden(true)
+    tlw:SetDimensions(1010, 914) -- same height as ZO_OptionsWindow
+
+    ZO_ReanchorControlForLeftSidePanel(tlw)
+
+    -- create black background for the window (mimic ZO_RightFootPrintBackground)
+
+    local bgLeft = wm:CreateControl("$(parent)BackgroundLeft", tlw, CT_TEXTURE)
+    bgLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_left.dds")
+    bgLeft:SetDimensions(1024, 1024)
+    bgLeft:SetAnchor(TOPLEFT, nil, TOPLEFT)
+    bgLeft:SetDrawLayer(DL_BACKGROUND)
+    bgLeft:SetExcludeFromResizeToFitExtents(true)
+
+    local bgRight = wm:CreateControl("$(parent)BackgroundRight", tlw, CT_TEXTURE)
+    bgRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_right.dds")
+    bgRight:SetDimensions(64, 1024)
+    bgRight:SetAnchor(TOPLEFT, bgLeft, TOPRIGHT)
+    bgRight:SetDrawLayer(DL_BACKGROUND)
+    bgRight:SetExcludeFromResizeToFitExtents(true)
+
+    -- create gray background for addon list (mimic ZO_TreeUnderlay)
+
+    local underlayLeft = wm:CreateControl("$(parent)UnderlayLeft", tlw, CT_TEXTURE)
+    underlayLeft:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_left.dds")
+    underlayLeft:SetDimensions(256, 1024)
+    underlayLeft:SetAnchor(TOPLEFT, bgLeft, TOPLEFT)
+    underlayLeft:SetDrawLayer(DL_BACKGROUND)
+    underlayLeft:SetExcludeFromResizeToFitExtents(true)
+
+    local underlayRight = wm:CreateControl("$(parent)UnderlayRight", tlw, CT_TEXTURE)
+    underlayRight:SetTexture("EsoUI/Art/Miscellaneous/centerscreen_indexArea_right.dds")
+    underlayRight:SetDimensions(128, 1024)
+    underlayRight:SetAnchor(TOPLEFT, underlayLeft, TOPRIGHT)
+    underlayRight:SetDrawLayer(DL_BACKGROUND)
+    underlayRight:SetExcludeFromResizeToFitExtents(true)
+
+    -- create title bar (mimic ZO_OptionsWindow)
+
+    local title = wm:CreateControl("$(parent)Title", tlw, CT_LABEL)
+    title:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 70)
+    title:SetFont("ZoFontWinH1")
+    title:SetModifyTextType(MODIFY_TEXT_TYPE_UPPERCASE)
+
+    local divider = wm:CreateControlFromVirtual("$(parent)Divider", tlw, "ZO_Options_Divider")
+    divider:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 108)
+
+    -- create search filter box
+
+    local srchBox = CreateSearchFilterBox("$(parent)SearchFilter", tlw)
+    srchBox:SetAnchor(TOPLEFT, nil, TOPLEFT, 63, 120)
+    srchBox:SetDimensions(260, 30)
+
+    -- create scrollable addon list
+
+    local addonList = CreateAddonList("$(parent)AddonList", tlw)
+    addonList:SetAnchor(TOPLEFT, nil, TOPLEFT, 65, 160)
+    addonList:SetDimensions(285, 665)
+
+    lam.addonList = addonList -- for easy access from elsewhere
+
+    -- create container for option panels
+
+    local panelContainer = wm:CreateControl("$(parent)PanelContainer", tlw, CT_CONTROL)
+    panelContainer:SetAnchor(TOPLEFT, nil, TOPLEFT, 365, 120)
+    panelContainer:SetDimensions(645, 675)
+
+    local defaultButton = wm:CreateControlFromVirtual("$(parent)ResetToDefaultButton", tlw, "ZO_DialogButton")
+    ZO_KeybindButtonTemplate_Setup(defaultButton, "OPTIONS_LOAD_DEFAULTS", HandleLoadDefaultsPressed, GetString(SI_OPTIONS_DEFAULTS))
+    defaultButton:SetAnchor(TOPLEFT, panelContainer, BOTTOMLEFT, 0, 2)
+    lam.defaultButton = defaultButton
+
+    local applyButton = wm:CreateControlFromVirtual("$(parent)ApplyButton", tlw, "ZO_DialogButton")
+    ZO_KeybindButtonTemplate_Setup(applyButton, "OPTIONS_APPLY_CHANGES", HandleReloadUIPressed, GetString(SI_ADDON_MANAGER_RELOAD))
+    applyButton:SetAnchor(TOPRIGHT, panelContainer, BOTTOMRIGHT, 0, 2)
+    applyButton:SetHidden(true)
+    lam.applyButton = applyButton
+
+    return tlw
+end
+
+
+--INITIALIZING
+local safeToInitialize = false
+local hasInitialized = false
+
+local eventHandle = table.concat({MAJOR, MINOR}, "r")
+local function OnLoad(_, addonName)
+    -- wait for the first loaded event
+    em:UnregisterForEvent(eventHandle, EVENT_ADD_ON_LOADED)
+    safeToInitialize = true
+end
+em:RegisterForEvent(eventHandle, EVENT_ADD_ON_LOADED, OnLoad)
+
+local function OnActivated(_, initial)
+    em:UnregisterForEvent(eventHandle, EVENT_PLAYER_ACTIVATED)
+    FlushMessages()
+
+    local reopenPanel = RetrievePanelForReopening()
+    if not initial and reopenPanel then
+        lam:OpenToPanel(reopenPanel)
+    end
+end
+em:RegisterForEvent(eventHandle, EVENT_PLAYER_ACTIVATED, OnActivated)
+
+function CheckSafetyAndInitialize(addonID)
+    if not safeToInitialize then
+        local msg = string.format("The panel with id '%s' was registered before addon loading has completed. This might break the AddOn Settings menu.", addonID)
+        PrintLater(msg)
+    end
+    if not hasInitialized then
+        hasInitialized = true
+    end
+end
+
+
+--TODO documentation
+function lam:GetAddonPanelContainer()
+    local fragment = lam:GetAddonSettingsFragment()
+    local window = fragment:GetControl()
+    return window:GetNamedChild("PanelContainer")
+end
+
+
+--TODO documentation
+function lam:GetAddonSettingsFragment()
+    assert(hasInitialized or safeToInitialize)
+    if not LAMAddonSettingsFragment then
+        local window = CreateAddonSettingsWindow()
+        LAMAddonSettingsFragment = ZO_FadeSceneFragment:New(window, true, 100)
+        LAMAddonSettingsFragment:RegisterCallback("StateChange", function(oldState, newState)
+            if(newState == SCENE_FRAGMENT_SHOWN) then
+                InitKeybindActions()
+                PushActionLayerByName("OptionsWindow")
+                OpenCurrentPanel()
+            elseif(newState == SCENE_FRAGMENT_HIDDEN) then
+                CloseCurrentPanel()
+                RemoveActionLayerByName("OptionsWindow")
+                ShowReloadDialogIfNeeded()
+            end
+        end)
+        CreateAddonSettingsMenuEntry()
+    end
+    return LAMAddonSettingsFragment
+end
diff --git a/libs/LibAddonMenu-2.0/controls/button.lua b/libs/LibAddonMenu-2.0/controls/button.lua
new file mode 100644
index 0000000..82b5032
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/button.lua
@@ -0,0 +1,91 @@
+--[[buttonData = {
+    type = "button",
+    name = "My Button", -- string id or function returning a string
+    func = function() end,
+    tooltip = "Button's tooltip text.", -- string id or function returning a string (optional)
+    width = "full", --or "half" (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    icon = "icon\\path.dds", --(optional)
+    isDangerous = false, -- boolean, if set to true, the button text will be red and a confirmation dialog with the button label and warning text will show on click before the callback is executed (optional)
+    warning = "Will need to reload the UI.", --(optional)
+    reference = "MyAddonButton", -- unique global reference to control (optional)
+} ]]
+
+local widgetVersion = 11
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("button", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local function UpdateDisabled(control)
+    local disable = control.data.disabled
+    if type(disable) == "function" then
+        disable = disable()
+    end
+    control.button:SetEnabled(not disable)
+end
+
+--controlName is optional
+local MIN_HEIGHT = 28 -- default_button height
+local HALF_WIDTH_LINE_SPACING = 2
+function LAMCreateControl.button(parent, buttonData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, buttonData, controlName)
+    control:SetMouseEnabled(true)
+
+    local width = control:GetWidth()
+    if control.isHalfWidth then
+        control:SetDimensions(width / 2, MIN_HEIGHT * 2 + HALF_WIDTH_LINE_SPACING)
+    else
+        control:SetDimensions(width, MIN_HEIGHT)
+    end
+
+    if buttonData.icon then
+        control.button = wm:CreateControl(nil, control, CT_BUTTON)
+        control.button:SetDimensions(26, 26)
+        control.button:SetNormalTexture(buttonData.icon)
+        control.button:SetPressedOffset(2, 2)
+    else
+        --control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton")
+        control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton")
+        control.button:SetWidth(width / 3)
+        control.button:SetText(LAM.util.GetStringFromValue(buttonData.name))
+        if buttonData.isDangerous then control.button:SetNormalFontColor(ZO_ERROR_COLOR:UnpackRGBA()) end
+    end
+    local button = control.button
+    button:SetAnchor(control.isHalfWidth and CENTER or RIGHT)
+    button:SetClickSound("Click")
+    button.data = {tooltipText = LAM.util.GetStringFromValue(buttonData.tooltip)}
+    button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+    button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    button:SetHandler("OnClicked", function(...)
+        local args = {...}
+        local function callback()
+            buttonData.func(unpack(args))
+            LAM.util.RequestRefreshIfNeeded(control)
+        end
+
+        if(buttonData.isDangerous) then
+            local title = LAM.util.GetStringFromValue(buttonData.name)
+            local body = LAM.util.GetStringFromValue(buttonData.warning)
+            LAM.util.ShowConfirmationDialog(title, body, callback)
+        else
+            callback()
+        end
+    end)
+
+    if buttonData.warning ~= nil then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    if buttonData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/checkbox.lua b/libs/LibAddonMenu-2.0/controls/checkbox.lua
new file mode 100644
index 0000000..6696dd7
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/checkbox.lua
@@ -0,0 +1,142 @@
+--[[checkboxData = {
+    type = "checkbox",
+    name = "My Checkbox", -- or string id or function returning a string
+    getFunc = function() return db.var end,
+    setFunc = function(value) db.var = value doStuff() end,
+    tooltip = "Checkbox's tooltip text.", -- or string id or function returning a string (optional)
+    width = "full", -- or "half" (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = defaults.var, -- a boolean or function that returns a boolean (optional)
+    reference = "MyAddonCheckbox", -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 14
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("checkbox", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+--label
+local enabledColor = ZO_DEFAULT_ENABLED_COLOR
+local enabledHLcolor = ZO_HIGHLIGHT_TEXT
+local disabledColor = ZO_DEFAULT_DISABLED_COLOR
+local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR
+--checkbox
+local checkboxColor = ZO_NORMAL_TEXT
+local checkboxHLcolor = ZO_HIGHLIGHT_TEXT
+
+
+local function UpdateDisabled(control)
+    local disable
+    if type(control.data.disabled) == "function" then
+        disable = control.data.disabled()
+    else
+        disable = control.data.disabled
+    end
+
+    control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA())
+    control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA())
+    --control:SetMouseEnabled(not disable)
+    --control:SetMouseEnabled(true)
+
+    control.isDisabled = disable
+end
+
+local function ToggleCheckbox(control)
+    if control.value then
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+        control.checkbox:SetText(control.checkedText)
+    else
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+        control.checkbox:SetText(control.uncheckedText)
+    end
+end
+
+local function UpdateValue(control, forceDefault, value)
+    if forceDefault then --if we are forcing defaults
+        value = LAM.util.GetDefaultValue(control.data.default)
+        control.data.setFunc(value)
+    elseif value ~= nil then --our value could be false
+        control.data.setFunc(value)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        value = control.data.getFunc()
+    end
+    control.value = value
+
+    ToggleCheckbox(control)
+end
+
+local function OnMouseEnter(control)
+    ZO_Options_OnMouseEnter(control)
+
+    if control.isDisabled then return end
+
+    local label = control.label
+    if control.value then
+        label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
+    else
+        label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+    end
+    control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA())
+end
+
+local function OnMouseExit(control)
+    ZO_Options_OnMouseExit(control)
+
+    if control.isDisabled then return end
+
+    local label = control.label
+    if control.value then
+        label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    else
+        label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+    end
+    control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
+end
+
+--controlName is optional
+function LAMCreateControl.checkbox(parent, checkboxData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, checkboxData, controlName)
+    control:SetHandler("OnMouseEnter", OnMouseEnter)
+    control:SetHandler("OnMouseExit", OnMouseExit)
+    control:SetHandler("OnMouseUp", function(control)
+        if control.isDisabled then return end
+        PlaySound(SOUNDS.DEFAULT_CLICK)
+        control.value = not control.value
+        control:UpdateValue(false, control.value)
+    end)
+
+    control.checkbox = wm:CreateControl(nil, control.container, CT_LABEL)
+    local checkbox = control.checkbox
+    checkbox:SetAnchor(LEFT, control.container, LEFT, 0, 0)
+    checkbox:SetFont("ZoFontGameBold")
+    checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
+    control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper()
+    control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper()
+
+    if checkboxData.warning ~= nil or checkboxData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.data.tooltipText = LAM.util.GetStringFromValue(checkboxData.tooltip)
+
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+    if checkboxData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/colorpicker.lua b/libs/LibAddonMenu-2.0/controls/colorpicker.lua
new file mode 100644
index 0000000..a57aab0
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/colorpicker.lua
@@ -0,0 +1,106 @@
+--[[colorpickerData = {
+    type = "colorpicker",
+    name = "My Color Picker", -- or string id or function returning a string
+    getFunc = function() return db.r, db.g, db.b, db.a end, --(alpha is optional)
+    setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end, --(alpha is optional)
+    tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
+    width = "full", --or "half" (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a}, --(optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a]) or a function that returns the color
+    reference = "MyAddonColorpicker" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 13
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local function UpdateDisabled(control)
+    local disable
+    if type(control.data.disabled) == "function" then
+        disable = control.data.disabled()
+    else
+        disable = control.data.disabled
+    end
+
+    if disable then
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+    else
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    end
+
+    control.isDisabled = disable
+end
+
+local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA)
+    if forceDefault then --if we are forcing defaults
+        local color = LAM.util.GetDefaultValue(control.data.default)
+        valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a
+        control.data.setFunc(valueR, valueG, valueB, valueA)
+    elseif valueR and valueG and valueB then
+        control.data.setFunc(valueR, valueG, valueB, valueA or 1)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        valueR, valueG, valueB, valueA = control.data.getFunc()
+    end
+
+    control.thumb:SetColor(valueR, valueG, valueB, valueA or 1)
+end
+
+function LAMCreateControl.colorpicker(parent, colorpickerData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, colorpickerData, controlName)
+
+    control.color = control.container
+    local color = control.color
+
+    control.thumb = wm:CreateControl(nil, color, CT_TEXTURE)
+    local thumb = control.thumb
+    thumb:SetDimensions(36, 18)
+    thumb:SetAnchor(LEFT, color, LEFT, 4, 0)
+
+    color.border = wm:CreateControl(nil, color, CT_TEXTURE)
+    local border = color.border
+    border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds")
+    border:SetTextureCoords(0, .625, 0, .8125)
+    border:SetDimensions(40, 22)
+    border:SetAnchor(CENTER, thumb, CENTER, 0, 0)
+
+    local function ColorPickerCallback(r, g, b, a)
+        control:UpdateValue(false, r, g, b, a)
+    end
+
+    control:SetHandler("OnMouseUp", function(self, btn, upInside)
+        if self.isDisabled then return end
+
+        if upInside then
+            local r, g, b, a = colorpickerData.getFunc()
+            COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, LAM.util.GetStringFromValue(colorpickerData.name))
+        end
+    end)
+
+    if colorpickerData.warning ~= nil or colorpickerData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.data.tooltipText = LAM.util.GetStringFromValue(colorpickerData.tooltip)
+
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+    if colorpickerData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/custom.lua b/libs/LibAddonMenu-2.0/controls/custom.lua
new file mode 100644
index 0000000..40a7c42
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/custom.lua
@@ -0,0 +1,35 @@
+--[[customData = {
+    type = "custom",
+    reference = "MyAddonCustomControl", --(optional) unique name for your control to use as reference
+    refreshFunc = function(customControl) end, --(optional) function to call when panel/controls refresh
+    width = "full", --or "half" (optional)
+} ]]
+
+local widgetVersion = 7
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("custom", widgetVersion) then return end
+
+local function UpdateValue(control)
+    if control.data.refreshFunc then
+        control.data.refreshFunc(control)
+    end
+end
+
+local MIN_HEIGHT = 26
+function LAMCreateControl.custom(parent, customData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, customData, controlName)
+    local width = control:GetWidth()
+    control:SetResizeToFitDescendents(true)
+
+    if control.isHalfWidth then --note these restrictions
+        control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
+    else
+        control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
+    end
+
+    control.UpdateValue = UpdateValue
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/description.lua b/libs/LibAddonMenu-2.0/controls/description.lua
new file mode 100644
index 0000000..da207a0
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/description.lua
@@ -0,0 +1,60 @@
+--[[descriptionData = {
+    type = "description",
+    text = "My description text to display.", -- or string id or function returning a string
+    title = "My Title", -- or string id or function returning a string (optional)
+    width = "full", --or "half" (optional)
+    reference = "MyAddonDescription" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 8
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("description", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local function UpdateValue(control)
+    if control.title then
+        control.title:SetText(LAM.util.GetStringFromValue(control.data.title))
+    end
+    control.desc:SetText(LAM.util.GetStringFromValue(control.data.text))
+end
+
+function LAMCreateControl.description(parent, descriptionData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, descriptionData, controlName)
+    local isHalfWidth = control.isHalfWidth
+    local width = control:GetWidth()
+    control:SetResizeToFitDescendents(true)
+
+    if isHalfWidth then
+        control:SetDimensionConstraints(width / 2, 0, width / 2, 0)
+    else
+        control:SetDimensionConstraints(width, 0, width, 0)
+    end
+
+    control.desc = wm:CreateControl(nil, control, CT_LABEL)
+    local desc = control.desc
+    desc:SetVerticalAlignment(TEXT_ALIGN_TOP)
+    desc:SetFont("ZoFontGame")
+    desc:SetText(LAM.util.GetStringFromValue(descriptionData.text))
+    desc:SetWidth(isHalfWidth and width / 2 or width)
+
+    if descriptionData.title then
+        control.title = wm:CreateControl(nil, control, CT_LABEL)
+        local title = control.title
+        title:SetWidth(isHalfWidth and width / 2 or width)
+        title:SetAnchor(TOPLEFT, control, TOPLEFT)
+        title:SetFont("ZoFontWinH4")
+        title:SetText(LAM.util.GetStringFromValue(descriptionData.title))
+        desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT)
+    else
+        desc:SetAnchor(TOPLEFT)
+    end
+
+    control.UpdateValue = UpdateValue
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+
+    return control
+
+end
diff --git a/libs/LibAddonMenu-2.0/controls/desktop.ini b/libs/LibAddonMenu-2.0/controls/desktop.ini
new file mode 100644
index 0000000..df8fdc8
Binary files /dev/null and b/libs/LibAddonMenu-2.0/controls/desktop.ini differ
diff --git a/libs/LibAddonMenu-2.0/controls/divider.lua b/libs/LibAddonMenu-2.0/controls/divider.lua
new file mode 100644
index 0000000..8089539
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/divider.lua
@@ -0,0 +1,45 @@
+--[[dividerData = {
+    type = "divider",
+    width = "full", --or "half" (optional)
+    height = 10, (optional)
+    alpha = 0.25, (optional)
+    reference = "MyAddonDivider" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 2
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("divider", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local MIN_HEIGHT = 10
+local MAX_HEIGHT = 50
+local MIN_ALPHA = 0
+local MAX_ALPHA = 1
+local DEFAULT_ALPHA = 0.25
+
+local function GetValueInRange(value, min, max, default)
+    if not value or type(value) ~= "number" then
+        return default
+    end
+    return math.min(math.max(min, value), max)
+end
+
+function LAMCreateControl.divider(parent, dividerData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, dividerData, controlName)
+    local isHalfWidth = control.isHalfWidth
+    local width = control:GetWidth()
+    local height = GetValueInRange(dividerData.height, MIN_HEIGHT, MAX_HEIGHT, MIN_HEIGHT)
+    local alpha = GetValueInRange(dividerData.alpha, MIN_ALPHA, MAX_ALPHA, DEFAULT_ALPHA)
+
+    control:SetDimensions(isHalfWidth and width / 2 or width, height)
+
+    control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
+    local divider = control.divider
+    divider:SetWidth(isHalfWidth and width / 2 or width)
+    divider:SetAnchor(TOPLEFT)
+    divider:SetAlpha(alpha)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/dropdown.lua b/libs/LibAddonMenu-2.0/controls/dropdown.lua
new file mode 100644
index 0000000..70e23bb
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/dropdown.lua
@@ -0,0 +1,387 @@
+--[[dropdownData = {
+    type = "dropdown",
+    name = "My Dropdown", -- or string id or function returning a string
+    choices = {"table", "of", "choices"},
+    choicesValues = {"foo", 2, "three"}, -- if specified, these values will get passed to setFunc instead (optional)
+    getFunc = function() return db.var end,
+    setFunc = function(var) db.var = var doStuff() end,
+    tooltip = "Dropdown's tooltip text.", -- or string id or function returning a string (optional)
+    choicesTooltips = {"tooltip 1", "tooltip 2", "tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
+    sort = "name-up", --or "name-down", "numeric-up", "numeric-down", "value-up", "value-down", "numericvalue-up", "numericvalue-down" (optional) - if not provided, list will not be sorted
+    width = "full", --or "half" (optional)
+    scrollable = true, -- boolean or number, if set the dropdown will feature a scroll bar if there are a large amount of choices and limit the visible lines to the specified number or 10 if true is used (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = defaults.var, -- default value or function that returns the default value (optional)
+    reference = "MyAddonDropdown" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 18
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("dropdown", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local SORT_BY_VALUE         = { ["value"] = {} }
+local SORT_BY_VALUE_NUMERIC = { ["value"] = { isNumeric = true } }
+local SORT_TYPES = {
+    name = ZO_SORT_BY_NAME,
+    numeric = ZO_SORT_BY_NAME_NUMERIC,
+    value = SORT_BY_VALUE,
+    numericvalue = SORT_BY_VALUE_NUMERIC,
+}
+local SORT_ORDERS = {
+    up = ZO_SORT_ORDER_UP,
+    down = ZO_SORT_ORDER_DOWN,
+}
+
+local function UpdateDisabled(control)
+    local disable
+    if type(control.data.disabled) == "function" then
+        disable = control.data.disabled()
+    else
+        disable = control.data.disabled
+    end
+
+    control.dropdown:SetEnabled(not disable)
+    if disable then
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+    else
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    end
+end
+
+local function UpdateValue(control, forceDefault, value)
+    if forceDefault then --if we are forcing defaults
+        value = LAM.util.GetDefaultValue(control.data.default)
+        control.data.setFunc(value)
+        control.dropdown:SetSelectedItem(control.choices[value])
+    elseif value then
+        control.data.setFunc(value)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        value = control.data.getFunc()
+        control.dropdown:SetSelectedItem(control.choices[value])
+    end
+end
+
+local function DropdownCallback(control, choiceText, choice)
+    choice.control:UpdateValue(false, choice.value or choiceText)
+end
+
+local function SetupTooltips(comboBox, choicesTooltips)
+    local function ShowTooltip(control)
+        InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
+        SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.tooltip))
+        InformationTooltipTopLevel:BringWindowToTop()
+    end
+    local function HideTooltip(control)
+        ClearTooltip(InformationTooltip)
+    end
+
+    -- allow for tooltips on the drop down entries
+    local originalShow = comboBox.ShowDropdownInternal
+    comboBox.ShowDropdownInternal = function(comboBox)
+        originalShow(comboBox)
+        local entries = ZO_Menu.items
+        for i = 1, #entries do
+            local entry = entries[i]
+            local control = entries[i].item
+            control.tooltip = choicesTooltips[i]
+            entry.onMouseEnter = control:GetHandler("OnMouseEnter")
+            entry.onMouseExit = control:GetHandler("OnMouseExit")
+            ZO_PreHookHandler(control, "OnMouseEnter", ShowTooltip)
+            ZO_PreHookHandler(control, "OnMouseExit", HideTooltip)
+        end
+    end
+
+    local originalHide = comboBox.HideDropdownInternal
+    comboBox.HideDropdownInternal = function(self)
+        local entries = ZO_Menu.items
+        for i = 1, #entries do
+            local entry = entries[i]
+            local control = entries[i].item
+            control:SetHandler("OnMouseEnter", entry.onMouseEnter)
+            control:SetHandler("OnMouseExit", entry.onMouseExit)
+            control.tooltip = nil
+        end
+        originalHide(self)
+    end
+end
+
+local function UpdateChoices(control, choices, choicesValues, choicesTooltips)
+    control.dropdown:ClearItems() --remove previous choices --(need to call :SetSelectedItem()?)
+    ZO_ClearTable(control.choices)
+
+    --build new list of choices
+    local choices = choices or control.data.choices
+    local choicesValues = choicesValues or control.data.choicesValues
+    local choicesTooltips = choicesTooltips or control.data.choicesTooltips
+
+    if choicesValues then
+        assert(#choices == #choicesValues, "choices and choicesValues need to have the same size")
+    end
+
+    if choicesTooltips then
+        assert(#choices == #choicesTooltips, "choices and choicesTooltips need to have the same size")
+        if not control.scrollHelper then -- only do this for non-scrollable
+            SetupTooltips(control.dropdown, choicesTooltips)
+        end
+    end
+
+    for i = 1, #choices do
+        local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback)
+        entry.control = control
+        if choicesValues then
+            entry.value = choicesValues[i]
+        end
+        if choicesTooltips and control.scrollHelper then
+            entry.tooltip = choicesTooltips[i]
+        end
+        control.choices[entry.value or entry.name] = entry.name
+        control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE) --if sort type/order isn't specified, then don't sort
+    end
+end
+
+local function GrabSortingInfo(sortInfo)
+    local t, i = {}, 1
+    for info in string.gmatch(sortInfo, "([^%-]+)") do
+        t[i] = info
+        i = i + 1
+    end
+
+    return t
+end
+
+local DEFAULT_VISIBLE_ROWS = 10
+local SCROLLABLE_ENTRY_TEMPLATE_HEIGHT = 25 -- same as in zo_combobox.lua
+local CONTENT_PADDING = 24
+local SCROLLBAR_PADDING = 16
+local PADDING = GetMenuPadding() / 2 -- half the amount looks closer to the regular dropdown
+local ROUNDING_MARGIN = 0.01 -- needed to avoid rare issue with too many anchors processed
+local ScrollableDropdownHelper = ZO_Object:Subclass()
+
+function ScrollableDropdownHelper:New(...)
+    local object = ZO_Object.New(self)
+    object:Initialize(...)
+    return object
+end
+
+function ScrollableDropdownHelper:Initialize(parent, control, visibleRows)
+    local combobox = control.combobox
+    local dropdown = control.dropdown
+    self.parent = parent
+    self.control = control
+    self.combobox = combobox
+    self.dropdown = dropdown
+    self.visibleRows = visibleRows
+
+    -- clear anchors so we can adjust the width dynamically
+    dropdown.m_dropdown:ClearAnchors()
+    dropdown.m_dropdown:SetAnchor(TOPLEFT, combobox, BOTTOMLEFT)
+
+    -- handle dropdown or settingsmenu opening/closing
+    local function onShow() self:OnShow() end
+    local function onHide() self:OnHide() end
+    local function doHide() self:DoHide() end
+
+    ZO_PreHook(dropdown, "ShowDropdownOnMouseUp", onShow)
+    ZO_PreHook(dropdown, "HideDropdownInternal", onHide)
+    combobox:SetHandler("OnEffectivelyHidden", onHide)
+    parent:SetHandler("OnEffectivelyHidden", doHide)
+
+    -- dont fade entries near the edges
+    local scrollList = dropdown.m_scroll
+    scrollList.selectionTemplate = nil
+    scrollList.highlightTemplate = nil
+    ZO_ScrollList_EnableSelection(scrollList, "ZO_SelectionHighlight")
+    ZO_ScrollList_EnableHighlight(scrollList, "ZO_SelectionHighlight")
+    ZO_Scroll_SetUseFadeGradient(scrollList, false)
+
+    -- adjust scroll content anchor to mimic menu padding
+    local scroll = dropdown.m_dropdown:GetNamedChild("Scroll")
+    local anchor1 = {scroll:GetAnchor(0)}
+    local anchor2 = {scroll:GetAnchor(1)}
+    scroll:ClearAnchors()
+    scroll:SetAnchor(anchor1[2], anchor1[3], anchor1[4], anchor1[5] + PADDING, anchor1[6] + PADDING)
+    scroll:SetAnchor(anchor2[2], anchor2[3], anchor2[4], anchor2[5] - PADDING, anchor2[6] - PADDING)
+    ZO_ScrollList_Commit(scrollList)
+
+    -- hook mouse enter/exit
+    local function onMouseEnter(control) self:OnMouseEnter(control) end
+    local function onMouseExit(control) self:OnMouseExit(control) end
+
+    -- adjust row setup to mimic the highlight padding
+    local dataType1 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
+    local dataType2 = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 2)
+    local oSetup = dataType1.setupCallback -- both types have the same setup function
+    local function SetupEntry(control, data, list)
+        oSetup(control, data, list)
+        control.m_label:SetAnchor(LEFT, nil, nil, 2)
+        -- no need to store old ones since we have full ownership of our dropdown controls
+        if not control.hookedMouseHandlers then --only do it once per control
+            control.hookedMouseHandlers = true
+            ZO_PreHookHandler(control, "OnMouseEnter", onMouseEnter)
+            ZO_PreHookHandler(control, "OnMouseExit", onMouseExit)
+            -- we could also just replace the handlers
+            --control:SetHandler("OnMouseEnter", onMouseEnter)
+            --control:SetHandler("OnMouseExit", onMouseExit)
+        end
+    end
+    dataType1.setupCallback = SetupEntry
+    dataType2.setupCallback = SetupEntry
+
+    -- adjust dimensions based on entries
+    local scrollContent = scroll:GetNamedChild("Contents")
+    ZO_PreHook(dropdown, "AddMenuItems", function()
+        local width = PADDING * 2 + zo_max(self:GetMaxWidth(), combobox:GetWidth())
+        local numItems = #dropdown.m_sortedItems
+        local anchorOffset = 0
+        if(numItems > self.visibleRows) then
+            width = width + CONTENT_PADDING + SCROLLBAR_PADDING
+            anchorOffset = -SCROLLBAR_PADDING
+            numItems = self.visibleRows
+        end
+        scrollContent:SetAnchor(BOTTOMRIGHT, nil, nil, anchorOffset)
+        local height = PADDING * 2 + numItems * (SCROLLABLE_ENTRY_TEMPLATE_HEIGHT + dropdown.m_spacing) - dropdown.m_spacing + ROUNDING_MARGIN
+        dropdown.m_dropdown:SetWidth(width)
+        dropdown.m_dropdown:SetHeight(height)
+    end)
+end
+
+function ScrollableDropdownHelper:OnShow()
+    local dropdown = self.dropdown
+    if dropdown.m_lastParent ~= ZO_Menus then
+        dropdown.m_lastParent = dropdown.m_dropdown:GetParent()
+        dropdown.m_dropdown:SetParent(ZO_Menus)
+        ZO_Menus:BringWindowToTop()
+    end
+end
+
+function ScrollableDropdownHelper:OnHide()
+    local dropdown = self.dropdown
+    if dropdown.m_lastParent then
+        dropdown.m_dropdown:SetParent(dropdown.m_lastParent)
+        dropdown.m_lastParent = nil
+    end
+end
+
+function ScrollableDropdownHelper:DoHide()
+    local dropdown = self.dropdown
+    if dropdown:IsDropdownVisible() then
+        dropdown:HideDropdown()
+    end
+end
+
+function ScrollableDropdownHelper:GetMaxWidth()
+    local dropdown = self.dropdown
+    local dataType = ZO_ScrollList_GetDataTypeTable(dropdown.m_scroll, 1)
+
+    local dummy = dataType.pool:AcquireObject()
+    dataType.setupCallback(dummy, {
+        m_owner = dropdown,
+        name = "Dummy"
+    }, dropdown)
+
+    local maxWidth = 0
+    local label = dummy.m_label
+    local entries = dropdown.m_sortedItems
+    local numItems = #entries
+    for index = 1, numItems do
+        label:SetText(entries[index].name)
+        local width = label:GetTextWidth()
+        if (width > maxWidth) then
+            maxWidth = width
+        end
+    end
+
+    dataType.pool:ReleaseObject(dummy.key)
+    return maxWidth
+end
+
+function ScrollableDropdownHelper:OnMouseEnter(control)
+    -- call original code if we replace instead of hook the handler
+        --ZO_ScrollableComboBox_Entry_OnMouseEnter(control)
+    -- show tooltip
+    if control.m_data.tooltip then
+        InitializeTooltip(InformationTooltip, control, TOPLEFT, 0, 0, BOTTOMRIGHT)
+        SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(control.m_data.tooltip))
+        InformationTooltipTopLevel:BringWindowToTop()
+    end
+end
+function ScrollableDropdownHelper:OnMouseExit(control)
+    -- call original code if we replace instead of hook the handler
+        --ZO_ScrollableComboBox_Entry_OnMouseExit(control)
+    -- hide tooltip
+    if control.m_data.tooltip then
+        ClearTooltip(InformationTooltip)
+    end
+end
+
+function LAMCreateControl.dropdown(parent, dropdownData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, dropdownData, controlName)
+    control.choices = {}
+
+    local countControl = parent
+    local name = parent:GetName()
+    if not name or #name == 0 then
+        countControl = LAMCreateControl
+        name = "LAM"
+    end
+    local comboboxCount = (countControl.comboboxCount or 0) + 1
+    countControl.comboboxCount = comboboxCount
+    control.combobox = wm:CreateControlFromVirtual(zo_strjoin(nil, name, "Combobox", comboboxCount), control.container, dropdownData.scrollable and "ZO_ScrollableComboBox" or "ZO_ComboBox")
+
+    local combobox = control.combobox
+    combobox:SetAnchor(TOPLEFT)
+    combobox:SetDimensions(control.container:GetDimensions())
+    combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+    combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+    control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox)
+    local dropdown = control.dropdown
+    dropdown:SetSortsItems(false) -- need to sort ourselves in order to be able to sort by value
+
+    if dropdownData.scrollable then
+        local visibleRows = type(dropdownData.scrollable) == "number" and dropdownData.scrollable or DEFAULT_VISIBLE_ROWS
+        control.scrollHelper = ScrollableDropdownHelper:New(parent, control, visibleRows)
+    end
+
+    ZO_PreHook(dropdown, "UpdateItems", function(self)
+        assert(not self.m_sortsItems, "built-in dropdown sorting was reactivated, sorting is handled by LAM")
+        if control.m_sortOrder ~= nil and control.m_sortType then
+            local sortKey = next(control.m_sortType)
+            local sortFunc = function(item1, item2) return ZO_TableOrderingFunction(item1, item2, sortKey, control.m_sortType, control.m_sortOrder) end
+            table.sort(self.m_sortedItems, sortFunc)
+        end
+    end)
+
+    if dropdownData.sort then
+        local sortInfo = GrabSortingInfo(dropdownData.sort)
+        control.m_sortType, control.m_sortOrder = SORT_TYPES[sortInfo[1]], SORT_ORDERS[sortInfo[2]]
+    elseif dropdownData.choicesValues then
+        control.m_sortType, control.m_sortOrder = ZO_SORT_ORDER_UP, SORT_BY_VALUE
+    end
+
+    if dropdownData.warning ~= nil or dropdownData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.UpdateChoices = UpdateChoices
+    control:UpdateChoices(dropdownData.choices, dropdownData.choicesValues)
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+    if dropdownData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/editbox.lua b/libs/LibAddonMenu-2.0/controls/editbox.lua
new file mode 100644
index 0000000..d6baf11
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/editbox.lua
@@ -0,0 +1,156 @@
+--[[editboxData = {
+    type = "editbox",
+    name = "My Editbox", -- or string id or function returning a string
+    getFunc = function() return db.text end,
+    setFunc = function(text) db.text = text doStuff() end,
+    tooltip = "Editbox's tooltip text.", -- or string id or function returning a string (optional)
+    isMultiline = true, --boolean (optional)
+    isExtraWide = true, --boolean (optional)
+    width = "full", --or "half" (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = defaults.text, -- default value or function that returns the default value (optional)
+    reference = "MyAddonEditbox" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 14
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("editbox", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local function UpdateDisabled(control)
+    local disable
+    if type(control.data.disabled) == "function" then
+        disable = control.data.disabled()
+    else
+        disable = control.data.disabled
+    end
+
+    if disable then
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+        control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+    else
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+        control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    end
+    --control.editbox:SetEditEnabled(not disable)
+    control.editbox:SetMouseEnabled(not disable)
+end
+
+local function UpdateValue(control, forceDefault, value)
+    if forceDefault then --if we are forcing defaults
+        value = LAM.util.GetDefaultValue(control.data.default)
+        control.data.setFunc(value)
+        control.editbox:SetText(value)
+    elseif value then
+        control.data.setFunc(value)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        value = control.data.getFunc()
+        control.editbox:SetText(value)
+    end
+end
+
+local MIN_HEIGHT = 24
+local HALF_WIDTH_LINE_SPACING = 2
+function LAMCreateControl.editbox(parent, editboxData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, editboxData, controlName)
+
+    local container = control.container
+    control.bg = wm:CreateControlFromVirtual(nil, container, "ZO_EditBackdrop")
+    local bg = control.bg
+    bg:SetAnchorFill()
+
+    if editboxData.isMultiline then
+        control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop")
+        control.editbox:SetHandler("OnMouseWheel", function(self, delta)
+            if self:HasFocus() then --only set focus to new spots if the editbox is currently in use
+                local cursorPos = self:GetCursorPosition()
+                local text = self:GetText()
+                local textLen = text:len()
+                local newPos
+                if delta > 0 then --scrolling up
+                    local reverseText = text:reverse()
+                    local revCursorPos = textLen - cursorPos
+                    local revPos = reverseText:find("\n", revCursorPos+1)
+                    newPos = revPos and textLen - revPos
+                else --scrolling down
+                    newPos = text:find("\n", cursorPos+1)
+                end
+                if newPos then --if we found a new line, then scroll, otherwise don't
+                    self:SetCursorPosition(newPos)
+                end
+            end
+        end)
+    else
+        control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop")
+    end
+    local editbox = control.editbox
+    editbox:SetText(editboxData.getFunc())
+    editbox:SetMaxInputChars(3000)
+    editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end)
+    editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end)
+    editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+    editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+
+    local MIN_WIDTH = (parent.GetWidth and (parent:GetWidth() / 10)) or (parent.panel.GetWidth and (parent.panel:GetWidth() / 10)) or 0
+
+    control.label:ClearAnchors()
+    container:ClearAnchors()
+
+    control.label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 0)
+    container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
+
+    if control.isHalfWidth then
+        container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, 0, 0)
+    end
+
+    if editboxData.isExtraWide then
+        container:SetAnchor(BOTTOMLEFT, control, BOTTOMLEFT, 0, 0)
+    else
+        container:SetWidth(MIN_WIDTH * 3.2)
+    end
+
+    if editboxData.isMultiline then
+        container:SetHeight(MIN_HEIGHT * 3)
+    else
+        container:SetHeight(MIN_HEIGHT)
+    end
+
+    if control.isHalfWidth ~= true and editboxData.isExtraWide ~= true then
+        control:SetHeight(container:GetHeight())
+    else
+        control:SetHeight(container:GetHeight() + control.label:GetHeight())
+    end
+
+    editbox:ClearAnchors()
+    editbox:SetAnchor(TOPLEFT, container, TOPLEFT, 2, 2)
+    editbox:SetAnchor(BOTTOMRIGHT, container, BOTTOMRIGHT, -2, -2)
+
+    if editboxData.warning ~= nil or editboxData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        if editboxData.isExtraWide then
+            control.warning:SetAnchor(BOTTOMRIGHT, control.bg, TOPRIGHT, 2, 0)
+        else
+            control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0)
+        end
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+    if editboxData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/header.lua b/libs/LibAddonMenu-2.0/controls/header.lua
new file mode 100644
index 0000000..eadff38
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/header.lua
@@ -0,0 +1,42 @@
+--[[headerData = {
+    type = "header",
+    name = "My Header", -- or string id or function returning a string
+    width = "full", --or "half" (optional)
+    reference = "MyAddonHeader" -- unique global reference to control (optional)
+} ]]
+
+
+local widgetVersion = 8
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("header", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local function UpdateValue(control)
+    control.header:SetText(LAM.util.GetStringFromValue(control.data.name))
+end
+
+local MIN_HEIGHT = 30
+function LAMCreateControl.header(parent, headerData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, headerData, controlName)
+    local isHalfWidth = control.isHalfWidth
+    local width = control:GetWidth()
+    control:SetDimensions(isHalfWidth and width / 2 or width, MIN_HEIGHT)
+
+    control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider")
+    local divider = control.divider
+    divider:SetWidth(isHalfWidth and width / 2 or width)
+    divider:SetAnchor(TOPLEFT)
+
+    control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+    local header = control.header
+    header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT)
+    header:SetAnchor(BOTTOMRIGHT)
+    header:SetText(LAM.util.GetStringFromValue(headerData.name))
+
+    control.UpdateValue = UpdateValue
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/iconpicker.lua b/libs/LibAddonMenu-2.0/controls/iconpicker.lua
new file mode 100644
index 0000000..65c7782
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/iconpicker.lua
@@ -0,0 +1,436 @@
+--[[iconpickerData = {
+    type = "iconpicker",
+    name = "My Icon Picker", -- or string id or function returning a string
+    choices = {"texture path 1", "texture path 2", "texture path 3"},
+    getFunc = function() return db.var end,
+    setFunc = function(var) db.var = var doStuff() end,
+    tooltip = "Color Picker's tooltip text.", -- or string id or function returning a string (optional)
+    choicesTooltips = {"icon tooltip 1", "icon tooltip 2", "icon tooltip 3"}, -- or array of string ids or array of functions returning a string (optional)
+    maxColumns = 5, -- number of icons in one row (optional)
+    visibleRows = 4.5, -- number of visible rows (optional)
+    iconSize = 28, -- size of the icons (optional)
+    defaultColor = ZO_ColorDef:New("FFFFFF"), -- default color of the icons (optional)
+    width = "full", --or "half" (optional)
+    beforeShow = function(control, iconPicker) return preventShow end, --(optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = defaults.var, -- default value or function that returns the default value (optional)
+    reference = "MyAddonIconPicker" -- unique global reference to control (optional)
+} ]]
+
+local widgetVersion = 8
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("iconpicker", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local IconPickerMenu = ZO_Object:Subclass()
+local iconPicker
+LAM.util.GetIconPickerMenu = function()
+    if not iconPicker then
+        iconPicker = IconPickerMenu:New("LAMIconPicker")
+        local sceneFragment = LAM:GetAddonSettingsFragment()
+        ZO_PreHook(sceneFragment, "OnHidden", function()
+            if not iconPicker.control:IsHidden() then
+                iconPicker:Clear()
+            end
+        end)
+    end
+    return iconPicker
+end
+
+function IconPickerMenu:New(...)
+    local object = ZO_Object.New(self)
+    object:Initialize(...)
+    return object
+end
+
+function IconPickerMenu:Initialize(name)
+    local control = wm:CreateTopLevelWindow(name)
+    control:SetDrawTier(DT_HIGH)
+    control:SetHidden(true)
+    self.control = control
+
+    local scrollContainer = wm:CreateControlFromVirtual(name .. "ScrollContainer", control, "ZO_ScrollContainer")
+    -- control:SetDimensions(control.container:GetWidth(), height) -- adjust to icon size / col count
+    scrollContainer:SetAnchorFill()
+    ZO_Scroll_SetUseFadeGradient(scrollContainer, false)
+    ZO_Scroll_SetHideScrollbarOnDisable(scrollContainer, false)
+    ZO_VerticalScrollbarBase_OnMouseExit(scrollContainer:GetNamedChild("ScrollBar")) -- scrollbar initialization seems to be broken so we force it to update the correct alpha value
+    local scroll = GetControl(scrollContainer, "ScrollChild")
+    self.scroll = scroll
+    self.scrollContainer = scrollContainer
+
+    local bg = wm:CreateControl(nil, scrollContainer, CT_BACKDROP)
+    bg:SetAnchor(TOPLEFT, scrollContainer, TOPLEFT, 0, -3)
+    bg:SetAnchor(BOTTOMRIGHT, scrollContainer, BOTTOMRIGHT, 2, 5)
+    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
+    bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
+    bg:SetInsets(16, 16, -16, -16)
+
+    local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
+    mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
+    mungeOverlay:SetDrawLevel(1)
+    mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
+    mungeOverlay:SetAnchorFill()
+
+    local mouseOver = wm:CreateControl(nil, scrollContainer, CT_TEXTURE)
+    mouseOver:SetDrawLevel(2)
+    mouseOver:SetTexture("EsoUI/Art/Buttons/minmax_mouseover.dds")
+    mouseOver:SetHidden(true)
+
+    local function IconFactory(pool)
+        local icon = wm:CreateControl(name .. "Entry" .. pool:GetNextControlId(), scroll, CT_TEXTURE)
+        icon:SetMouseEnabled(true)
+        icon:SetDrawLevel(3)
+        icon:SetHandler("OnMouseEnter", function()
+            mouseOver:SetAnchor(TOPLEFT, icon, TOPLEFT, 0, 0)
+            mouseOver:SetAnchor(BOTTOMRIGHT, icon, BOTTOMRIGHT, 0, 0)
+            mouseOver:SetHidden(false)
+            if self.customOnMouseEnter then
+                self.customOnMouseEnter(icon)
+            else
+                self:OnMouseEnter(icon)
+            end
+        end)
+        icon:SetHandler("OnMouseExit", function()
+            mouseOver:ClearAnchors()
+            mouseOver:SetHidden(true)
+            if self.customOnMouseExit then
+                self.customOnMouseExit(icon)
+            else
+                self:OnMouseExit(icon)
+            end
+        end)
+        icon:SetHandler("OnMouseUp", function(control, ...)
+            PlaySound("Click")
+            icon.OnSelect(icon, icon.texture)
+            self:Clear()
+        end)
+        return icon
+    end
+
+    local function ResetFunction(icon)
+        icon:ClearAnchors()
+    end
+
+    self.iconPool = ZO_ObjectPool:New(IconFactory, ResetFunction)
+    self:SetMaxColumns(1)
+    self.icons = {}
+    self.color = ZO_DEFAULT_ENABLED_COLOR
+
+    EVENT_MANAGER:RegisterForEvent(name .. "_OnGlobalMouseUp", EVENT_GLOBAL_MOUSE_UP, function()
+        if self.refCount ~= nil then
+            local moc = wm:GetMouseOverControl()
+            if(moc:GetOwningWindow() ~= control) then
+                self.refCount = self.refCount - 1
+                if self.refCount <= 0 then
+                    self:Clear()
+                end
+            end
+        end
+    end)
+end
+
+function IconPickerMenu:OnMouseEnter(icon)
+    InitializeTooltip(InformationTooltip, icon, TOPLEFT, 0, 0, BOTTOMRIGHT)
+    SetTooltipText(InformationTooltip, LAM.util.GetStringFromValue(icon.tooltip))
+    InformationTooltipTopLevel:BringWindowToTop()
+end
+
+function IconPickerMenu:OnMouseExit(icon)
+    ClearTooltip(InformationTooltip)
+end
+
+function IconPickerMenu:SetMaxColumns(value)
+    self.maxCols = value ~= nil and value or 5
+end
+
+local DEFAULT_SIZE = 28
+function IconPickerMenu:SetIconSize(value)
+    local iconSize = DEFAULT_SIZE
+    if value ~= nil then iconSize = math.max(iconSize, value) end
+    self.iconSize = iconSize
+end
+
+function IconPickerMenu:SetVisibleRows(value)
+    self.visibleRows = value ~= nil and value or 4.5
+end
+
+function IconPickerMenu:SetMouseHandlers(onEnter, onExit)
+    self.customOnMouseEnter = onEnter
+    self.customOnMouseExit = onExit
+end
+
+function IconPickerMenu:UpdateDimensions()
+    local iconSize = self.iconSize
+    local width = iconSize * self.maxCols + 20
+    local height = iconSize * self.visibleRows
+    self.control:SetDimensions(width, height)
+
+    local icons = self.icons
+    for i = 1, #icons do
+        local icon = icons[i]
+        icon:SetDimensions(iconSize, iconSize)
+    end
+end
+
+function IconPickerMenu:UpdateAnchors()
+    local iconSize = self.iconSize
+    local col, maxCols = 1, self.maxCols
+    local previousCol, previousRow
+    local scroll = self.scroll
+    local icons = self.icons
+
+    for i = 1, #icons do
+        local icon = icons[i]
+        icon:ClearAnchors()
+        if i == 1 then
+            icon:SetAnchor(TOPLEFT, scroll, TOPLEFT, 0, 0)
+            previousRow = icon
+        elseif col == 1 then
+            icon:SetAnchor(TOPLEFT, previousRow, BOTTOMLEFT, 0, 0)
+            previousRow = icon
+        else
+            icon:SetAnchor(TOPLEFT, previousCol, TOPRIGHT, 0, 0)
+        end
+        previousCol = icon
+        col = col >= maxCols and 1 or col + 1
+    end
+end
+
+function IconPickerMenu:Clear()
+    self.icons = {}
+    self.iconPool:ReleaseAllObjects()
+    self.control:SetHidden(true)
+    self.color = ZO_DEFAULT_ENABLED_COLOR
+    self.refCount = nil
+    self.parent = nil
+    self.customOnMouseEnter = nil
+    self.customOnMouseExit = nil
+end
+
+function IconPickerMenu:AddIcon(texturePath, callback, tooltip)
+    local icon, key = self.iconPool:AcquireObject()
+    icon:SetTexture(texturePath)
+    icon:SetColor(self.color:UnpackRGBA())
+    icon.texture = texturePath
+    icon.tooltip = tooltip
+    icon.OnSelect = callback
+    self.icons[#self.icons + 1] = icon
+end
+
+function IconPickerMenu:Show(parent)
+    if #self.icons == 0 then return false end
+    if not self.control:IsHidden() then self:Clear() return false end
+    self:UpdateDimensions()
+    self:UpdateAnchors()
+
+    local control = self.control
+    control:ClearAnchors()
+    control:SetAnchor(TOPLEFT, parent, BOTTOMLEFT, 0, 8)
+    control:SetHidden(false)
+    control:BringWindowToTop()
+    self.parent = parent
+    self.refCount = 2
+
+    return true
+end
+
+function IconPickerMenu:SetColor(color)
+    local icons = self.icons
+    self.color = color
+    for i = 1, #icons do
+        local icon = icons[i]
+        icon:SetColor(color:UnpackRGBA())
+    end
+end
+
+-------------------------------------------------------------
+
+local function UpdateChoices(control, choices, choicesTooltips)
+    local data = control.data
+    if not choices then
+        choices, choicesTooltips = data.choices, data.choicesTooltips or {}
+    end
+    local addedChoices = {}
+
+    local iconPicker = LAM.util.GetIconPickerMenu()
+    iconPicker:Clear()
+    for i = 1, #choices do
+        local texture = choices[i]
+        if not addedChoices[texture] then -- remove duplicates
+            iconPicker:AddIcon(choices[i], function(self, texture)
+                control.icon:SetTexture(texture)
+                data.setFunc(texture)
+                LAM.util.RequestRefreshIfNeeded(control)
+            end, LAM.util.GetStringFromValue(choicesTooltips[i]))
+        addedChoices[texture] = true
+        end
+    end
+end
+
+local function IsDisabled(control)
+    if type(control.data.disabled) == "function" then
+        return control.data.disabled()
+    else
+        return control.data.disabled
+    end
+end
+
+local function SetColor(control, color)
+    local icon = control.icon
+    if IsDisabled(control) then
+        icon:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+    else
+        icon.color = color or control.data.defaultColor or ZO_DEFAULT_ENABLED_COLOR
+        icon:SetColor(icon.color:UnpackRGBA())
+    end
+
+    local iconPicker = LAM.util.GetIconPickerMenu()
+    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
+        iconPicker:SetColor(icon.color)
+    end
+end
+
+local function UpdateDisabled(control)
+    local disable = IsDisabled(control)
+
+    control.dropdown:SetMouseEnabled(not disable)
+    control.dropdownButton:SetEnabled(not disable)
+
+    local iconPicker = LAM.util.GetIconPickerMenu()
+    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
+        iconPicker:Clear()
+    end
+
+    SetColor(control, control.icon.color)
+    if disable then
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+    else
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    end
+end
+
+local function UpdateValue(control, forceDefault, value)
+    if forceDefault then --if we are forcing defaults
+        value = LAM.util.GetDefaultValue(control.data.default)
+        control.data.setFunc(value)
+        control.icon:SetTexture(value)
+    elseif value then
+        control.data.setFunc(value)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        value = control.data.getFunc()
+        control.icon:SetTexture(value)
+    end
+end
+
+local MIN_HEIGHT = 26
+local HALF_WIDTH_LINE_SPACING = 2
+local function SetIconSize(control, size)
+    local icon = control.icon
+    icon.size = size
+    icon:SetDimensions(size, size)
+
+    local height = size + 4
+    control.dropdown:SetDimensions(size + 20, height)
+    height = math.max(height, MIN_HEIGHT)
+    control.container:SetHeight(height)
+    if control.lineControl then
+        control.lineControl:SetHeight(MIN_HEIGHT + size + HALF_WIDTH_LINE_SPACING)
+    else
+        control:SetHeight(height)
+    end
+
+    local iconPicker = LAM.util.GetIconPickerMenu()
+    if iconPicker.parent == control.container and not iconPicker.control:IsHidden() then
+        iconPicker:SetIconSize(size)
+        iconPicker:UpdateDimensions()
+        iconPicker:UpdateAnchors()
+    end
+end
+
+function LAMCreateControl.iconpicker(parent, iconpickerData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, iconpickerData, controlName)
+
+    local function ShowIconPicker()
+        local iconPicker = LAM.util.GetIconPickerMenu()
+        if iconPicker.parent == control.container then
+            iconPicker:Clear()
+        else
+            iconPicker:SetMaxColumns(iconpickerData.maxColumns)
+            iconPicker:SetVisibleRows(iconpickerData.visibleRows)
+            iconPicker:SetIconSize(control.icon.size)
+            UpdateChoices(control)
+            iconPicker:SetColor(control.icon.color)
+            if iconpickerData.beforeShow then
+                if iconpickerData.beforeShow(control, iconPicker) then
+                    iconPicker:Clear()
+                    return
+                end
+            end
+            iconPicker:Show(control.container)
+        end
+    end
+
+    local iconSize = iconpickerData.iconSize ~= nil and iconpickerData.iconSize or DEFAULT_SIZE
+    control.dropdown = wm:CreateControl(nil, control.container, CT_CONTROL)
+    local dropdown = control.dropdown
+    dropdown:SetAnchor(LEFT, control.container, LEFT, 0, 0)
+    dropdown:SetMouseEnabled(true)
+    dropdown:SetHandler("OnMouseUp", ShowIconPicker)
+    dropdown:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+    dropdown:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+
+    control.icon = wm:CreateControl(nil, dropdown, CT_TEXTURE)
+    local icon = control.icon
+    icon:SetAnchor(LEFT, dropdown, LEFT, 3, 0)
+    icon:SetDrawLevel(2)
+
+    local dropdownButton = wm:CreateControlFromVirtual(nil, dropdown, "ZO_DropdownButton")
+    dropdownButton:SetDimensions(16, 16)
+    dropdownButton:SetHandler("OnClicked", ShowIconPicker)
+    dropdownButton:SetAnchor(RIGHT, dropdown, RIGHT, -3, 0)
+    control.dropdownButton = dropdownButton
+
+    control.bg = wm:CreateControl(nil, dropdown, CT_BACKDROP)
+    local bg = control.bg
+    bg:SetAnchor(TOPLEFT, dropdown, TOPLEFT, 0, -3)
+    bg:SetAnchor(BOTTOMRIGHT, dropdown, BOTTOMRIGHT, 2, 5)
+    bg:SetEdgeTexture("EsoUI/Art/Tooltips/UI-Border.dds", 128, 16)
+    bg:SetCenterTexture("EsoUI/Art/Tooltips/UI-TooltipCenter.dds")
+    bg:SetInsets(16, 16, -16, -16)
+    local mungeOverlay = wm:CreateControl(nil, bg, CT_TEXTURE)
+    mungeOverlay:SetTexture("EsoUI/Art/Tooltips/munge_overlay.dds")
+    mungeOverlay:SetDrawLevel(1)
+    mungeOverlay:SetAddressMode(TEX_MODE_WRAP)
+    mungeOverlay:SetAnchorFill()
+
+    if iconpickerData.warning ~= nil or iconpickerData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, control.container, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.UpdateChoices = UpdateChoices
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+    control.SetColor = SetColor
+    control:SetColor()
+    control.SetIconSize = SetIconSize
+    control:SetIconSize(iconSize)
+
+    if iconpickerData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/panel.lua b/libs/LibAddonMenu-2.0/controls/panel.lua
new file mode 100644
index 0000000..1404686
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/panel.lua
@@ -0,0 +1,126 @@
+--[[panelData = {
+    type = "panel",
+    name = "Window Title", -- or string id or function returning a string
+    displayName = "My Longer Window Title",  -- or string id or function returning a string (optional) (can be useful for long addon names or if you want to colorize it)
+    author = "Seerah",  -- or string id or function returning a string (optional)
+    version = "2.0",  -- or string id or function returning a string (optional)
+    website = "http://www.esoui.com/downloads/info7-LibAddonMenu.html", -- URL of website where the addon can be updated (optional)
+    keywords = "settings", -- additional keywords for search filter (it looks for matches in name..keywords..author) (optional)
+    slashCommand = "/myaddon", -- will register a keybind to open to this panel (don't forget to include the slash!) (optional)
+    registerForRefresh = true, --boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown)
+    registerForDefaults = true, --boolean (optional) (will set all options controls back to default values)
+    resetFunc = function() print("defaults reset") end, --(optional) custom function to run after settings are reset to defaults
+} ]]
+
+
+local widgetVersion = 13
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("panel", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local cm = CALLBACK_MANAGER
+
+local function RefreshPanel(control)
+    local panel = LAM.util.GetTopPanel(control) --callback can be fired by a single control, by the panel showing or by a nested submenu
+    local panelControls = panel.controlsToRefresh
+
+    for i = 1, #panelControls do
+        local updateControl = panelControls[i]
+        if updateControl ~= control and updateControl.UpdateValue then
+            updateControl:UpdateValue()
+        end
+        if updateControl.UpdateDisabled then
+            updateControl:UpdateDisabled()
+        end
+        if updateControl.UpdateWarning then
+            updateControl:UpdateWarning()
+        end
+    end
+end
+
+local function ForceDefaults(panel)
+    local panelControls = panel.controlsToRefresh
+
+    for i = 1, #panelControls do
+        local updateControl = panelControls[i]
+        if updateControl.UpdateValue and updateControl.data.default ~= nil then
+            updateControl:UpdateValue(true)
+        end
+    end
+
+    if panel.data.resetFunc then
+        panel.data.resetFunc()
+    end
+
+    cm:FireCallbacks("LAM-RefreshPanel", panel)
+end
+
+local callbackRegistered = false
+LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1
+local SEPARATOR = " - "
+local LINK_COLOR = ZO_ColorDef:New("5959D5")
+local LINK_MOUSE_OVER_COLOR = ZO_ColorDef:New("B8B8D3")
+
+function LAMCreateControl.panel(parent, panelData, controlName)
+    local control = wm:CreateControl(controlName, parent, CT_CONTROL)
+
+    control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+    local label = control.label
+    label:SetAnchor(TOPLEFT, control, TOPLEFT, 0, 4)
+    label:SetText(LAM.util.GetStringFromValue(panelData.displayName or panelData.name))
+
+    if panelData.author or panelData.version then
+        control.info = wm:CreateControl(nil, control, CT_LABEL)
+        local info = control.info
+        info:SetFont(LAM.util.L["PANEL_INFO_FONT"])
+        info:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
+
+        local output = {}
+        if panelData.author then
+            output[#output + 1] = zo_strformat(LAM.util.L["AUTHOR"], LAM.util.GetStringFromValue(panelData.author))
+        end
+        if panelData.version then
+            output[#output + 1] = zo_strformat(LAM.util.L["VERSION"], LAM.util.GetStringFromValue(panelData.version))
+        end
+        info:SetText(table.concat(output, SEPARATOR))
+    end
+
+    if panelData.website then
+        control.website = wm:CreateControl(nil, control, CT_BUTTON)
+        local website = control.website
+        website:SetClickSound("Click")
+        website:SetFont(LAM.util.L["PANEL_INFO_FONT"])
+        website:SetNormalFontColor(LINK_COLOR:UnpackRGBA())
+        website:SetMouseOverFontColor(LINK_MOUSE_OVER_COLOR:UnpackRGBA())
+        if(control.info) then
+            website:SetAnchor(TOPLEFT, control.info, TOPRIGHT, 0, 0)
+            website:SetText(string.format("|cffffff%s|r%s", SEPARATOR, LAM.util.L["WEBSITE"]))
+        else
+            website:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, -2)
+            website:SetText(LAM.util.L["WEBSITE"])
+        end
+        website:SetDimensions(website:GetLabelControl():GetTextDimensions())
+        website:SetHandler("OnClicked", function()
+            RequestOpenUnsafeURL(panelData.website)
+        end)
+    end
+
+    control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer")
+    LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1
+    local container = control.container
+    container:SetAnchor(TOPLEFT, control.info or label, BOTTOMLEFT, 0, 20)
+    container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3)
+    control.scroll = GetControl(control.container, "ScrollChild")
+    control.scroll:SetResizeToFitPadding(0, 20)
+
+    if panelData.registerForRefresh and not callbackRegistered then --don't want to register our callback more than once
+        cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel)
+        callbackRegistered = true
+    end
+
+    control.ForceDefaults = ForceDefaults
+    control.data = panelData
+    control.controlsToRefresh = {}
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/slider.lua b/libs/LibAddonMenu-2.0/controls/slider.lua
new file mode 100644
index 0000000..bd721c5
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/slider.lua
@@ -0,0 +1,212 @@
+--[[sliderData = {
+    type = "slider",
+    name = "My Slider", -- or string id or function returning a string
+    getFunc = function() return db.var end,
+    setFunc = function(value) db.var = value doStuff() end,
+    min = 0,
+    max = 20,
+    step = 1, --(optional)
+    clampInput = true, -- boolean, if set to false the input won't clamp to min and max and allow any number instead (optional)
+    decimals = 0, -- when specified the input value is rounded to the specified number of decimals (optional)
+    autoSelect = false, -- boolean, automatically select everything in the text input field when it gains focus (optional)
+    inputLocation = "below", -- or "right", determines where the input field is shown. This should not be used within the addon menu and is for custom sliders (optional)
+    tooltip = "Slider's tooltip text.", -- or string id or function returning a string (optional)
+    width = "full", --or "half" (optional)
+    disabled = function() return db.someBooleanSetting end, --or boolean (optional)
+    warning = "May cause permanent awesomeness.", -- or string id or function returning a string (optional)
+    requiresReload = false, -- boolean, if set to true, the warning text will contain a notice that changes are only applied after an UI reload and any change to the value will make the "Apply Settings" button appear on the panel which will reload the UI when pressed (optional)
+    default = defaults.var, -- default value or function that returns the default value (optional)
+    reference = "MyAddonSlider" -- unique global reference to control (optional)
+} ]]
+
+local widgetVersion = 12
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("slider", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local strformat = string.format
+
+local function RoundDecimalToPlace(d, place)
+    return tonumber(strformat("%." .. tostring(place) .. "f", d))
+end
+
+local function UpdateDisabled(control)
+    local disable
+    if type(control.data.disabled) == "function" then
+        disable = control.data.disabled()
+    else
+        disable = control.data.disabled
+    end
+
+    control.slider:SetEnabled(not disable)
+    control.slidervalue:SetEditEnabled(not disable)
+    if disable then
+        control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+        control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+        control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
+        control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA())
+    else
+        control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+        control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+        control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+        control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
+    end
+end
+
+local function UpdateValue(control, forceDefault, value)
+    if forceDefault then --if we are forcing defaults
+        value = LAM.util.GetDefaultValue(control.data.default)
+        control.data.setFunc(value)
+    elseif value then
+        if control.data.decimals then
+            value = RoundDecimalToPlace(value, control.data.decimals)
+        end
+        if control.data.clampInput ~= false then
+            value = math.max(math.min(value, control.data.max), control.data.min)
+        end
+        control.data.setFunc(value)
+        --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed
+        LAM.util.RequestRefreshIfNeeded(control)
+    else
+        value = control.data.getFunc()
+    end
+
+    control.slider:SetValue(value)
+    control.slidervalue:SetText(value)
+end
+
+function LAMCreateControl.slider(parent, sliderData, controlName)
+    local control = LAM.util.CreateLabelAndContainerControl(parent, sliderData, controlName)
+    local isInputOnRight = sliderData.inputLocation == "right"
+
+    --skipping creating the backdrop...  Is this the actual slider texture?
+    control.slider = wm:CreateControl(nil, control.container, CT_SLIDER)
+    local slider = control.slider
+    slider:SetAnchor(TOPLEFT)
+    slider:SetHeight(14)
+    if(isInputOnRight) then
+        slider:SetAnchor(TOPRIGHT, nil, nil, -60)
+    else
+        slider:SetAnchor(TOPRIGHT)
+    end
+    slider:SetMouseEnabled(true)
+    slider:SetOrientation(ORIENTATION_HORIZONTAL)
+    --put nil for highlighted texture file path, and what look to be texture coords
+    slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16)
+    local minValue = sliderData.min
+    local maxValue = sliderData.max
+    slider:SetMinMax(minValue, maxValue)
+    slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end)
+    slider:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end)
+
+    slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP)
+    local bg = slider.bg
+    bg:SetCenterColor(0, 0, 0)
+    bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4)
+    bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4)
+    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4)
+
+    control.minText = wm:CreateControl(nil, slider, CT_LABEL)
+    local minText = control.minText
+    minText:SetFont("ZoFontGameSmall")
+    minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT)
+    minText:SetText(sliderData.min)
+
+    control.maxText = wm:CreateControl(nil, slider, CT_LABEL)
+    local maxText = control.maxText
+    maxText:SetFont("ZoFontGameSmall")
+    maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT)
+    maxText:SetText(sliderData.max)
+
+    control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop")
+    if(isInputOnRight) then
+        control.slidervalueBG:SetDimensions(60, 26)
+        control.slidervalueBG:SetAnchor(LEFT, slider, RIGHT, 5, 0)
+    else
+        control.slidervalueBG:SetDimensions(50, 16)
+        control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0)
+    end
+    control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop")
+    local slidervalue = control.slidervalue
+    slidervalue:ClearAnchors()
+    slidervalue:SetAnchor(TOPLEFT, control.slidervalueBG, TOPLEFT, 3, 1)
+    slidervalue:SetAnchor(BOTTOMRIGHT, control.slidervalueBG, BOTTOMRIGHT, -3, -1)
+    slidervalue:SetTextType(TEXT_TYPE_NUMERIC)
+    if(isInputOnRight) then
+        slidervalue:SetFont("ZoFontGameLarge")
+    else
+        slidervalue:SetFont("ZoFontGameSmall")
+    end
+
+    local isHandlingChange = false
+    local function HandleValueChanged(value)
+        if isHandlingChange then return end
+        if sliderData.decimals then
+            value = RoundDecimalToPlace(value, sliderData.decimals)
+        end
+        isHandlingChange = true
+        slider:SetValue(value)
+        slidervalue:SetText(value)
+        isHandlingChange = false
+    end
+
+    slidervalue:SetHandler("OnEscape", function(self)
+        HandleValueChanged(sliderData.getFunc())
+        self:LoseFocus()
+    end)
+    slidervalue:SetHandler("OnEnter", function(self)
+        self:LoseFocus()
+    end)
+    slidervalue:SetHandler("OnFocusLost", function(self)
+        local value = tonumber(self:GetText())
+        control:UpdateValue(false, value)
+    end)
+    slidervalue:SetHandler("OnTextChanged", function(self)
+        local input = self:GetText()
+        if(#input > 1 and not input:sub(-1):match("[0-9]")) then return end
+        local value = tonumber(input)
+        if(value) then
+            HandleValueChanged(value)
+        end
+    end)
+    if(sliderData.autoSelect) then
+        ZO_PreHookHandler(slidervalue, "OnFocusGained", function(self)
+            self:SelectAll()
+        end)
+    end
+
+    local range = maxValue - minValue
+    slider:SetValueStep(sliderData.step or 1)
+    slider:SetHandler("OnValueChanged", function(self, value, eventReason)
+        if eventReason == EVENT_REASON_SOFTWARE then return end
+        HandleValueChanged(value)
+    end)
+    slider:SetHandler("OnSliderReleased", function(self, value)
+        control:UpdateValue(false, value)
+    end)
+    slider:SetHandler("OnMouseWheel", function(self, value)
+        if(not self:GetEnabled()) then return end
+        local new_value = (tonumber(slidervalue:GetText()) or sliderData.min or 0) + ((sliderData.step or 1) * value)
+        control:UpdateValue(false, new_value)
+    end)
+
+    if sliderData.warning ~= nil or sliderData.requiresReload then
+        control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon")
+        control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0)
+        control.UpdateWarning = LAM.util.UpdateWarning
+        control:UpdateWarning()
+    end
+
+    control.UpdateValue = UpdateValue
+    control:UpdateValue()
+
+    if sliderData.disabled ~= nil then
+        control.UpdateDisabled = UpdateDisabled
+        control:UpdateDisabled()
+    end
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+    LAM.util.RegisterForReloadIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/submenu.lua b/libs/LibAddonMenu-2.0/controls/submenu.lua
new file mode 100644
index 0000000..1766a1f
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/submenu.lua
@@ -0,0 +1,108 @@
+--[[submenuData = {
+    type = "submenu",
+    name = "Submenu Title", -- or string id or function returning a string
+    tooltip = "My submenu tooltip", -- -- or string id or function returning a string (optional)
+    controls = {sliderData, buttonData} --(optional) used by LAM
+    reference = "MyAddonSubmenu" --(optional) unique global reference to control
+} ]]
+
+local widgetVersion = 11
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("submenu", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+local am = ANIMATION_MANAGER
+
+local function UpdateValue(control)
+    control.label:SetText(LAM.util.GetStringFromValue(control.data.name))
+    if control.data.tooltip then
+        control.label.data.tooltipText = LAM.util.GetStringFromValue(control.data.tooltip)
+    end
+end
+
+local function AnimateSubmenu(clicked)
+    local control = clicked:GetParent()
+    control.open = not control.open
+
+    if control.open then
+        control.animation:PlayFromStart()
+    else
+        control.animation:PlayFromEnd()
+    end
+end
+
+function LAMCreateControl.submenu(parent, submenuData, controlName)
+    local width = parent:GetWidth() - 45
+    local control = wm:CreateControl(controlName or submenuData.reference, parent.scroll or parent, CT_CONTROL)
+    control.panel = parent
+    control.data = submenuData
+
+    control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel")
+    local label = control.label
+    label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5)
+    label:SetDimensions(width, 30)
+    label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS)
+    label:SetText(LAM.util.GetStringFromValue(submenuData.name))
+    label:SetMouseEnabled(true)
+    if submenuData.tooltip then
+        label.data = {tooltipText = LAM.util.GetStringFromValue(submenuData.tooltip)}
+        label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+        label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    end
+
+    control.scroll = wm:CreateControl(nil, control, CT_SCROLL)
+    local scroll = control.scroll
+    scroll:SetParent(control)
+    scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10)
+    scroll:SetDimensionConstraints(width + 5, 0, width + 5, 0)
+
+    control.bg = wm:CreateControl(nil, label, CT_BACKDROP)
+    local bg = control.bg
+    bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5)
+    bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0)
+    bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16)
+    bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds")
+    bg:SetInsets(16, 16, -16, -16)
+
+    control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE)
+    local arrow = control.arrow
+    arrow:SetDimensions(28, 28)
+    arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds") --list_sortup for the other way
+    arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5)
+
+    --figure out the cool animation later...
+    control.animation = am:CreateTimeline()
+    local animation = control.animation
+    animation:SetPlaybackType(ANIMATION_SIZE, 0) --2nd arg = loop count
+
+    control:SetResizeToFitDescendents(true)
+    control.open = false
+    label:SetHandler("OnMouseUp", AnimateSubmenu)
+    animation:SetHandler("OnStop", function(self, completedPlaying)
+        scroll:SetResizeToFitDescendents(control.open)
+        if control.open then
+            control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds")
+            scroll:SetResizeToFitPadding(5, 20)
+        else
+            control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds")
+            scroll:SetResizeToFitPadding(5, 0)
+            scroll:SetHeight(0)
+        end
+    end)
+
+    --small strip at the bottom of the submenu that you can click to close it
+    control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE)
+    local btmToggle = control.btmToggle
+    btmToggle:SetMouseEnabled(true)
+    btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT)
+    btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT)
+    btmToggle:SetHeight(15)
+    btmToggle:SetAlpha(0)
+    btmToggle:SetHandler("OnMouseUp", AnimateSubmenu)
+
+    control.UpdateValue = UpdateValue
+
+    LAM.util.RegisterForRefreshIfNeeded(control)
+
+    return control
+end
diff --git a/libs/LibAddonMenu-2.0/controls/texture.lua b/libs/LibAddonMenu-2.0/controls/texture.lua
new file mode 100644
index 0000000..29dda7c
--- /dev/null
+++ b/libs/LibAddonMenu-2.0/controls/texture.lua
@@ -0,0 +1,45 @@
+--[[textureData = {
+    type = "texture",
+    image = "file/path.dds",
+    imageWidth = 64, --max of 250 for half width, 510 for full
+    imageHeight = 32, --max of 100
+    tooltip = "Image's tooltip text.", -- or string id or function returning a string (optional)
+    width = "full", --or "half" (optional)
+    reference = "MyAddonTexture" --(optional) unique global reference to control
+} ]]
+
+--add texture coords support?
+
+local widgetVersion = 9
+local LAM = LibStub("LibAddonMenu-2.0")
+if not LAM:RegisterWidget("texture", widgetVersion) then return end
+
+local wm = WINDOW_MANAGER
+
+local MIN_HEIGHT = 26
+function LAMCreateControl.texture(parent, textureData, controlName)
+    local control = LAM.util.CreateBaseControl(parent, textureData, controlName)
+    local width = control:GetWidth()
+    control:SetResizeToFitDescendents(true)
+
+    if control.isHalfWidth then --note these restrictions
+        control:SetDimensionConstraints(width / 2, MIN_HEIGHT, width / 2, MIN_HEIGHT * 4)
+    else
+        control:SetDimensionConstraints(width, MIN_HEIGHT, width, MIN_HEIGHT * 4)
+    end
+
+    control.texture = wm:CreateControl(nil, control, CT_TEXTURE)
+    local texture = control.texture
+    texture:SetAnchor(CENTER)
+    texture:SetDimensions(textureData.imageWidth, textureData.imageHeight)
+    texture:SetTexture(textureData.image)
+
+    if textureData.tooltip then
+        texture:SetMouseEnabled(true)
+        texture.data = {tooltipText = LAM.util.GetStringFromValue(textureData.tooltip)}
+        texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter)
+        texture:SetHandler("OnMouseExit", ZO_Options_OnMouseExit)
+    end
+
+    return control
+end
diff --git a/libs/LibCustomTitles/LibCustomTitles.lua b/libs/LibCustomTitles/LibCustomTitles.lua
new file mode 100644
index 0000000..441c396
--- /dev/null
+++ b/libs/LibCustomTitles/LibCustomTitles.lua
@@ -0,0 +1,563 @@
+--[[
+Author: Ayantir
+Filename: LibCustomTitles.lua
+Version: 20
+]]--
+
+--[[
+
+This software is under : CreativeCommons CC BY-NC-SA 4.0
+Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
+
+You are free to:
+
+    Share — copy and redistribute the material in any medium or format
+    Adapt — remix, transform, and build upon the material
+    The licensor cannot revoke these freedoms as long as you follow the license terms.
+
+
+Under the following terms:
+
+    Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
+    NonCommercial — You may not use the material for commercial purposes.
+    ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
+    No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
+
+
+Please read full licence at :
+http://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
+
+]]--
+
+local libLoaded
+local LIB_NAME, VERSION = "LibCustomTitles", 20
+local LibCustomTitles, oldminor = LibStub:NewLibrary(LIB_NAME, VERSION)
+if not LibCustomTitles then return end
+
+function LibCustomTitles:Init()
+
+	local CT_NO_TITLE = 0
+	local CT_TITLE_ACCOUNT = 1
+	local CT_TITLE_CHARACTER = 2
+
+	-- Default override
+	local overriden = {
+		en = "Volunteer",
+		fr = "Volontaire",
+		de = "Freiwillige",
+	}
+
+	local customTitles = {
+
+		["@Ayantir"] = { -- Dev / EU. v1
+			ov = true,
+			en = "The Enlightened",
+			fr = "Mangeuse de Gâteaux",
+			de = "Die Erleuchtete",
+		},
+
+		["@Baertram"] = { -- Dev / EU. v4
+			ov = true,
+			en = "Ursa Major",
+			fr = "Ursa Major",
+			de = "Ursa Major",
+		},
+
+		["@sirinsidiator"] = { -- Dev / EU. v5
+			["Illonia Ithildû"] = {
+				ov = true,
+				en = "Planeswalker",
+				fr = "Arpenteuse de Mondes",
+				de = "Weltenwanderer",
+			},
+			ov = true,
+			en = "Absolutely Not Suspicious",
+			fr = "Carrément pas suspect",
+			de = "Absolut Nicht Verdächtig",
+		},
+
+		["@Randactyl"] = { -- Dev / NA. v6
+			["Vedrasi Rilim"] = {
+				ov = true,
+				en = "Glorious Leader",
+			},
+			ov = true,
+			en = "No Lollygaggin'",
+		},
+
+		["@Wedgez"] = { -- NA. v8
+			ov = true,
+			en = "Golden Light Master",
+		},
+
+		["@Ign0tus"] = { -- NA. v8
+			["Smudgê"] = {
+				ov = true,
+				en = "Infiltrator",
+			},
+			["Nefandus Pravus"] = {
+				ov = true,
+				en = "Nightlord",
+			},
+			["Zero Divisor"] = {
+				ov = true,
+				en = "Executioner",
+			},
+			ov = true,
+			en = "Sweetroll Thief",
+		},
+
+		["@dOpiate"] = { -- Dev / EU. v8
+			["Harmful"] = {
+				ov = {en = "Recruit", fr = "Recrue", de = "Rekrutin"},
+				en = "The Butcher",
+				fr = "Le Boucher",
+				de = "Der Metzger",
+			},
+		},
+
+		["@LadyHermione"] = { -- NA v9
+			["Lady Hermione Sophia"] = {
+				ov = true,
+				en = "Know-It-All",
+			},
+		},
+
+		["@Tarsalterror"] = { -- NA v9
+			ov = {en = "Enemy of Coldharbour", fr = "Ennemi de Havreglace", de = "Feind Kalthafens"},
+			en = "Fancy Man of Cornwood",
+		},
+
+		["@manavortex"] = { -- EU v10 (v12 changes)
+			["Vivicah Telvanni"] = {
+				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meisterin der Zauberei"},
+				en = "Archmagister",
+				fr = "Archimage",
+				de = "Erzmagister",
+			},
+			["Sugar-Paws Underfoot"] = {
+				ov = true,
+				en = "Favorite Apprentice",
+				fr = "Apprenti préféré",
+				de = "Lieblingslehrling",
+			},
+			["Ravani Indoril"] = {
+				ov = true,
+				en = "Warden",
+				fr = "Sentinelle",
+				de = "Aufseher",
+			},
+			["Telvanni Ravani Varo"] = {
+				ov = true,
+				en = "Warden",
+				fr = "Sentinelle",
+				de = "Aufseher",
+			},
+		},
+
+		["@Valorin"] = { -- EU v10
+			["Valorin Telvanni"] = {
+				ov = {en = "Savior of Nirn", fr = "Sauveur de Nirn", de = "Retter Nirns"},
+				en = "Aetherial Blade",
+				fr = "Lame Ethérée",
+				de = "Ätherklinge",
+			},
+			["Nathyn Varo"] = {
+				ov = true,
+				en = "Warden",
+				fr = "Sentinelle",
+				de = "Aufseher",
+			},
+		},
+
+		["@Manorin"] = { -- EU v10 (v12 fix)
+			["Foryn Telvanni"] = {
+				ov = {en = "Pact Hero", fr = "Héros du Pacte", de = "Held des Paktes"},
+				en = "Hero",
+				fr = "Héros",
+				de = "Helt",
+			},
+			["Serjo Vivicah Telvanni"] = {
+				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meisterin der Zauberei"},
+				en = "Archmagister",
+				fr = "Archimage",
+				de = "Erzmagister",
+			},
+		},
+
+		["@Chivana"] = { -- EU v11
+			["Chivana"] = {
+				ov = true,
+				en = "Amazon Queen",
+				fr = "Reine Amazone",
+				de = "Amazonaskönigin",
+			},
+		},
+
+		["@Mythk"] = { -- NA v11
+			ov = {en = "Recruit", fr = "Recrue", de = "Rekrutin"},
+			en = "The One and Only",
+			fr = "Le Seul et l'Unique",
+		},
+
+		["@susmitds"] = { -- NA. v11
+			["Shadow Kitter"] = {
+				ov = true,
+				en = "Emperor Slayer",
+			},
+			["Venom Kitter"] = {
+				ov = true,
+				en = "Poison Angel",
+			},
+			["Wind Kitter"] = {
+				ov = true,
+				en = "Cyclone Walker",
+			},
+			["Lumina Kitter"] = {
+				ov = true,
+				en = "Darklight Seeker",
+			},
+			["Thunder Xyler"] = {
+				ov = true,
+				en = "Unbound Infinium",
+			},
+			["Light Xyler"] = {
+				ov = true,
+				en = "Everglow Hunter",
+			},
+			["Fire Xyler"] = {
+				ov = true,
+				en = "Eternal Inferno",
+			},
+			["Void Xyler"] = {
+				ov = true,
+				en = "Existential Anomaly",
+			},
+		},
+
+		["@JasminTheSecond"] = { -- EU v11
+			["Durac"] = {
+				ov = true,
+				en = "The Lost",
+				fr = "L'égaré",
+				de = "Der Verschollene",
+			},
+		},
+
+		["@Haunted1994"] = { -- v12
+			["Jah'rakal"] = {
+				ov = {en = "Veteran", fr = "Vétéran", de = "Veteran"},
+				en = "Troll Warlord",
+				fr = "Troll Warlord",
+				de = "Troll Warlord",
+			},
+		},
+
+		["@Vortexman11"] = { -- v12
+			["Ålaunus"] = {
+				ov = true,
+				en = "The Silent",
+				fr = "Le Discret",
+				de = "Die Stille",
+			},
+		},
+
+		["@Domardal"] = { -- v12
+			ov = true,
+			en = "Coco",
+			fr = "Coco",
+			de = "Coco",
+		},
+
+		["@RaddyBK"] = { -- v12
+			["Radolfus"] = {
+				ov = {en = "Major", fr = "Major", de = "Major"},
+				en = "The Elder Dragon",
+				fr = "Le Vieux Dragon",
+				de = "The Elder Dragon",
+			},
+			["RADOLFUS II"] = {
+				ov = {en = "Executioner", fr = "Exécuteur", de = "Henker"},
+				en = "The Elder Dragon",
+				fr = "Le Vieux Dragon",
+				de = "The Elder Dragon",
+			},
+		},
+
+		["@Dolgubon"] = { -- v12
+			["Relthion"] = {
+				ov = true,
+				en = "Undying",
+				fr = "L'immortel",
+				de = "Undying",
+			},
+		},
+
+		["@Sethize"] = { -- EU v12
+			["Nelvan Telvanni"] = {
+				ov = {en = "Master Wizard", fr = "Maître mage", de = "Meister der Zauberei"},
+				en = "Master",
+				fr = "Maître",
+				de = "Meister",
+			},
+		},
+
+		["@ScattyThePirate"] = { -- EU v13
+			["Teldryn Dreth"] = {
+				ov = true,
+				en = "Warden",
+				fr = "Sentinelle",
+				de = "Aufseher",
+			},
+			["Ralyn Telvanni"] = {
+				ov = true,
+				en = "Spellwright",
+				fr = "Tisseur de Sorts",
+				--de = "Meister",
+			},
+			["Shabar-Jo"] = {
+				ov = true,
+				en = "Tisseur de Sorts",
+				fr = "Spellwright",
+				--de = "Meister",
+			},
+			["Shurkul gro-Kharzog"] = {
+				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
+				en = "The Monster",
+				fr = "La Bête",
+				de = "Das Monster",
+			},
+			["Azuk gro-Shakh"] = {
+				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
+				en = "Windsinger",
+				fr = "Ténor des tempêtes",
+				--de = "Das Monster",
+			},
+			["Xal-Shei"] = {
+				ov = {en = "Fighters Guild Victor", fr = "Champion de la guilde des guerriers", de = "Sieger der Kriegergilde"},
+				en = "Swamp Knight",
+				fr = "Chevalier des Marais",
+				--de = "Das Monster",
+			},
+		},
+
+		["@ScattyTheWizard"] = { -- v13
+			["Marukh-do"] = {
+				ov = true,
+				en = "Privateer",
+				fr = "Corsaire",
+				--de = "Meister",
+			},
+		},
+
+		["@Karstyll"] = { -- v13
+			ov = true,
+			en = "Forsaken",
+			fr = "L'oublié",
+			de = "Die Verlassene",
+		},
+
+		["@Methuselah86"] = { -- v13
+			ov = true,
+			en = "Wabbajack Warrior",
+			fr = "Guerrier de Wabbajack",
+			--de = "Die Verlassene",
+		},
+
+		["@DaedricAdept"] = { -- v14
+			ov = {en = "Pact Hero", fr = "Héros du Pacte", de = "Held des Paktes"},
+			en = "Hand of Almalexia",
+			fr = "Main d'Almalexia",
+			--de = "Die Verlassene",
+		},
+
+		["@Cloudless"] = { -- v14
+			ov = true,
+			en = "Order of Doctrine",
+			fr = "Ordre de la Doctrine",
+			--de = "Die Verlassene",
+		},
+
+		["@Atomkern"] = { -- v13
+			ov = true,
+			en = "The Refrigerator",
+			fr = "Le glacé",
+			--de = "Die Verlassene",
+		},
+
+		["@Orizonta"] = { -- v13
+			ov = true,
+			en = "Manslayer",
+			fr = "Assassin",
+			--de = "Die Verlassene",
+		},
+
+		["@laksikus"] = { -- v13
+			ov = {en = "Veteran", fr = "Vétéran", de = "Veteran"},
+			en = "Sexy Zogger",
+			fr = "Zog-Zog",
+			--de = "Die Verlassene",
+		},
+
+		["@flyty"] = { -- v13
+			ov = true,
+			en = "Always Drunk",
+			fr = "Toujours bourré",
+			--de = "Die Verlassene",
+		},
+
+		["@Deltia"] = { -- v13
+			ov = {en = "Tyro", fr = "Première classe", de = "Tyro"},
+			en = "The Destroyer",
+			fr = "Le Destructeur",
+			--de = "Die Verlassene",
+		},
+
+		["@tannips"] = { -- v13
+			ov = true,
+			en = "Potentate",
+			fr = "Potentat",
+			--de = "Die Verlassene",
+		},
+
+		["@sioniann"] = { -- v13
+			["Uloth The Furious Blade"] = {
+				ov = true,
+				en = "Sinister Turkey",
+				fr = "Dindon Sinistre",
+				--de = "Meister",
+			},
+			["Enid an Gleana"] = {
+				ov = true,
+				en = "Fountain of Auridon",
+				fr = "Fontaine d'Auridia",
+				--de = "Meister",
+			},
+		},
+
+		["@HMS-Dragonfly"] = { -- v16
+			ov = true,
+			en = "Knight of Stendarr",
+			fr = "Chevalier de Stendarr",
+			--de = "Die Verlassene",
+		},
+
+		["@Faso"] = { -- v16
+			["Fasò"] = {
+				ov = true,
+				en = "Knights Radiant",
+			},
+		},
+
+		["@nifty2g"] = { -- v16
+			["Nifty Jong-Un"] = {
+				ov = true,
+				en = "Dawn of Anu",
+			},
+		},
+
+		["@Twirlz"] = { -- v17
+			["Yirel Virith"] = {
+				ov = true,
+				en = "Nightcaller",
+			},
+		},
+
+		["@Anceane"] = { -- v19
+			ov = true,
+			en = "Dark Emerald",
+			fr = "Emeraude Sombre",
+		},
+
+		["@Potato-Salad"] = { -- v19
+			ov = true,
+			en = "Seraphim of Azura",
+			fr = "Séraphin d'Azura",
+		},
+
+		["@blakeblox"] = { -- v19
+			["fyboba"] = {
+				ov = {en = "Tyro", fr = "Première classe", de = "Tyro"},
+				en = "Golden Lady",
+			},
+		},
+
+	}
+
+	local lang = GetCVar("Language.2")
+
+	local function GetCustomTitleType(displayName, unitName)
+		if customTitles[displayName] then
+			if customTitles[displayName][unitName] then
+				return CT_TITLE_CHARACTER
+			end
+			return CT_TITLE_ACCOUNT
+		end
+		return CT_NO_TITLE
+	end
+
+	local function GetModifiedTitle(originalTitle, displayName, unitName, registerType)
+
+		local title = originalTitle
+		if registerType == CT_TITLE_CHARACTER then
+			if customTitles[displayName][unitName].ov then
+				if type(customTitles[displayName][unitName].ov) == "boolean" then
+					if originalTitle == overriden[lang] then
+						title = customTitles[displayName][unitName][lang] or originalTitle
+					end
+				elseif originalTitle == customTitles[displayName][unitName].ov[lang] then
+					title = customTitles[displayName][unitName][lang] or originalTitle
+				end
+			end
+		elseif registerType == CT_TITLE_ACCOUNT then
+			if customTitles[displayName].ov then
+				if type(customTitles[displayName].ov) == "boolean" then
+					if originalTitle == overriden[lang] then
+						title = customTitles[displayName][lang] or originalTitle
+					end
+				elseif originalTitle == customTitles[displayName].ov[lang] then
+					title = customTitles[displayName][lang] or originalTitle
+				end
+			end
+		end
+
+		return title
+
+	end
+
+	local GetUnitTitle_original = GetUnitTitle
+	GetUnitTitle = function(unitTag)
+		local unitTitleOriginal = GetUnitTitle_original(unitTag)
+		local unitDisplayName = GetUnitDisplayName(unitTag)
+		local unitCharacterName = GetUnitName(unitTag)
+		local registerType = GetCustomTitleType(unitDisplayName, unitCharacterName)
+		if registerType ~= CT_NO_TITLE then
+			return GetModifiedTitle(unitTitleOriginal, unitDisplayName, unitCharacterName, registerType)
+		end
+		return unitTitleOriginal
+	end
+
+	local GetTitle_original = GetTitle
+	GetTitle = function(index)
+		local titleOriginal = GetTitle_original(index)
+		local displayName = GetDisplayName()
+		local characterName = GetUnitName("player")
+		local registerType = GetCustomTitleType(displayName, characterName)
+		if registerType ~= CT_NO_TITLE then
+			return GetModifiedTitle(titleOriginal, displayName, characterName, registerType)
+		end
+		return titleOriginal
+	end
+
+end
+
+local function OnAddonLoaded()
+	if not libLoaded then
+		libLoaded = true
+		local LCC = LibStub('LibCustomTitles')
+		LCC:Init()
+		EVENT_MANAGER:UnregisterForEvent(LIB_NAME, EVENT_ADD_ON_LOADED)
+	end
+end
+
+EVENT_MANAGER:RegisterForEvent(LIB_NAME, EVENT_ADD_ON_LOADED, OnAddonLoaded)
\ No newline at end of file
diff --git a/libs/LibStub/LibStub.lua b/libs/LibStub/LibStub.lua
new file mode 100644
index 0000000..0e6bf67
--- /dev/null
+++ b/libs/LibStub/LibStub.lua
@@ -0,0 +1,38 @@
+-- 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
+-- LibStub developed for World of Warcraft by above members of the WowAce community.
+-- Ported to Elder Scrolls Online by Seerah
+
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 4
+local LibStub = _G[LIBSTUB_MAJOR]
+
+local strformat = string.format
+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)")
+		if type(minor) ~= "number" then
+			minor = assert(tonumber(zo_strmatch(minor, "%d+%.?%d*")), "Minor version must either be a number or contain a number.")
+		end
+
+		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(strformat("Cannot find a library instance of %q.", 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
+
+LibStub.SILENT = true
\ No newline at end of file
diff --git a/locale/de.lua b/locale/de.lua
new file mode 100644
index 0000000..5f6ee3b
--- /dev/null
+++ b/locale/de.lua
@@ -0,0 +1,179 @@
+DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
+
+local strings  = {
+
+
+	DAS_SI_INVITE_TRUE 		= "Automatisches Einladen: Aktiviert",
+	DAS_SI_INVITE_FALSE 	= "Automatisches Einladen: Deaktiviert",
+	DAS_SI_ACCEPT_TRUE 		= "Geteilte Quests werden automatisch akzeptiert",
+	DAS_SI_ACCEPT_FALSE 	= "Geteilte Quests werden nicht automatisch akzeptiert",
+	DAS_SI_SHARE_TRUE 		= "Teilt deine aktiven Quests jedes Mal, wenn ein neues Gruppenmitglied dazukommt, oder wenn jemand 'share' oder 'quest' in den Gruppenchat schreibt\nRechtsklick um alle Quests zu teilen",
+	DAS_SI_SHARE_FALSE 		= "Automatisches Teilen deaktiviert",
+	DAS_SI_SPAM 			= "Klicken, um in den Chat zu spammen",
+	DAS_SI_SPAM_VERBOSE 	= "Klicken, um nach Quests zu fragen",
+
+	DAS_SI_HIDE		 		= "DailyAutoShare ausblenden",
+
+	DAS_SI_TOGGLE	 		= "Toggle hidden",
+	DAS_SI_MINIMISE	 		= "Toggle minimised",
+
+	DAS_SI_DONATE	 		=  "Klicken für ein Dankeschön:\nLinks: 2k\nRechts: 10k\nMitte: 25k\nIch freue mich  über Feedback und/oder Spenden! :)",
+
+	DAS_SI_SHARE	 		= "Teilen",
+	DAS_SI_TRACK	 		= "* Verfolgen",
+	DAS_SI_ABANDON	 		= "|cFF0000Abbrechen|r",
+	DAS_SI_SPAM_SINGLE	 	= "Spammen",
+	DAS_SI_REFRESH	 		="Aktualisieren",
+
+
+	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
+	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
+
+
+	-- Clockwork City
+	DAS_CLOCK_IMP		 = "Das Reizen des Unvollendeten",
+	DAS_CLOCK_FOE		 = "Ein feingefiederter Feind",
+
+    -- Clockwork City
+	DAS_CLOCK_BOSS_START	 = "I'll take on a contract.",
+	DAS_CLOCK_CRAFT_START    = "Got any work?",
+	DAS_CLOCK_CAVE_START     = "What's the job?",
+	DAS_CLOCK_CROW_START     = "How can I help?",
+
+	DAS_CLOCK_CRAFT_CLOTH	 = "Lose Fasern",
+	DAS_CLOCK_CRAFT_WATER	 = "Eine klebrige Lösung",
+	DAS_CLOCK_CRAFT_RUNE	 = "Verzauberte Ansammlung",
+	DAS_CLOCK_CRAFT_SMITH	 = "Das tägliche Zermahlen",
+	DAS_CLOCK_CRAFT_ALCH	 = "Eine bittere Pille",
+	DAS_CLOCK_CRAFT_WOOD	 = "Brennstoff für unsere Feuer",
+
+	DAS_CLOCK_DELVE_FILT	 = "Filterwechsel",
+	DAS_CLOCK_DELVE_FANS	 = "Die Ventilatoren ölen",
+	DAS_CLOCK_DELVE_COMM	 = "Gleichrichterersatz",
+	DAS_CLOCK_DELVE_MALF	 = "Eine schattige Fehlfunktion",
+	DAS_CLOCK_DELVE_MISP	 = "Ein verlegter Schatten",
+	DAS_CLOCK_DELVE_AGAI	 = "Zurück in die Schatten",
+
+	DAS_CLOCK_CROW_GLIT		 = "Glitzern und Funkeln",
+	DAS_CLOCK_CROW_TRIB		 = "Eine Frage des Tributs",
+	DAS_CLOCK_CROW_NIBB		 = "Stückchen und Häppchen",
+	DAS_CLOCK_CROW_MORS		 = "Bröckchen und Bisschen",
+	DAS_CLOCK_CROW_RESP		 = "Eine Frage des Respekts",
+	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
+
+	-- Morrowind dailies
+	DAS_M_REL_ASHAL =  "Relikte von Ashalmawia",
+	DAS_M_REL_ASSAR =  "Relikte von Assarnatamat",
+	DAS_M_REL_ASHUR =  "Relikte von Ashurnabitashpi",
+	DAS_M_REL_DUSHA =  "Relikte von Dushariran",
+	DAS_M_REL_EBERN =  "Relikte von Ebernanit",
+	DAS_M_REL_MAELK =  "Relikte von Maelkashishi",
+	DAS_M_REL_YASAM =  "Relikte von Yasammidan",
+
+	DAS_M_HUNT_EATER =  "Jagd auf Aschfresser",
+	DAS_M_HUNT_ZEXXI =  "Jagd auf den großen Zexxin",
+	DAS_M_HUNT_RAZOR =  "Jagd auf König Klingenhauer",
+	DAS_M_HUNT_JAGGE =  "Jagd auf Mutter Zackige-Klaue",
+	DAS_M_HUNT_STOMP =  "Jagd auf den alten Stampfer",
+	DAS_M_HUNT_TARRA =  "Jagd auf Tarra-Suj",
+	DAS_M_HUNT_SVEET =  "Jagd auf den sich windenden Sveeth",
+
+	-- Cave dailies (Hall of Justice)
+	DAS_M_DELVE_DAEDR =  "Daedrische Störungen",
+	DAS_M_DELVE_KWAMA =  "Quatsch mit Kwama",
+	DAS_M_DELVE_MISIN =  "Das Streuen von Fehlinformationen",
+	DAS_M_DELVE_TAXES =  "Steuerabzug",
+	DAS_M_DELVE_TRIBA =  "Stammessorgen",
+	DAS_M_DELVE_SYNDI =  "Ein Syndikat in Unruhe",
+
+	-- World boss dailies (Hall of Justice)
+	DAS_M_BOSS_WUYWU        =  "Ein schleichender Hunger",
+	DAS_M_BOSS_SWARM        =  "Das Ausdünnen des Schwarms",
+	DAS_M_BOSS_NILTH        =  "Frei laufende Ochsen",
+	DAS_M_BOSS_SALOT        =  "Salothans Fluch",
+	DAS_M_BOSS_SIREN        =  "Sirenensang",
+	DAS_M_BOSS_APPRE        =  "Der besorgte Lehrling",
+
+
+	-- wrothgar dailies
+    DAS_W_POACHERS        = "Fleisch für die Massen",
+    DAS_W_EDU             = "So riecht ein falsches Spiel",
+	DAS_W_NYZ             = "Schnee und Dampf",
+    DAS_W_CORI            = "Die Gabe der Natur",
+    DAS_W_DOLMEN       	  = "Der Frevel des Unwissens",
+    DAS_W_OGRE            = "Gelehrtes Bergungsgut",
+
+	-- wrothgar single
+	DAS_W_HARPIES 		    = "Ein bizarres Frühstück",
+	DAS_W_SPIRITS 		    = "Freie Geister",
+	DAS_W_DURZOGS 		    = "Der volle Bauch",
+	DAS_W_DWEMER 		    = "Teile des Ganzen",
+	DAS_W_WEREWOLVES	    = "Das Geschäft mit der Haut",
+	DAS_W_THAT_OTHER	    = "Feuer in der Feste",
+
+
+	-- gold coast
+	DAS_DB_MINO			    = "Drohende Schatten",
+	DAS_DB_ARENA 		    = "Das Jubeln der Menge",
+	DAS_DB_GOOD 		    = "Das Gemeinwohl",
+	DAS_DB_EVIL 		    = "Das Übel unter der Erde",
+
+	-- new life
+	DAS_NL_STORMHAVEN	    = "Burgbardenherausforderung",
+	DAS_NL_STONEFALLS	    = "Lavafußstampfer",
+	DAS_NL_ALIKR		    = "Signalfeuersprint",
+	DAS_NL_SHADOWFEN	    = "Fischgunstfestmahl",
+	DAS_NL_GRAHTWOOD	    = "Kriegsweisenreise",
+	DAS_NL_REAPERSMARCH	    = "Prüfung der Fünfkrallenlist",
+	DAS_NL_BETNIKH		    = "Steinzahnsause",
+	DAS_NL_AURIDON		    = "Schlammballspiele",
+	DAS_NL_EASTMARCH	    = "Schneebärensprung",
+
+	-- craglorn
+	-- lower
+	DAS_CRAG_SARA 		 = "Kritische Masse",
+	DAS_CRAG_SHADA 		 = "Die gefallene Stadt Shada",
+	DAS_CRAG_NEDE 		 = "Der Grund für unseren Kampf",	-- this is not a single daily, it's part off The fallen City of Shada
+	DAS_CRAG_HERMY 		 = "Das Archiv des Suchers",
+	DAS_CRAG_ELINHIR 	 = "Unbeschreibliche Macht",
+	DAS_CRAG_TUWHACCA 	 = "Die Prüfungen von Rahni’Za",
+	DAS_CRAG_NEREID 	 = "Wenn das Wasser giftig wird",	-- this is not a single daily, it's part off The fallen City of Shada
+
+	-- upper
+	DAS_CRAG_NIRNCRUX	 = "Das Blut Nirns",
+	DAS_CRAG_WORLDTRIP 	 = "Der graue Lauf",
+	DAS_CRAG_SCALES 	 = "Eisen und Schuppen",
+	DAS_CRAG_NECRO 		 = "Die Seelen der Verratenen",
+	DAS_CRAG_KIDNAP 	 = "Lebendig gefangen",
+	DAS_CRAG_HITMAN 	 = "Die wahren Giftzähne",
+	DAS_CRAG_DUNGEON 	 = "Entfesselt",
+
+
+    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
+    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
+
+    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
+    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
+    DAS_QUEST_CC_NOVICE     = "Novice Holli",
+    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
+    DAS_QUEST_CC_DARO       = "Adjunct Daro",
+    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
+
+    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
+    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
+
+    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
+
+    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
+
+    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
+
+
+
+}
+DAS_STRINGS_LOCALE.de = strings
+
+for stringId, stringValue in pairs(strings) do
+	ZO_CreateStringId(stringId, stringValue)
+	SafeAddVersion(stringId, 2)
+end
\ No newline at end of file
diff --git a/locale/en.lua b/locale/en.lua
new file mode 100644
index 0000000..60fab5c
--- /dev/null
+++ b/locale/en.lua
@@ -0,0 +1,212 @@
+DailyAutoShare = DailyAutoShare or {}
+DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
+local strings  = {
+	-- UI stuffs
+	DAS_SI_INVITE_TRUE 		= "Invite is now on",
+	DAS_SI_INVITE_FALSE 	= "Invite is now off",
+	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
+	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
+	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
+	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
+	DAS_SI_SPAM 			= "Click to spam in zone chat",
+	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
+
+	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
+	DAS_SI_TOGGLE	 		= "Toggle hidden",
+	DAS_SI_MINIMISE	 		= "Toggle minimised",
+	DAS_SI_REFRESH	 		= "Refresh",
+
+	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
+
+	DAS_SI_SHARE	 		= "Share",
+	DAS_SI_TRACK	 		= "* Track",
+	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
+	DAS_SI_SPAM_SINGLE	 	= "Spam",
+	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
+	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
+
+	-- Clockwork City
+	DAS_CLOCK_IMP			 = "Inciting the Imperfect",
+	DAS_CLOCK_FOE			 = "A Fine-Feathered Foe",
+
+
+	DAS_CLOCK_CRAFT_CLOTH	 = "Loose Strands",
+	DAS_CLOCK_CRAFT_WATER	 = "A Sticky Solution",
+	DAS_CLOCK_CRAFT_RUNE	 = "Enchanted Accumulation",
+	DAS_CLOCK_CRAFT_SMITH	 = "A Daily Grind",
+	DAS_CLOCK_CRAFT_ALCH	 = "A Bitter Pill",
+	DAS_CLOCK_CRAFT_WOOD	 = "Fuel for our Fires",
+
+	DAS_CLOCK_DELVE_FILT	 = "Changing the Filters",
+	DAS_CLOCK_DELVE_FANS	 = "Oiling the Fans",
+	DAS_CLOCK_DELVE_COMM	 = "Replacing the Commutators",
+	DAS_CLOCK_DELVE_MALF	 = "A Shadow Malfunction",
+	DAS_CLOCK_DELVE_MISP	 = "A Shadow Misplaced",
+	DAS_CLOCK_DELVE_AGAI	 = "Again Into the Shadows",
+
+	DAS_CLOCK_CROW_GLIT		 = "Glitter and Gleam",
+	DAS_CLOCK_CROW_TRIB		 = "A Matter of Tributes",
+	DAS_CLOCK_CROW_NIBB		 = "Nibbles and Bits",
+	DAS_CLOCK_CROW_MORS		 = "Morsels and Pecks",
+	DAS_CLOCK_CROW_RESP		 = "A Matter of Respect",
+	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
+
+	-- Morrowind dailies
+	DAS_M_REL_ASHAL          =  "Relics of Ashalmawia",
+	DAS_M_REL_ASSAR          =  "Relics of Assarnatamat",
+	DAS_M_REL_ASHUR          =  "Relics of Ashurnabitashpi",
+	DAS_M_REL_DUSHA          =  "Relics of Dushariran",
+	DAS_M_REL_EBERN          =  "Relics of Ebernanit",
+	DAS_M_REL_MAELK          =  "Relics of Maelkashishi",
+	DAS_M_REL_YASAM          =  "Relics of Yasammidan",
+
+	DAS_M_HUNT_EATER         =  "Ash-Eater Hunt",
+	DAS_M_HUNT_ZEXXI         =  "Great Zexxin Hunt",
+	DAS_M_HUNT_RAZOR         =  "King Razor-Tusk Hunt",
+	DAS_M_HUNT_JAGGE         =  "Mother Jagged-Claw Hunt",
+	DAS_M_HUNT_STOMP         =  "Old Stomper Hunt",
+	DAS_M_HUNT_TARRA         =  "Tarra-Suj Hunt",
+	DAS_M_HUNT_SVEET         =  "Writhing Sveeth Hunt",
+
+	-- World boss dailies (Hall of Justice)
+	DAS_M_BOSS_WUYWU         =  "A Creeping Hunger",
+	DAS_M_BOSS_SWARM         =  "Culling the Swarm",
+	DAS_M_BOSS_NILTH         =  "Oxen Free",
+	DAS_M_BOSS_SALOT         =  "Salothan's Curse",
+	DAS_M_BOSS_SIREN         =  "Siren's Song",
+	DAS_M_BOSS_APPRE         =  "The Anxious Apprentice",
+
+	-- Cave dailies (Hall of Justice)
+	DAS_M_DELVE_DAEDR        =  "Daedric Disruptions",
+	DAS_M_DELVE_KWAMA        =  "Kwama Conundrum",
+	DAS_M_DELVE_MISIN        =  "Planting Misinformation",
+	DAS_M_DELVE_TAXES        =  "Tax Deduction",
+	DAS_M_DELVE_TRIBA        =  "Tribal Troubles",
+	DAS_M_DELVE_SYNDI        =  "Unsettled Syndicate",
+
+	-- wrothgar dailies
+    DAS_W_POACHERS          = "Meat for the Masses",
+    DAS_W_EDU               = "Reeking of Foul Play",
+    DAS_W_NYZ               = "Snow and Steam",
+    DAS_W_CORI              = "Nature's Bounty",
+    DAS_W_DOLMEN            = "Heresy of Ignorance",
+    DAS_W_OGRE              = "Scholarly Salvage",
+
+	-- wrothgar single
+	DAS_W_HARPIES 		    = "Breakfast of the Bizarre",
+	DAS_W_SPIRITS 		    = "Free Spirits",
+	DAS_W_DURZOGS 		    = "Getting a Bellyful",
+	DAS_W_DWEMER 		    = "Parts of the Whole",
+	DAS_W_WEREWOLVES	    = "The Skin Trade",
+	DAS_W_THAT_OTHER	    = "Fire in the Hold",
+
+
+	-- gold coast
+	DAS_DB_MINO			    = "Looming Shadows",
+	DAS_DB_ARENA 		    = "The Roar of the Crowds",
+	DAS_DB_GOOD 		    = "The Common Good",
+	DAS_DB_EVIL 		    = "Buried Evil",
+
+	-- new life
+	DAS_NL_STORMHAVEN	    = "Castle Charm Challenge",
+	DAS_NL_STONEFALLS	    = "Lava Foot Stomp",
+	DAS_NL_ALIKR		    = "Signal Fire Sprint",
+	DAS_NL_SHADOWFEN	    = "Fish Boon Feast",
+	DAS_NL_GRAHTWOOD	    = "War Orphan's Sojourn",
+	DAS_NL_REAPERSMARCH	    = "The Trial of Five-Clawed Guile",
+	DAS_NL_BETNIKH		    = "Stonetooth Bash",
+	DAS_NL_AURIDON		    = "Mud Ball Merriment",
+	DAS_NL_EASTMARCH	    = "Snow Bear Plunge",
+
+	-- craglorn
+	-- lower
+	DAS_CRAG_SARA 		    = "Critical Mass",
+	DAS_CRAG_SHADA 		    = "The Fallen City of Shada",
+	DAS_CRAG_NEDE 		    = "The Reason We Fight",
+	DAS_CRAG_HERMY 		    = "The Seeker’s Archive",
+	DAS_CRAG_ELINHIR 	    = "Supreme Power",
+	DAS_CRAG_TUWHACCA 	    = "The Trials of Rahni’Za",
+	DAS_CRAG_NEREID 	    = "Waters Run Foul",
+
+	-- upper
+	DAS_CRAG_NIRNCRUX	    = "The Blood of Nirn",
+	DAS_CRAG_WORLDTRIP 	    = "The Gray Passage",
+	DAS_CRAG_SCALES 	    = "Iron and Scales",
+	DAS_CRAG_NECRO 		    = "Souls of the Betrayed",
+	DAS_CRAG_KIDNAP 	    = "Taken Alive",
+	DAS_CRAG_HITMAN 	    = "The Truer Fangs",
+	DAS_CRAG_DUNGEON 	    = "Uncaged",
+
+
+    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
+    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
+
+    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
+    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
+    DAS_QUEST_CC_NOVICE     = "Novice Holli",
+    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
+    DAS_QUEST_CC_DARO       = "Adjunct Daro",
+    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
+
+    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
+    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
+
+    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
+
+    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
+
+    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
+
+    DAS_QUEST_CAP_CARDEA    = "Cardea Gallus",
+    DAS_QUEST_CAP_ALVUR     = "Alvur Baren",
+    DAS_QUEST_CAP_BOLGRUL   = "Bolgrul",
+
+    -- don't need translation for anyone but the russians - I think
+
+    DAS_QUEST_DB_LARONEN    = "Laronen",
+    DAS_QUEST_DB_FINIA      = "Finia Sele",
+    DAS_QUEST_DB_CODUS      = "Codus ap Dugal",
+
+    DAS_QUEST_W_NEDNOR      = "Nednor",
+    DAS_QUEST_W_THAZEK      = "Thazeg",
+    DAS_QUEST_W_ARUSHNA     = "Arushna",
+    DAS_QUEST_W_LILYAMEH    = "Lilyameh",
+    DAS_QUEST_W_BAGRUBESH   = "Bagrugbesh",
+    DAS_QUEST_W_CIRANTILLE  = "Cirantille",
+    DAS_QUEST_W_MENNINIA    = "Menninia",
+    DAS_QUEST_W_SONOLIA     = "Sonolia Muspidius",
+    DAS_QUEST_W_RAYNOR      = "Raynor Vanos", -- maybe not include Raynor?
+
+    DAS_QUEST_M_TRAYLAN     = "Traylan Omoril",
+    DAS_QUEST_M_BELERU      = "Beleru Omoril",
+    DAS_QUEST_M_NUMANI      = "Numani-Rasi",
+    DAS_QUEST_M_NARA        = "Nara Varam",
+    DAS_QUEST_M_TIRVINA     = "Tirvina Avani",
+    DAS_QUEST_M_DINOR       = "Dinor Salvi",
+    DAS_QUEST_M_BRAVOSI     = "Bravosi Felder",
+    DAS_QUEST_M_IVULEN      = "Ivulen Andromo",
+    DAS_QUEST_M_SAVILE      = "Savile Alam",
+    DAS_QUEST_M_KYLIA       = "Kylia Thando",
+    DAS_QUEST_M_EVOS        = "Evos Hledas",
+    DAS_QUEST_M_ALVES       = "Alves Droth",
+    DAS_QUEST_M_DREDASE     = "Dredase-Hlarar",
+    DAS_QUEST_M_VORAR       = "Vorar Vendu",
+    DAS_QUEST_M_VALGA       = "Valga Celatus",
+
+    DAS_QUEST_CC_ORC        = "Razgurug",
+    DAS_QUEST_CC_COOK       = "Aveberl Tremouille",
+    DAS_QUEST_CC_MINDORA    = "Mindora",
+    DAS_QUEST_CC_NJORD      = "Njordemar",
+    DAS_QUEST_CC_IGMUND     = "Igmund",
+
+    DAS_QUEST_W_GURUZUG     = "Guruzug",
+    DAS_QUEST_W_ARZORAG     = "Arzorag",
+
+}
+DailyAutoShare.EnglishQuestNames = strings
+DAS_STRINGS_LOCALE.en = strings
+
+for stringId, stringValue in pairs(strings) do
+	ZO_CreateStringId(stringId, stringValue)
+	SafeAddVersion(stringId, 1)
+end
diff --git a/locale/fr.lua b/locale/fr.lua
new file mode 100644
index 0000000..4d1e572
--- /dev/null
+++ b/locale/fr.lua
@@ -0,0 +1,167 @@
+DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
+
+local strings  = {
+
+	DAS_SI_INVITE_TRUE 		= "Invite auto activé",
+	DAS_SI_INVITE_FALSE 	= "Invite auto désactivé",
+	DAS_SI_ACCEPT_TRUE 		= "Accepte automatiquement les quêtes quotidienne partagées",
+	DAS_SI_ACCEPT_FALSE 	= "N'accepte pas automatiquement les quêtes",
+	DAS_SI_SHARE_TRUE 		= "Partager automatiquement votre quête quotidienne active avec le groupe ou 'share' dans le chat de groupe (Clic droit pour partager votre quête active)",
+	DAS_SI_SHARE_FALSE 		= "Ne partage pas votre quête active (Clic droit pour partager)",
+	DAS_SI_SPAM 			= "Clic pour spam dans le chat de zone",
+	DAS_SI_SPAM_VERBOSE 	= "Clic pour demander poliment une part du quest le chat de zone",
+
+	DAS_SI_HIDE		 		= "Cacher DailyAutoShare",
+	DAS_SI_TOGGLE	 		= "Toggle hidden",
+	DAS_SI_MINIMISE	 		= "Toggle minimised",
+	DAS_SI_REFRESH	 		= "Mettre a jour",
+
+	DAS_SI_DONATE	 		= "Clic pour remercier:\nGauche: 2k\nDroit: 10k\nMilieu: 25k\nVos commentaires et/ou don seront apprécié!",
+
+	DAS_SI_SHARE	 		= "Share",
+	DAS_SI_TRACK	 		= "* Track",
+	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
+	DAS_SI_SPAM_SINGLE	 	= "Rechercher cette quête uniquement",
+	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
+	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
+
+	-- Clockwork City
+	DAS_CLOCK_IMP			= "Attirer l'Imparfait",
+	DAS_CLOCK_FOE			= "Un si beau plumage",
+
+	DAS_CLOCK_CRAFT_CLOTH	= "Détails à régler",
+	DAS_CLOCK_CRAFT_WATER	= "La poisse",
+	DAS_CLOCK_CRAFT_RUNE	= "Accumulation enchantée",
+	DAS_CLOCK_CRAFT_SMITH	= "Chaque jour sur le métier",
+	DAS_CLOCK_CRAFT_ALCH	= "Pilule amère",
+	DAS_CLOCK_CRAFT_WOOD	= "Ce qui alimente nos feux",
+
+	DAS_CLOCK_DELVE_FILT	= "Changer les filtres",
+	DAS_CLOCK_DELVE_FANS	= "Graisser les ventilateurs",
+	DAS_CLOCK_DELVE_COMM	= "Remplacer les commutateurs",
+	DAS_CLOCK_DELVE_MALF	= "Une avarie d'ombre",
+	DAS_CLOCK_DELVE_MISP	= "Une ombre égarée",
+	DAS_CLOCK_DELVE_AGAI	= "Retour dans les ombres vertes",
+
+	DAS_CLOCK_CROW_GLIT		= "Lueur et Chatoiement",
+	DAS_CLOCK_CROW_TRIB		= "Une affaire de tributs",
+	DAS_CLOCK_CROW_NIBB		= "Petites bouchées",
+	DAS_CLOCK_CROW_MORS		= "Morceaux de choix",
+	DAS_CLOCK_CROW_RESP		= "Une histoire de respect",
+	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
+
+	-- Morrowind dailies
+	DAS_M_REL_ASHAL 		= "Reliques d'Ashalmawia",
+	DAS_M_REL_ASSAR 		= "Reliques d'Assarnatamat",
+	DAS_M_REL_ASHUR 		= "Reliques d'Ashurnabitashpi",
+	DAS_M_REL_DUSHA 		= "Reliques de Dushariran",
+	DAS_M_REL_EBERN 		= "Reliques d'Ebernanit",
+	DAS_M_REL_MAELK 		= "Reliques de Maelkashishi",
+	DAS_M_REL_YASAM 		= "Reliques de Yasammidan",
+
+	DAS_M_HUNT_EATER 		= "Chasse à Gobe-cendre",
+	DAS_M_HUNT_ZEXXI 		= "Chasse au Grand Zexxin",
+	DAS_M_HUNT_RAZOR 		= "Chasse au Roi Défense-rasoir",
+	DAS_M_HUNT_JAGGE 		= "Mère Griffe-dentelée",
+	DAS_M_HUNT_STOMP 		= "Chasse au vieux piétineur",
+	DAS_M_HUNT_TARRA 		= "Chasse de Tarra-Suj",
+	DAS_M_HUNT_SVEET 		= "Chasse au sveeth ondulant",
+
+	-- Cave dailies (Hall of Justice)
+	DAS_M_DELVE_DAEDR 		= "Perturbations daedriques",
+	DAS_M_DELVE_KWAMA 		= "L'équation kwama",
+	DAS_M_DELVE_MISIN 		= "Plantage à la plantation",
+	DAS_M_DELVE_TAXES 		= "Déduction fiscale",
+	DAS_M_DELVE_TRIBA 		= "Tribus troublées",
+	DAS_M_DELVE_SYNDI 		= "Mouvement syndical",
+
+	-- World boss dailies (Hall of Justice)
+	DAS_M_BOSS_WUYWU 		= "Une faim dévorante",
+	DAS_M_BOSS_SWARM 		= "Réduire le troupeau",
+	DAS_M_BOSS_NILTH 		= "Garanti sans bœuf",
+	DAS_M_BOSS_SALOT 		= "Malédiction de Salothan",
+	DAS_M_BOSS_SIREN 		= "Chant de la sirène",
+	DAS_M_BOSS_APPRE 		= "L'Apprenti anxieux",
+
+	-- wrothgar dailies
+    DAS_W_POACHERS      	= "Nourrir les foules",
+    DAS_W_EDU          		= "L'odeur du crime",
+    DAS_W_NYZ          		= "Neige et vapeur",
+    DAS_W_CORI         		= "Abondance de la nature",
+    DAS_W_DOLMEN       		= "Hérésie par l'ignorance",
+    DAS_W_OGRE           	= "Sauvetage académique",
+
+	-- wrothgar single
+	DAS_W_HARPIES 			= "Petit-déjeuner de l'étrange",
+	DAS_W_SPIRITS 			= "Esprits libres",
+	DAS_W_DURZOGS 			= "Plein la panse !",
+	DAS_W_DWEMER 			= "Parties du tout",
+	DAS_W_WEREWOLVES		= "Commerce de peaux",
+	DAS_W_THAT_OTHER		= "Incendie au fort",
+
+	-- gold coast
+	DAS_DB_MINO				= "Ombres menaçantes",
+	DAS_DB_ARENA 			= "Le hurlement des foules",
+	DAS_DB_EVIL 			= "Mal enfoui",
+	DAS_DB_GOOD 			= "Le bien commun",
+
+	-- new life
+	DAS_NL_STORMHAVEN		= "Castle Charm Challenge",
+	DAS_NL_STONEFALLS		= "Lava Foot Stomp",
+	DAS_NL_ALIKR			= "Signal Fire Sprint",
+	DAS_NL_SHADOWFEN		= "Fish Boon Feast",
+	DAS_NL_GRAHTWOOD		= "War Orphan's Sojourn",
+	DAS_NL_REAPERSMARCH		= "The Trial of Five-Clawed Guile",
+	DAS_NL_BETNIKH			= "Stonetooth Bash",
+	DAS_NL_AURIDON			= "Mud Ball Merriment",
+	DAS_NL_EASTMARCH		= "Snow Bear Plunge",
+
+
+	-- craglorn
+	-- lower
+	DAS_CRAG_SARA 			 = "Masse critique",
+	DAS_CRAG_SHADA 			 = "La cité perdue de Shada",
+	DAS_CRAG_NEDE 			 = "Notre cause",
+	DAS_CRAG_HERMY 			 = "L'Archive des Sourciers",
+	DAS_CRAG_ELINHIR 		 = "Puissance supérieur",
+	DAS_CRAG_TUWHACCA 		 = "Les épreuves de Rahni’Za",
+	DAS_CRAG_NEREID 		 = "Les eaux se troubles",
+
+	-- upper
+	DAS_CRAG_NIRNCRUX		 = "Le sang de Nirn",
+	DAS_CRAG_WORLDTRIP 		 = "Passage gris",
+	DAS_CRAG_SCALES 		 = "Fer et écailles",
+	DAS_CRAG_NECRO 			 = "Les âmes des trahis",
+	DAS_CRAG_KIDNAP 		 = "Capturés vivants",
+	DAS_CRAG_HITMAN 		 = "Les crocs ajustés",
+	DAS_CRAG_DUNGEON 		 = "Libéré",
+
+
+
+    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
+    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
+
+    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
+    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
+    DAS_QUEST_CC_NOVICE     = "Novice Holli",
+    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
+    DAS_QUEST_CC_DARO       = "Adjunct Daro",
+    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
+
+    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
+    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
+
+    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
+
+    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
+
+    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
+
+
+}
+DAS_STRINGS_LOCALE.fr = strings
+
+for stringId, stringValue in pairs(strings) do
+	ZO_CreateStringId(stringId, stringValue)
+	SafeAddVersion(stringId, 2)
+end
\ No newline at end of file
diff --git a/locale/jp.lua b/locale/jp.lua
new file mode 100644
index 0000000..28f7d9d
--- /dev/null
+++ b/locale/jp.lua
@@ -0,0 +1,174 @@
+DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
+
+local strings  = {
+	-- UI stuffs
+	DAS_SI_INVITE_TRUE 		= "Invite is now on",
+	DAS_SI_INVITE_FALSE 	= "Invite is now off",
+	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
+	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
+	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
+	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
+	DAS_SI_SPAM 			= "Click to spam in zone chat",
+	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
+
+	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
+	DAS_SI_TOGGLE	 		= "Toggle hidden",
+	DAS_SI_MINIMISE	 		= "Toggle minimised",
+	DAS_SI_REFRESH	 		= "Refresh",
+
+	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
+
+	DAS_SI_SHARE	 		= "Share",
+	DAS_SI_TRACK	 		= "* Track",
+	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
+	DAS_SI_SPAM_SINGLE	 	= "Spam",
+	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
+	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
+
+	-- Clockwork City
+	DAS_CLOCK_IMP			 = "Inciting the Imperfect",
+	DAS_CLOCK_FOE			 = "A Fine-Feathered Foe",
+
+	DAS_CLOCK_CRAFT_CLOTH	 = "Loose Strands",
+	DAS_CLOCK_CRAFT_WATER	 = "A Sticky Solution",
+	DAS_CLOCK_CRAFT_RUNE	 = "Enchanted Accumulation",
+	DAS_CLOCK_CRAFT_SMITH	 = "A Daily Grind",
+	DAS_CLOCK_CRAFT_ALCH	 = "A Bitter Pill",
+	DAS_CLOCK_CRAFT_WOOD	 = "Fuel for our Fires",
+
+	DAS_CLOCK_DELVE_FILT	 = "Changing the Filters",
+	DAS_CLOCK_DELVE_FANS	 = "Oiling the Fans",
+	DAS_CLOCK_DELVE_COMM	 = "Replacing the Commutators",
+	DAS_CLOCK_DELVE_MALF	 = "A Shadow Malfunction",
+	DAS_CLOCK_DELVE_MISP	 = "A Shadow Misplaced",
+	DAS_CLOCK_DELVE_AGAI	 = "Again Into the Shadows",
+
+	DAS_CLOCK_CROW_GLIT		 = "Glitter and Gleam",
+	DAS_CLOCK_CROW_TRIB		 = "A Matter of Tributes",
+	DAS_CLOCK_CROW_NIBB		 = "Nibbles and Bits",
+	DAS_CLOCK_CROW_MORS		 = "Morsels and Pecks",
+	DAS_CLOCK_CROW_RESP		 = "A Matter of Respect",
+	DAS_CLOCK_CROW_LEIS		 = "A Matter of Leisure",
+
+
+	-- Morrowind dailies
+	DAS_M_REL_ASHAL =  "Relics of Ashalmawia",
+	DAS_M_REL_ASSAR =  "Relics of Assarnatamat",
+	DAS_M_REL_ASHUR =  "Relics of Ashurnabitashpi",
+	DAS_M_REL_DUSHA =  "Relics of Dushariran",
+	DAS_M_REL_EBERN =  "Relics of Ebernanit",
+	DAS_M_REL_MAELK =  "Relics of Maelkashishi",
+	DAS_M_REL_YASAM =  "Relics of Yasammidan",
+
+	DAS_M_HUNT_EATER =  "Ash-Eater Hunt",
+	DAS_M_HUNT_ZEXXI =  "Great Zexxin Hunt",
+	DAS_M_HUNT_RAZOR =  "King Razor-Tusk Hunt",
+	DAS_M_HUNT_JAGGE =  "Mother Jagged-Claw Hunt",
+	DAS_M_HUNT_STOMP =  "Old Stomper Hunt",
+	DAS_M_HUNT_TARRA =  "Tarra-Suj Hunt",
+	DAS_M_HUNT_SVEET =  "Writhing Sveeth Hunt",
+
+	-- Cave dailies (Hall of Justice)
+	DAS_M_DELVE_DAEDR =  "Daedric Disruptions",
+	DAS_M_DELVE_KWAMA =  "Kwama Conundrum",
+	DAS_M_DELVE_MISIN =  "Planting Misinformation",
+	DAS_M_DELVE_TAXES =  "Tax Deduction",
+	DAS_M_DELVE_TRIBA =  "Tribal Troubles",
+	DAS_M_DELVE_SYNDI =  "Unsettled Syndicate",
+
+	-- World boss dailies (Hall of Justice)
+	DAS_M_BOSS_WUYWU =  "A Creeping Hunger",
+	DAS_M_BOSS_SWARM =  "Culling the Swarm",
+	DAS_M_BOSS_NILTH =  "Oxen Free",
+	DAS_M_BOSS_SALOT =  "Salothan's Curse",
+	DAS_M_BOSS_SIREN =  "Siren's Song",
+	DAS_M_BOSS_APPRE =  "The Anxious Apprentice",
+
+	-- wrothgar dailies
+    DAS_W_POACHERS        = "Meat for the Masses",
+    DAS_W_EDU             = "Reeking of Foul Play",
+    DAS_W_NYZ             = "Snow and Steam",
+    DAS_W_CORI            = "Nature's Bounty",
+    DAS_W_DOLMEN          = "Heresy of Ignorance",
+    DAS_W_OGRE            = "Scholarly Salvage",
+
+    DAS_W_BOSS_START        = "I'm here to work. What do you have for me?",
+    DAS_W_DELVE_START       = "What do you have for me?",
+
+	-- wrothgar single
+	DAS_W_HARPIES 		 = "Breakfast of the Bizarre",
+	DAS_W_SPIRITS 		 = "Free Spirits",
+	DAS_W_DURZOGS 		 = "Getting a Bellyful",
+	DAS_W_DWEMER 		 = "Parts of the Whole",
+	DAS_W_WEREWOLVES	 = "The Skin Trade",
+	DAS_W_THAT_OTHER	 = "Fire in the Hold",
+
+
+	-- gold coast
+	DAS_DB_MINO			 = "Looming Shadows",
+	DAS_DB_ARENA 		 = "The Roar of the Crowd",
+	DAS_DB_GOOD 		 = "Common Good",
+	DAS_DB_EVIL 		 = "Buried Evil",
+
+
+	-- new life
+	DAS_NL_STORMHAVEN	 = "Castle Charm Challenge",
+	DAS_NL_STONEFALLS	 = "Lava Foot Stomp",
+	DAS_NL_ALIKR		 = "Signal Fire Sprint",
+	DAS_NL_SHADOWFEN	 = "Fish Boon Feast",
+	DAS_NL_GRAHTWOOD	 = "War Orphan's Sojourn",
+	DAS_NL_REAPERSMARCH	 = "The Trial of Five-Clawed Guile",
+	DAS_NL_BETNIKH		 = "Stonetooth Bash",
+	DAS_NL_AURIDON		 = "Mud Ball Merriment",
+	DAS_NL_EASTMARCH	 = "Snow Bear Plunge",
+
+
+	-- craglorn
+	-- lower
+	DAS_CRAG_SARA 		 = "Critical Mass",
+	DAS_CRAG_SHADA 		 = "The Fallen City of Shada",
+	DAS_CRAG_NEDE 		 = "The Reason We Fight",
+	DAS_CRAG_HERMY 		 = "The Seeker’s Archive",
+	DAS_CRAG_ELINHIR 	 = "Supreme Power",
+	DAS_CRAG_TUWHACCA 	 = "The Trials of Rahni’Za",
+	DAS_CRAG_NEREID 	 = "Waters Run Foul",
+
+	-- upper
+	DAS_CRAG_NIRNCRUX	 = "The Blood of Nirn",
+	DAS_CRAG_WORLDTRIP 	 = "The Gray Passage",
+	DAS_CRAG_SCALES 	 = "Iron and Scales",
+	DAS_CRAG_NECRO 		 = "Souls of the Betrayed",
+	DAS_CRAG_KIDNAP 	 = "Taken Alive",
+	DAS_CRAG_HITMAN 	 = "The Truer Fangs",
+	DAS_CRAG_DUNGEON 	 = "Uncaged",
+
+
+
+    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
+    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
+
+    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
+    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
+    DAS_QUEST_CC_NOVICE     = "Novice Holli",
+    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
+    DAS_QUEST_CC_DARO       = "Adjunct Daro",
+    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
+
+    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
+    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
+
+    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
+
+    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
+
+    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
+
+
+
+}
+DAS_STRINGS_LOCALE.jp = strings
+
+for stringId, stringValue in pairs(strings) do
+	ZO_CreateStringId(stringId, stringValue)
+	SafeAddVersion(stringId, 1)
+end
diff --git a/locale/ru.lua b/locale/ru.lua
new file mode 100644
index 0000000..d58356d
--- /dev/null
+++ b/locale/ru.lua
@@ -0,0 +1,218 @@
+DAS_STRINGS_LOCALE = DAS_STRINGS_LOCALE or {}
+
+local strings  = {
+
+	DAS_SI_INVITE_TRUE 		= "Invite is now on",
+	DAS_SI_INVITE_FALSE 	= "Invite is now off",
+	DAS_SI_ACCEPT_TRUE 		= "Automatically accepting quest shares for dailies",
+	DAS_SI_ACCEPT_FALSE 	= "Not automatically accepting dailies",
+	DAS_SI_SHARE_TRUE 		= "Automatically sharing your active daily on group member join or 'share' in group chat (Right-click to share your active quest)",
+	DAS_SI_SHARE_FALSE 		= "Not automatically sharing your active daily, most likely someone yelled at you (Right-click to share anyway)",
+	DAS_SI_SPAM 			= "Click to spam in zone chat",
+	DAS_SI_SPAM_VERBOSE 	= "Click to ask for quest shares",
+
+	DAS_SI_HIDE		 		= "Hide DailyAutoShare",
+	DAS_SI_TOGGLE	 		= "Toggle hidden",
+	DAS_SI_MINIMISE	 		= "Toggle minimised",
+	DAS_SI_REFRESH	 		= "Refresh",
+
+	DAS_SI_DONATE	 		= "Click to say thank you:\nLeft: 2k\nRight: 10k\nMiddle: 25k\nYour feedback and/or donation is appreciated!",
+
+	DAS_SI_SHARE	 		= "Share",
+	DAS_SI_TRACK	 		= "* Track",
+	DAS_SI_ABANDON	 		= "|cFF0000Abandon|r",
+	DAS_SI_SPAM_SINGLE	 	= "Spam",
+	DAS_SI_SETOPEN_TRUE	 	= "Toggle open",
+	DAS_SI_SETOPEN_FALSE	= "Toggle complete",
+
+	-- Clockwork City
+	DAS_CLOCK_IMP			 = "Пробуждение Несовершенства",
+	DAS_CLOCK_FOE			 = "Враг в прекрасном оперении",
+
+	DAS_CLOCK_CRAFT_CLOTH	 = "Свободные нити",
+	DAS_CLOCK_CRAFT_WATER	 = "Липкое решение",
+	DAS_CLOCK_CRAFT_RUNE	 = "Сбор зачарований",
+	DAS_CLOCK_CRAFT_SMITH	 = "Ежедневная молотилка",
+	DAS_CLOCK_CRAFT_ALCH	 = "Горькая пилюля",
+	DAS_CLOCK_CRAFT_WOOD	 = "Масло в огонь",
+
+	DAS_CLOCK_DELVE_FILT	 = "Замена фильтров",
+	DAS_CLOCK_DELVE_FANS	 = "Смазывание вентиляторов",
+	DAS_CLOCK_DELVE_COMM	 = "Замена преобразователей",
+	DAS_CLOCK_DELVE_MALF	 = "Сумрачная неисправность",
+	DAS_CLOCK_DELVE_MISP	 = "Пропавшая тень",
+	DAS_CLOCK_DELVE_AGAI	 = "Обратно в тень",
+
+	DAS_CLOCK_CROW_GLIT		 = "Шик и блеск",
+	DAS_CLOCK_CROW_TRIB		 = "Вопрос о подношениях",
+	DAS_CLOCK_CROW_NIBB		 = "Кусочки и частички",
+	DAS_CLOCK_CROW_MORS		 = "Лакомые кусочки",
+	DAS_CLOCK_CROW_RESP		 = "Вопрос уважения",
+	DAS_CLOCK_CROW_LEIS		 = "Вопрос о свободном времени",
+
+
+	-- Morrowind dailies
+	DAS_M_REL_ASHAL =  "Реликвии Ашалмавии",
+	DAS_M_REL_ASSAR =  "Реликвии Ассарнатамата",
+	DAS_M_REL_ASHUR =  "Реликвии Ассурнабиташпи",
+	DAS_M_REL_DUSHA =  "Реликвии Душарирана",
+	DAS_M_REL_EBERN =  "Реликвии Эбернанита",
+	DAS_M_REL_MAELK =  "Реликвии Мелкашиши",
+	DAS_M_REL_YASAM =  "Реликвии Ясаммидана",
+
+	DAS_M_HUNT_EATER =  "Охота на Пеплоеда",
+	DAS_M_HUNT_ZEXXI =  "Охота на Великого Зексина",
+	DAS_M_HUNT_RAZOR =  "Охота на Короля Острый Клык",
+	DAS_M_HUNT_JAGGE =  "Охота на Мать Зазубренная Клешня",
+	DAS_M_HUNT_STOMP =  "Охота на Старого Топотуна",
+	DAS_M_HUNT_TARRA =  "Охота на Тарра-Судж",
+	DAS_M_HUNT_SVEET =  "Охота на Извивающегося Свита",
+
+	-- Cave dailies (Hall of Justice)
+	DAS_M_DELVE_DAEDR =  "Даэдрический срыв",
+	DAS_M_DELVE_KWAMA =  "Задачка с квама",
+	DAS_M_DELVE_MISIN =  "Насаждение дезинформации",
+	DAS_M_DELVE_TAXES =  "Налоговый вычет",
+	DAS_M_DELVE_TRIBA =  "Проблемы племени",
+	DAS_M_DELVE_SYNDI =  "Беспокойный синдикат",
+
+
+	-- World boss dailies (Hall of Justice)
+	DAS_M_BOSS_WUYWU =  "Затаившийся алчущий",
+	DAS_M_BOSS_SWARM =  "Отбраковка колонии",
+	DAS_M_BOSS_NILTH =  "Волам здесь не место",
+	DAS_M_BOSS_SALOT =  "Проклятье Салотанов",
+	DAS_M_BOSS_SIREN =  "Песня сирены",
+	DAS_M_BOSS_APPRE =  "Обеспокоенная ученица",
+
+
+	-- wrothgar dailies
+    DAS_W_POACHERS        = "Мясо в массы",
+    DAS_W_EDU             = "Запах нечестной игры",
+    DAS_W_NYZ             = "Снег и пар",
+    DAS_W_CORI            = "Щедрость природы",
+    DAS_W_DOLMEN          = "Ересь невежества",
+    DAS_W_OGRE            = "Спасение во имя знаний",
+
+	-- wrothgar single
+	DAS_W_HARPIES 		 = "Завтрак чудака",
+	DAS_W_SPIRITS 		 = "Свободные духи",
+	DAS_W_DURZOGS 		 = "До отвала",
+	DAS_W_DWEMER 		 = "Части целого",
+	DAS_W_WEREWOLVES	 = "Торговля кожей",
+	DAS_W_THAT_OTHER	 = "Пожар во владении",
+
+
+
+	-- gold coast
+	DAS_DB_MINO			 = "Надвигающиеся тени",
+	DAS_DB_ARENA 		 = "Рев толпы",
+	DAS_DB_GOOD 		 = "Всеобщее благо",
+	DAS_DB_EVIL 		 = "Захороненное зло",
+
+	-- new life
+	DAS_NL_STORMHAVEN	 = "Замковое состязание очарования",
+	DAS_NL_STONEFALLS	 = "Пляска лавовых ног",
+	DAS_NL_ALIKR		 = "Забег сигнальных огней",
+	DAS_NL_SHADOWFEN	 = "Пир рыбьего блага",
+	DAS_NL_GRAHTWOOD	 = "Пребывание сирот войны",
+	DAS_NL_REAPERSMARCH	 = "Испытание пятипалого коварства",
+	DAS_NL_BETNIKH		 = "Удар Каменного зуба",
+	DAS_NL_AURIDON		 = "Развлечение с комками грязи",
+	DAS_NL_EASTMARCH	 = "Ныряние снежного медведя",
+
+	-- craglorn
+	-- lower
+	DAS_CRAG_SARA 		 = "Критическая масса",
+	DAS_CRAG_SHADA 		 = "Павший город Шады",
+	DAS_CRAG_NEDE 		 = "Причина, по которой мы сражаемся",
+	DAS_CRAG_HERMY 		 = "Архив искателя",
+	DAS_CRAG_ELINHIR 	 = "Высшая сила",
+	DAS_CRAG_TUWHACCA 	 = "Испытания Рахни'За",
+	DAS_CRAG_NEREID 	 = "Испорченная вода",
+
+	-- upper
+	DAS_CRAG_NIRNCRUX	 = "Кровь Нирна",
+	DAS_CRAG_WORLDTRIP 	 = "Серый проход",
+	DAS_CRAG_SCALES 	 = "Железо и чешуя",
+	DAS_CRAG_NECRO 		 = "Души преданных",
+	DAS_CRAG_KIDNAP 	 = "Живые пленники",
+	DAS_CRAG_HITMAN 	 = "Настоящие клыки",
+	DAS_CRAG_DUNGEON 	 = "Освобожденные",
+
+
+
+    -- Questgiver names --
+
+
+
+    DAS_QUEST_M_ASHLANDER   = "Huntmaster Sorim-Nakar",
+    DAS_QUEST_M_RIVYN       = "Battlemaster Rivyn",
+
+    DAS_QUEST_CC_ROBOT      = "Clockwork Facilitator",
+    DAS_QUEST_CC_CROW       = "Bursar of Tributes",
+    DAS_QUEST_CC_NOVICE     = "Novice Holli",
+    DAS_QUEST_CC_THISTLE    = "Leaps-Over-Thistle",
+    DAS_QUEST_CC_DARO       = "Adjunct Daro",
+    DAS_QUEST_CC_TILELLE    = "Intiate Tilelle",
+
+    DAS_QUEST_W_OUFA        = "Sergeant Oufa",
+    DAS_QUEST_W_USHANG      = "Ushang the Untamed",
+
+    DAS_QUEST_W_BIRKHU      = "Birkhu the Bold",
+
+    DAS_QUEST_DB_ARVINA     = "Cleric Arvina",
+
+    DAS_QUEST_DB_BOUNTY     = "Bounty Board",
+
+
+    -- don't need translation for anyone but the russians - I think
+
+    DAS_QUEST_DB_LARONEN    = "Laronen",
+    DAS_QUEST_DB_FINIA      = "Finia Sele",
+    DAS_QUEST_DB_CODUS      = "Codus ap Dugal",
+
+    DAS_QUEST_W_NEDNOR      = "Nednor",
+    DAS_QUEST_W_THAZEK      = "Thazeg",
+    DAS_QUEST_W_ARUSHNA     = "Arushna",
+    DAS_QUEST_W_LILYAMEH    = "Lilyameh",
+    DAS_QUEST_W_BAGRUBESH   = "Bagrugbesh",
+    DAS_QUEST_W_CIRANTILLE  = "Cirantille",
+    DAS_QUEST_W_MENNINIA    = "Menninia",
+    DAS_QUEST_W_SONOLIA     = "Sonolia Muspidius",
+    DAS_QUEST_W_RAYNOR      = "Raynor Vanos", -- maybe not include Raynor?
+
+    DAS_QUEST_M_TRAYLAN     = "Traylan Omoril",
+    DAS_QUEST_M_BELERU      = "Beleru Omoril",
+    DAS_QUEST_M_NUMANI      = "Numani-Rasi",
+    DAS_QUEST_M_NARA        = "Nara Varam",
+    DAS_QUEST_M_TIRVINA     = "Tirvina Avani",
+    DAS_QUEST_M_DINOR       = "Dinor Salvi",
+    DAS_QUEST_M_BRAVOSI     = "Bravosi Felder",
+    DAS_QUEST_M_IVULEN      = "Ivulen Andromo",
+    DAS_QUEST_M_SAVILE      = "Savile Alam",
+    DAS_QUEST_M_KYLIA       = "Kylia Thando",
+    DAS_QUEST_M_EVOS        = "Evos Hledas",
+    DAS_QUEST_M_ALVES       = "Alves Droth",
+    DAS_QUEST_M_DREDASE     = "Dredase-Hlarar",
+    DAS_QUEST_M_VORAR       = "Vorar Vendu",
+
+    DAS_QUEST_CC_ORC        = "Razgurug",
+    DAS_QUEST_CC_COOK       = "Aveberl Tremouille",
+    DAS_QUEST_CC_MINDORA    = "Mindora",
+    DAS_QUEST_CC_NJORD      = "Njordemar",
+    DAS_QUEST_CC_IGMUND     = "Igmund",
+
+    DAS_QUEST_W_GURUZUG     = "Guruzug",
+    DAS_QUEST_W_ARZORAG     = "Arzorag",
+
+
+
+}
+
+DAS_STRINGS_LOCALE.ru = strings
+
+for stringId, stringValue in pairs(strings) do
+	ZO_CreateStringId(stringId, stringValue)
+	SafeAddVersion(stringId, 2)
+end
\ No newline at end of file
diff --git a/questData/00_ids.lua b/questData/00_ids.lua
new file mode 100644
index 0000000..e5df203
--- /dev/null
+++ b/questData/00_ids.lua
@@ -0,0 +1,119 @@
+DAS_QUEST_IDS  = {
+
+-- Clockwork City
+	[6076]	 = true, -- Inciting the Imperfect,
+	[6077]	 = true, -- A Fine-Feathered Foe,
+
+	[6039]	 = true, -- Loose Strands,
+	[6040]	 = true, -- A Sticky Solution,
+	[6041]	 = true, -- Enchanted Accumulation,
+	[6038]	 = true, -- A Daily Grind,
+	[6042]	 = true, -- A Bitter Pill,
+	[6037]	 = true, -- Fuel for our Fires,
+
+	[6088]	 = true, -- Changing the Filters,
+	[6081]	 = true, -- Oiling the Fans,
+	[6089]	 = true, -- Replacing the Commutators,
+	[6080]	 = true, -- A Shadow Malfunction,
+	[6073]	 = true, -- A Shadow Misplaced,
+	[6079]	 = true, -- Again Into the Shadows,
+
+	[6110]	 = true, -- Glitter and Gleam,
+	[6106]	 = true, -- A Matter of Tributes,
+	[6070]	 = true, -- Nibbles and Bits,
+	[6071]	 = true, -- Morsels and Pecks,
+	[6072]	 = true, -- A Matter of Respect,
+
+
+	-- Morrowind dailies
+	[5924]  = true, -- "Relics of Yasammidan",
+	[5925]  = true, -- "Relics of Assarnatamat",
+	[5926]  = true, -- "Relics of Maelkashishi",
+	[5927]  = true, -- "Relics of Ashurnabitashpi",
+	[5928]  = true, -- "Relics of Ebernanit",
+	[5929]  = true, -- "Relics of Dushariran",
+	[5930]  = true, -- "Relics of Ashalmawia",
+
+	[5907]  = true, -- "Great Zexxin Hunt",
+	[5908]  = true, -- "Tarra-Suj Hunt",
+	[5909]  = true, -- "Writhing Sveeth Hunt",
+	[5910]  = true, -- "Mother Jagged-Claw Hunt",
+	[5911]  = true, -- "Ash-Eater Hunt",
+	[5912]  = true, -- "Old Stomper Hunt",
+	[5913]  = true, -- "King Razor-Tusk Hunt",
+
+	-- Cave dailies (Hall of Justice)
+	[5956]  = true, -- "Daedric Disruptions",
+	[5958]  = true, -- "Unsettled Syndicate",
+	[5961]  = true, -- "Planting Misinformation",
+	[5962]  = true, -- "Kwama Conundrum",
+	[5934]  = true, -- "Tax Deduction",
+	[5915]  = true, -- "Tribal Troubles",
+	[5958]  = true, -- "Unsettled Syndicate",
+
+	-- World boss dailies (Hall of Justice)
+	[5916]  = true, -- "The Anxious Apprentice",
+	[5918]  = true, -- "A Creeping Hunger",
+	[5865]  = true, -- "Culling the Swarm",
+	[5866]  = true, -- "Oxen Free",
+	[5904]  = true, -- "Salothan's Curse",
+	[5906]  = true, -- "Siren's Song",
+
+
+
+	-- wrothgar dailies
+	[5518]  = true, -- "Meat for the Masses",
+	[5519]  = true, -- "Scholarly Salvage",
+	[5520]  = true, -- "Flames of Forge and Fallen",
+	[5521]  = true, -- "Nature's Bounty",
+	[5522]  = true, -- "Heresy of Ignorance",
+	[5523]  = true, -- "Snow and Steam",
+	[5524]  = true, -- "Reeking of Foul Play",
+
+
+	-- wrothgar single
+	[5507]  = true, -- "Breakfast of the Bizarre",
+	[5515]  = true, -- "Free Spirits",
+	[5514]  = true, -- "Getting a Bellyful",
+	[5509]  = true, -- "Parts of the Whole",
+	[5504]  = true, -- "The Skin Trade",
+	[5505]  = true, -- "Fire in the Hold",
+
+
+
+	-- gold coast
+	[5603]  = true, -- "Buried Evil",
+	[5604]  = true, -- "The Common Good",
+	[5605]  = true, -- "Looming Shadows",
+	[5606]  = true, -- "The Roar of the Crowds",
+
+	-- new life
+	[5845]  = true, -- "Castle Charm Challenge",
+	[5837]  = true, -- "Lava Foot Stomp",
+	[5838]  = true, -- "Mud Ball Merriment",
+	[5839]  = true, -- "Signal Fire Sprint",
+	[5855]  = true, -- "Fish Boon Feast",
+	[5852]  = true, -- "War Orphan's Sojourn",
+	[5834]  = true, -- "The Trial of Five-Clawed Guile",
+	[5856]  = true, -- "Stonetooth Bash",
+	[5811]  = true, -- "Snow Bear Plunge",
+
+	-- craglorn
+	-- lower
+	[5108]  = true, -- "Critical Mass",
+	[5749]  = true, -- "The Seeker's Archive",
+	[5750]  = true, -- "The Fallen City of Shada",
+	[5751]  = true, -- "The Trials of Rahni'Za",
+	[5754]  = true, -- "Waters Run Foul",
+	[5755]  = true, -- "Supreme Power",
+	[5762]  = true, -- "The Reason We Fight",
+
+	-- upper
+	[5767]  = true, -- "The Blood of Nirn",
+	[5777]  = true, -- "The Gray Passage",
+	[5766]  = true, -- "Iron and Scales",
+	[5770]  = true, -- "Souls of the Betrayed",
+	[5765]  = true, -- "Taken Alive",
+	[5764]  = true, -- "The Truer Fangs",
+	[5772]  = true, -- "Uncaged",
+}
\ No newline at end of file
diff --git a/questData/ClockworkCity.lua b/questData/ClockworkCity.lua
new file mode 100644
index 0000000..4d86e7d
--- /dev/null
+++ b/questData/ClockworkCity.lua
@@ -0,0 +1,184 @@
+DAS.shareables 	    = DAS.shareables    or {}
+DAS.bingo 		    = DAS.bingo 	    or {}
+
+
+local zoneId	= 980
+local zoneId2	= 981
+local zoneId3	= 983
+
+local halls_of_regulation_id = 985
+local shadow_cleft_id 		 = 986
+local planisphere_id 		 = 993
+local wellspring_id 		 = 992
+
+local bingo
+
+-- =============================================================================================== --
+-- Clockwork City
+-- =============================================================================================== --
+
+local tbl = {}
+
+table.insert(tbl, GetString(DAS_CLOCK_IMP))
+table.insert(tbl, GetString(DAS_CLOCK_FOE))
+
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_CLOTH))
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_WATER))
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_RUNE))
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_SMITH))
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_ALCH))
+table.insert(tbl, GetString(DAS_CLOCK_CRAFT_WOOD))
+
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_FILT))
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_FANS))
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_COMM))
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_MALF))
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_MISP))
+table.insert(tbl, GetString(DAS_CLOCK_DELVE_AGAI))
+
+table.insert(tbl, GetString(DAS_CLOCK_CROW_GLIT))
+table.insert(tbl, GetString(DAS_CLOCK_CROW_TRIB))
+table.insert(tbl, GetString(DAS_CLOCK_CROW_NIBB))
+table.insert(tbl, GetString(DAS_CLOCK_CROW_MORS))
+table.insert(tbl, GetString(DAS_CLOCK_CROW_RESP))
+table.insert(tbl, GetString(DAS_CLOCK_CROW_LEIS))
+
+DAS.shareables[zoneId] = tbl
+
+
+-- Halls of Regulation
+local tbl2 = {}
+table.insert(tbl2, GetString(DAS_CLOCK_DELVE_FILT))
+table.insert(tbl2, GetString(DAS_CLOCK_DELVE_FANS))
+table.insert(tbl2, GetString(DAS_CLOCK_CRAFT_WOOD))
+table.insert(tbl2, GetString(DAS_CLOCK_DELVE_COMM))
+DAS.shareables[halls_of_regulation_id] = tbl2
+
+-- Shadow Cleft
+local tbl3 = {}
+table.insert(tbl3, GetString(DAS_CLOCK_DELVE_MALF))
+table.insert(tbl3, GetString(DAS_CLOCK_DELVE_MISP))
+table.insert(tbl3, GetString(DAS_CLOCK_CRAFT_RUNE))
+table.insert(tbl3, GetString(DAS_CLOCK_DELVE_AGAI))
+
+DAS.shareables[shadow_cleft_id] = tbl3
+
+-- Planisphere
+local tbl4 = {}
+table.insert(tbl4, GetString(DAS_CLOCK_CRAFT_CLOTH))
+DAS.shareables[planisphere_id] = tbl4
+
+-- Everwound Wellspring
+local tbl5 = {}
+table.insert(tbl5, GetString(DAS_CLOCK_CRAFT_ALCH))
+DAS.shareables[wellspring_id] = tbl5
+
+DAS.QuestLists[zoneId] = {
+	["boss"] = {
+		[GetString(DAS_CLOCK_IMP)] = true,
+		[GetString(DAS_CLOCK_FOE)] = true,
+	},
+	["craft"] = {
+		[GetString(DAS_CLOCK_CRAFT_CLOTH)] = true,
+		[GetString(DAS_CLOCK_CRAFT_WATER)] = true,
+		[GetString(DAS_CLOCK_CRAFT_RUNE)] = true,
+		[GetString(DAS_CLOCK_CRAFT_SMITH)] = true,
+		[GetString(DAS_CLOCK_CRAFT_ALCH)] = true,
+		[GetString(DAS_CLOCK_CRAFT_WOOD)] = true,
+	},
+	["crow"] = {
+		[GetString(DAS_CLOCK_CROW_GLIT)] = true,
+		[GetString(DAS_CLOCK_CROW_TRIB)] = true,
+		[GetString(DAS_CLOCK_CROW_NIBB)] = true,
+		[GetString(DAS_CLOCK_CROW_MORS)] = true,
+		[GetString(DAS_CLOCK_CROW_RESP)] = true,
+		[GetString(DAS_CLOCK_CROW_LEIS)] = true,
+	},
+	["delve"] = {
+		[GetString(DAS_CLOCK_DELVE_FILT)] = true,
+		[GetString(DAS_CLOCK_DELVE_FANS)] = true,
+		[GetString(DAS_CLOCK_DELVE_COMM)] = true,
+		[GetString(DAS_CLOCK_DELVE_MALF)] = true,
+		[GetString(DAS_CLOCK_DELVE_MISP)] = true,
+		[GetString(DAS_CLOCK_DELVE_AGAI)] = true,
+	},
+}
+
+bingo = {}
+
+table.insert(bingo, "imp")
+table.insert(bingo, "foe")
+
+table.insert(bingo, "strands")
+table.insert(bingo, "sticky")
+table.insert(bingo, "acc")
+table.insert(bingo, "grind")
+table.insert(bingo, "pill")
+table.insert(bingo, "fuel")
+
+table.insert(bingo, "filter")
+table.insert(bingo, "fan")
+table.insert(bingo, "comm")
+table.insert(bingo, "misplaced")
+table.insert(bingo, "malfunc")
+
+table.insert(bingo, "gleam")
+table.insert(bingo, "tribute")
+table.insert(bingo, "bits")
+table.insert(bingo, "respect")
+table.insert(bingo, "leisure")
+
+DAS.makeBingoTable(zoneId, bingo)
+
+bingo = {}
+table.insert(bingo, "filter")
+table.insert(bingo, "fan")
+
+DAS.makeBingoTable(halls_of_regulation_id, bingo)
+
+
+bingo = {}
+table.insert(bingo, "shadow")
+table.insert(bingo, "comm")
+DAS.makeBingoTable(shadow_cleft_id, bingo)
+
+bingo = {}
+table.insert(bingo, "pill")
+DAS.makeBingoTable(wellspring_id, bingo)
+
+
+
+DAS.shareables[zoneId2] = DAS.shareables[zoneId]
+DAS.shareables[zoneId3] = DAS.shareables[zoneId]
+DAS.bingo[zoneId2] = DAS.bingo[zoneId]
+DAS.bingo[zoneId3] = DAS.bingo[zoneId]
+
+DAS.QuestLists[zoneId2] = DAS.QuestLists[zoneId]
+DAS.QuestLists[zoneId3] = DAS.QuestLists[zoneId]
+
+DAS.questStarter[zoneId] = {
+    [GetString(DAS_QUEST_CC_ROBOT)] = true,
+    [GetString(DAS_QUEST_CC_NOVICE)] = true,
+    [GetString(DAS_QUEST_CC_ORC)] = true,
+    [GetString(DAS_QUEST_CC_CROW)] = true,
+}
+
+DAS.questStarter[zoneId2] = DAS.questStarter[zoneId]
+DAS.questStarter[zoneId3] = DAS.questStarter[zoneId]
+
+DAS.questFinisher[zoneId] = {
+    [GetString(DAS_QUEST_CC_ROBOT)] = true,
+    [GetString(DAS_QUEST_CC_CROW)] = true,
+
+    [GetString(DAS_QUEST_CC_THISTLE )] = true,
+    [GetString(DAS_QUEST_CC_COOK    )] = true,
+    [GetString(DAS_QUEST_CC_MINDORA  )] = true,
+    [GetString(DAS_QUEST_CC_NJORD   )] = true,
+    [GetString(DAS_QUEST_CC_IGMUND   )] = true,
+    [GetString(DAS_QUEST_CC_DARO   )] = true,
+    [GetString(DAS_QUEST_CC_TILELLE  )] = true,
+
+
+}
+DAS.questFinisher[zoneId2] = DAS.questFinisher[zoneId]
+DAS.questFinisher[zoneId3] = DAS.questFinisher[zoneId]
\ No newline at end of file
diff --git a/questData/Cyrodiil.lua b/questData/Cyrodiil.lua
new file mode 100644
index 0000000..15465dd
--- /dev/null
+++ b/questData/Cyrodiil.lua
@@ -0,0 +1,8 @@
+local zoneId	= 181
+
+DAS.shareables[zoneId] = {
+}
+
+local tbl2 = {}
+
+DAS.makeBingoTable(zoneId, tbl2)
\ No newline at end of file
diff --git a/questData/Festival.lua b/questData/Festival.lua
new file mode 100644
index 0000000..5d7c5b2
--- /dev/null
+++ b/questData/Festival.lua
@@ -0,0 +1,52 @@
+local zoneId	= 101
+
+local tbl = {}
+
+local NL = "newLife"
+
+table.insert(tbl, GetString(DAS_NL_STORMHAVEN))
+table.insert(tbl, GetString(DAS_NL_STONEFALLS))
+table.insert(tbl, GetString(DAS_NL_ALIKR))
+table.insert(tbl, GetString(DAS_NL_SHADOWFEN))
+table.insert(tbl, GetString(DAS_NL_GRAHTWOOD))
+table.insert(tbl, GetString(DAS_NL_REAPERSMARCH))
+table.insert(tbl, GetString(DAS_NL_BETNIKH))
+table.insert(tbl, GetString(DAS_NL_AURIDON))
+table.insert(tbl, GetString(DAS_NL_EASTMARCH))
+
+local function makeNestedZoneTable(id, quest)
+	DAS.shareables[id] 				= DAS.shareables[id] 	or {}
+	DAS.bingo[id]			 		= DAS.bingo[id] 		or {}
+	DAS.shareables[id][NL] 	= {}
+	table.insert(DAS.shareables[id][NL], quest)
+	table.insert(DAS.bingo[id], NL)
+end
+
+DAS.shareables[zoneId] = DAS.shareables[zoneId] or {}
+DAS.shareables[zoneId][NL] = tbl
+
+DAS.QuestLists = DAS.QuestLists or {}
+DAS.QuestLists[zoneId] = {
+	[NL] = {
+		[GetString(DAS_NL_STORMHAVEN)] = true,
+		[GetString(DAS_NL_STONEFALLS)] = true,
+		[GetString(DAS_NL_ALIKR)] = true,
+		[GetString(DAS_NL_SHADOWFEN)] = true,
+		[GetString(DAS_NL_GRAHTWOOD)] = true,
+		[GetString(DAS_NL_REAPERSMARCH)] = true,
+		[GetString(DAS_NL_BETNIKH)] = true,
+		[GetString(DAS_NL_AURIDON)] = true,
+		[GetString(DAS_NL_EASTMARCH)] = true,
+	},
+}
+
+
+
+makeNestedZoneTable(19 ,	GetString(DAS_NL_STORMHAVEN))   -- Stormhaven
+makeNestedZoneTable(41 ,	GetString(DAS_NL_STONEFALLS))   -- Stonefalls
+makeNestedZoneTable(117,	GetString(DAS_NL_SHADOWFEN))   -- Shadowfen
+makeNestedZoneTable(104,	GetString(DAS_NL_ALIKR))   -- Alik'r
+makeNestedZoneTable(383,	GetString(DAS_NL_GRAHTWOOD))   -- Grahtwood
+makeNestedZoneTable(382,	GetString(DAS_NL_REAPERSMARCH))   -- Reaper's March
+makeNestedZoneTable(535,	GetString(DAS_NL_BETNIKH))   -- Betnikh
+makeNestedZoneTable(381,	GetString(DAS_NL_AURIDON))   -- Auridon
diff --git a/questData/GoldCoast.lua b/questData/GoldCoast.lua
new file mode 100644
index 0000000..d3f5091
--- /dev/null
+++ b/questData/GoldCoast.lua
@@ -0,0 +1,37 @@
+DAS.shareables 	    = DAS.shareables    or {}
+DAS.bingo 		    = DAS.bingo 	    or {}
+
+
+local zoneId	= 823
+
+
+local tbl = {}
+
+table.insert(tbl, GetString(DAS_DB_MINO))
+table.insert(tbl, GetString(DAS_DB_ARENA))
+table.insert(tbl, GetString(DAS_DB_GOOD))
+table.insert(tbl, GetString(DAS_DB_EVIL))
+
+DAS.shareables[zoneId] = tbl
+DAS.shareables[825] = DAS.shareables[zoneId]
+
+local tbl2 = {}
+table.insert(tbl2, {[1] = "mino", [2] = "m"})
+table.insert(tbl2, {[1] = "arena",[2] = "a"})
+table.insert(tbl2, {[1] = "good", [2] = "common", [3] = "cg"})
+table.insert(tbl2, {[1] = "evil", [2] = "buried", [3] = "be"})
+
+DAS.makeBingoTable(zoneId, tbl2)
+DAS.bingo[825] = DAS.bingo[zoneId]
+
+
+DAS.questStarter[zoneId] = {
+    [GetString(DAS_QUEST_DB_BOUNTY)]    = true,
+}
+
+DAS.questFinisher[zoneId] = {
+    [GetString(DAS_QUEST_DB_ARVINA)]    = true,
+    [GetString(DAS_QUEST_DB_LARONEN)]   = true,
+    [GetString(DAS_QUEST_DB_FINIA)]     = true,
+    [GetString(DAS_QUEST_DB_CODUS)]     = true,
+}
diff --git a/questData/GuildQuests.lua b/questData/GuildQuests.lua
new file mode 100644
index 0000000..21143f0
--- /dev/null
+++ b/questData/GuildQuests.lua
@@ -0,0 +1,37 @@
+DAS.shareables 	        = DAS.shareables    or {}
+DAS.bingo 		        = DAS.bingo 	    or {}
+DAS.questFinisher       = DAS.questFinisher    or {}
+DAS.questStarter        = DAS.questStarter     or {}
+
+local zoneId    = 57    -- Deshaan
+local zoneId2   = 19    -- Stormhaven
+local zoneId3   = 383   -- Grahtwood
+
+DAS.shareables[zoneId] = {
+
+}
+DAS.shareables[zoneId2] = DAS.shareables[zoneId]
+DAS.shareables[zoneId3] = DAS.shareables[zoneId]
+
+DAS.bingo[zoneId]       = {
+
+}
+DAS.bingo[zoneId2]      = DAS.bingo[zoneId]
+DAS.bingo[zoneId3]      = DAS.bingo[zoneId]
+
+
+DAS.questStarter[zoneId] = {
+    [GetString(DAS_QUEST_CAP_CARDEA)]     = true,   -- Cardea Gallus,   FG
+    [GetString(DAS_QUEST_CAP_ALVUR)]      = true,   -- Alvur Baren,     MG
+    [GetString(DAS_QUEST_CAP_BOLGRUL)]    = true,   -- Bolgrul,         UD
+}
+DAS.questStarter[zoneId2] = DAS.questStarter[zoneId]
+DAS.questStarter[zoneId3] = DAS.questStarter[zoneId]
+
+DAS.questFinisher[zoneId] = {
+    [GetString(DAS_QUEST_CAP_CARDEA)]     = true,   -- Cardea Gallus,   FG
+    [GetString(DAS_QUEST_CAP_ALVUR)]      = true,   -- Alvur Baren,     MG
+    [GetString(DAS_QUEST_CAP_BOLGRUL)]    = true,   -- Bolgrul,         UD
+}
+DAS.questFinisher[zoneId2] = DAS.questFinisher[zoneId]
+DAS.questFinisher[zoneId3] = DAS.questFinisher[zoneId]
\ No newline at end of file
diff --git a/questData/HewsBane.lua b/questData/HewsBane.lua
new file mode 100644
index 0000000..5360256
--- /dev/null
+++ b/questData/HewsBane.lua
@@ -0,0 +1,14 @@
+DAS.shareables 	    = DAS.shareables    or {}
+DAS.bingo 		    = DAS.bingo 	    or {}
+
+
+local zoneId	= 816
+local zoneId2	= 821
+
+DAS.shareables[zoneId] = {
+
+}
+
+local tbl2 = {}
+
+DAS.makeBingoTable(zoneId, tbl2)
\ No newline at end of file
diff --git a/questData/Morrowind.lua b/questData/Morrowind.lua
new file mode 100644
index 0000000..0fd4b47
--- /dev/null
+++ b/questData/Morrowind.lua
@@ -0,0 +1,166 @@
+DAS.shareables 	        = DAS.shareables    or {}
+DAS.bingo 		        = DAS.bingo 	    or {}
+DAS.questFinisher  = DAS.questFinisher    or {}
+DAS.questStarter   = DAS.questStarter     or {}
+
+
+local zoneId	= 849
+
+local tbl = {}
+local tbl2 = {}
+
+table.insert(tbl, GetString(DAS_M_REL_ASHAL))
+table.insert(tbl2, "ashal")
+table.insert(tbl, GetString(DAS_M_REL_ASSAR))
+table.insert(tbl2, "assar")
+table.insert(tbl, GetString(DAS_M_REL_ASHUR))
+table.insert(tbl2, "ashur")
+table.insert(tbl, GetString(DAS_M_REL_DUSHA))
+table.insert(tbl2, "dushar")
+table.insert(tbl, GetString(DAS_M_REL_EBERN))
+table.insert(tbl2, "eber")
+table.insert(tbl, GetString(DAS_M_REL_MAELK))
+table.insert(tbl2, "maelk")
+table.insert(tbl, GetString(DAS_M_REL_YASAM))
+table.insert(tbl2, "yasam")
+
+table.insert(tbl, GetString(DAS_M_HUNT_EATER))
+table.insert(tbl2, "ash")
+table.insert(tbl, GetString(DAS_M_HUNT_ZEXXI))
+table.insert(tbl2, "zexxin")
+table.insert(tbl, GetString(DAS_M_HUNT_RAZOR))
+table.insert(tbl2, "razor")
+table.insert(tbl, GetString(DAS_M_HUNT_JAGGE))
+table.insert(tbl2, "claw")
+table.insert(tbl, GetString(DAS_M_HUNT_STOMP))
+table.insert(tbl2, "stomper")
+table.insert(tbl, GetString(DAS_M_HUNT_TARRA))
+table.insert(tbl2, "tarra")
+table.insert(tbl, GetString(DAS_M_HUNT_SVEET))
+table.insert(tbl2, "sveeth")
+
+
+table.insert(tbl, GetString(DAS_M_DELVE_DAEDR))
+table.insert(tbl2, "daedra")
+table.insert(tbl, GetString(DAS_M_DELVE_KWAMA))
+table.insert(tbl2, "kwama")
+table.insert(tbl, GetString(DAS_M_DELVE_MISIN))
+table.insert(tbl2, "counterspy")
+table.insert(tbl, GetString(DAS_M_DELVE_TAXES))
+table.insert(tbl2, "taxes")
+table.insert(tbl, GetString(DAS_M_DELVE_TRIBA))
+table.insert(tbl2, "tribe")
+table.insert(tbl, GetString(DAS_M_DELVE_SYNDI))
+table.insert(tbl2, "syndicate")
+
+table.insert(tbl, GetString(DAS_M_BOSS_WUYWU))
+table.insert(tbl2, {[1] = "wuyu", [2] = "wyu", [3] = "wuyuvus", [4] = "wuju", [5] = "sul", [6] = "sulipund"})
+table.insert(tbl, GetString(DAS_M_BOSS_SWARM))
+table.insert(tbl2, {[1] ="queen", [2] = "swarm", [3] = "consort", [4] = "qc"})
+table.insert(tbl, GetString(DAS_M_BOSS_NILTH))
+table.insert(tbl2, {[1] ="nil", [2] = "nilthog", [3] = "oxen"})
+table.insert(tbl, GetString(DAS_M_BOSS_SALOT))
+table.insert(tbl2, {[1] ="salo", [2] = "salothan", [3] = "sal"})
+table.insert(tbl, GetString(DAS_M_BOSS_SIREN))
+table.insert(tbl2, {[1] ="siren", [2] = "song", [3] = "songbird", [4] = "ss", [5] = "sirene"})
+table.insert(tbl, GetString(DAS_M_BOSS_APPRE))
+table.insert(tbl2, {[1] = "dub", [2] = "dubdil" })
+
+DAS.shareables[zoneId]      = tbl
+DAS.QuestLists = DAS.QuestLists or {}
+DAS.QuestLists[zoneId] = {
+	["relic"] = {
+		[GetString(DAS_M_REL_ASHAL)] = true,
+		[GetString(DAS_M_REL_ASSAR)] = true,
+		[GetString(DAS_M_REL_ASHUR)] = true,
+		[GetString(DAS_M_REL_DUSHA)] = true,
+		[GetString(DAS_M_REL_EBERN)] = true,
+		[GetString(DAS_M_REL_MAELK)] = true,
+		[GetString(DAS_M_REL_YASAM)] = true,
+	},
+	["hunt"] = {
+		[GetString(DAS_M_HUNT_EATER)] = true,
+		[GetString(DAS_M_HUNT_ZEXXI)] = true,
+		[GetString(DAS_M_HUNT_RAZOR)] = true,
+		[GetString(DAS_M_HUNT_JAGGE)] = true,
+		[GetString(DAS_M_HUNT_STOMP)] = true,
+		[GetString(DAS_M_HUNT_TARRA)] = true,
+		[GetString(DAS_M_HUNT_SVEET)] = true,
+	},
+	["delve"] = {
+		[GetString(DAS_M_DELVE_DAEDR)] = true,
+		[GetString(DAS_M_DELVE_KWAMA)] = true,
+		[GetString(DAS_M_DELVE_MISIN)] = true,
+		[GetString(DAS_M_DELVE_TAXES)] = true,
+		[GetString(DAS_M_DELVE_TRIBA)] = true,
+		[GetString(DAS_M_DELVE_SYNDI)] = true,
+	},
+	["boss"] = {
+		[GetString(DAS_M_BOSS_WUYWU)] = true,
+		[GetString(DAS_M_BOSS_SWARM)] = true,
+		[GetString(DAS_M_BOSS_NILTH)] = true,
+		[GetString(DAS_M_BOSS_SALOT)] = true,
+		[GetString(DAS_M_BOSS_SIREN)] = true,
+		[GetString(DAS_M_BOSS_APPRE)] = true,
+	},
+}
+
+
+-- Khartag point
+DAS.shareables[921] = {
+	[1] = DAS.shareables[zoneId][20],
+}-- Zainsipilu
+DAS.shareables[922] = {
+	[1] = DAS.shareables[zoneId][17],
+}
+-- Matus-Akin Egg Mine
+DAS.shareables[923] = {
+	[1] = DAS.shareables[zoneId][16],
+}
+-- Matus-Akin Egg Mine
+DAS.shareables[924] = {
+	[1] = DAS.shareables[zoneId][18],
+}
+-- Matus-Akin Egg Mine
+DAS.shareables[925] = {
+	[1] = DAS.shareables[zoneId][19],
+}
+-- Ashalmawia
+DAS.shareables[961] = {
+	[1] = DAS.shareables[zoneId][1],
+}
+
+DAS.makeBingoTable(zoneId, tbl2)
+
+
+DAS.questStarter[zoneId] = {
+    [GetString(DAS_QUEST_M_BELERU)]     = true,  -- Hall of Justice
+    [GetString(DAS_QUEST_M_TRAYLAN)]    = true,  -- Hall of Justice
+    [GetString(DAS_QUEST_M_ASHLANDER)]  = true,  -- Ashlander Hunt
+    [GetString(DAS_QUEST_M_NUMANI)]     = true,  -- Ashlander Relics
+    [GetString(DAS_QUEST_M_RIVYN)]      = true,  -- Battlegrounds
+}
+
+DAS.questFinisher[zoneId] = {
+    [GetString(DAS_QUEST_M_ASHLANDER)]  = true,
+    [GetString(DAS_QUEST_M_NUMANI)]     = true,
+
+    [GetString(DAS_QUEST_M_NARA)]       = true,
+    [GetString(DAS_QUEST_M_TRAYLAN )]   = true,
+    [GetString(DAS_QUEST_M_BELERU  )]   = true,
+    [GetString(DAS_QUEST_M_NUMANI  )]   = true,
+    [GetString(DAS_QUEST_M_NARA    )]   = true,
+    [GetString(DAS_QUEST_M_TIRVINA )]   = true,
+    [GetString(DAS_QUEST_M_DINOR   )]   = true,
+    [GetString(DAS_QUEST_M_BRAVOSI )]   = true,
+    [GetString(DAS_QUEST_M_IVULEN  )]   = true,
+    [GetString(DAS_QUEST_M_SAVILE  )]   = true,
+    [GetString(DAS_QUEST_M_KYLIA   )]   = true,
+    [GetString(DAS_QUEST_M_EVOS    )]   = true,
+    [GetString(DAS_QUEST_M_ALVES   )]   = true,
+    [GetString(DAS_QUEST_M_DREDASE )]   = true,
+    [GetString(DAS_QUEST_M_VORAR   )]   = true,
+    [GetString(DAS_QUEST_M_VALGA   )]   = true,
+    [GetString(DAS_QUEST_M_RIVYN)]      = true,  -- Battlegrounds
+}
+
diff --git a/questData/Wrothgar.lua b/questData/Wrothgar.lua
new file mode 100644
index 0000000..08b37a4
--- /dev/null
+++ b/questData/Wrothgar.lua
@@ -0,0 +1,62 @@
+DAS.shareables 	        = DAS.shareables            or {}
+DAS.bingo 		        = DAS.bingo 	            or {}
+DAS.questFinisher  = DAS.questFinisher    or {}
+DAS.questStarter   = DAS.questStarter     or {}
+
+local zoneId	= 684
+
+DAS.shareables[zoneId] = {
+
+    [1] = GetString(DAS_W_POACHERS),
+    [2] = GetString(DAS_W_EDU),
+    [3] = GetString(DAS_W_NYZ),
+    [4] = GetString(DAS_W_CORI),
+    [5] = GetString(DAS_W_DOLMEN),
+    [6] = GetString(DAS_W_OGRE),
+
+    [7] = GetString(DAS_W_HARPIES),
+    [8] = GetString(DAS_W_SPIRITS),
+    [9] = GetString(DAS_W_DURZOGS),
+    [10] = GetString(DAS_W_DWEMER),
+    [11] = GetString(DAS_W_WEREWOLVES),
+    [12] = GetString(DAS_W_THAT_OTHER),
+}
+local tbl2 = {}
+
+table.insert(tbl2, {[1] = "poa",    [2] = "poacher"})
+table.insert(tbl2, "edu")
+table.insert(tbl2, "nyz")
+table.insert(tbl2, {[1] = "cori",   [2] = "nb"})
+table.insert(tbl2, {[1] = "dolmen", [2] = "zan", [3] = "dol",   [4] = "ud"})
+table.insert(tbl2, {[1] = "ogre",   [2] = "mad", [3] = "shrek"})
+
+table.insert(tbl2, "harpy")
+table.insert(tbl2, "spirits")
+table.insert(tbl2, "durzog")
+table.insert(tbl2, "dwemer")
+table.insert(tbl2, {[1] = "wolf",   [2] = "skintrade"})
+table.insert(tbl2, {[1] = "bandit", [2] = "fire"})
+
+DAS.makeBingoTable(zoneId, tbl2)
+
+DAS.questStarter[zoneId] = {
+    [GetString(DAS_QUEST_W_GURUZUG)] = true,
+    [GetString(DAS_QUEST_W_ARZORAG)] = true,
+}
+
+DAS.questFinisher[zoneId] = {
+    [GetString(DAS_QUEST_W_OUFA      )] = true,
+    [GetString(DAS_QUEST_W_USHANG    )] = true,
+
+    [GetString(DAS_QUEST_W_NEDNOR    )] = true,
+    [GetString(DAS_QUEST_W_THAZEK    )] = true,
+    [GetString(DAS_QUEST_W_ARUSHNA   )] = true,
+    [GetString(DAS_QUEST_W_LILYAMEH  )] = true,
+    [GetString(DAS_QUEST_W_BAGRUBESH )] = true,
+    [GetString(DAS_QUEST_W_CIRANTILLE)] = true,
+    [GetString(DAS_QUEST_W_BIRKHU    )] = true,
+    [GetString(DAS_QUEST_W_MENNINIA  )] = true,
+    [GetString(DAS_QUEST_W_SONOLIA   )] = true,
+    -- [GetString(DAS_QUEST_W_RAYNOR    )] = true,
+
+}
diff --git a/startup.lua b/startup.lua
new file mode 100644
index 0000000..1941869
--- /dev/null
+++ b/startup.lua
@@ -0,0 +1,451 @@
+DailyAutoShare              = DailyAutoShare or {}
+DAS                         = DailyAutoShare
+local DailyAutoShare        = DailyAutoShare
+
+DAS.name                    = "Daily Autoshare"
+DAS.version                 = "3.0.5a"
+DAS.author                  = "manavortex"
+DAS.settings                = {}
+DAS.globalSettings          = {}
+
+DAS.shareables   	        = {}
+DAS.bingo 			        = {}
+DAS.subzones 		        = {}
+
+DAS.questFinisher      = {}
+DAS.questStarter       = {}
+
+DAS.channelTypes 	        = {
+    [CHAT_CHANNEL_PARTY]    = true,
+    [CHAT_CHANNEL_SAY ]     = false,
+    [CHAT_CHANNEL_YELL]     = false,
+    [CHAT_CHANNEL_ZONE]     = false,
+    [CHAT_CHANNEL_WHISPER]  = false,
+}
+
+DAS.locale 			    = GetCVar("language.2")
+DAS.autoInviting        = false
+DAS.guildInviteText     = nil
+
+DAS_STATUS_COMPLETE 	= 0
+DAS_STATUS_OPEN 		= 1
+DAS_STATUS_ACTIVE		= 2
+DAS_STATUS_TRACKED	    = 3
+
+local activeInCurrentZone   = false
+DAS.fullBingoString         = ""
+local fullBingoString       = DAS.fullBingoString
+
+local defaults = {
+
+	["singleDailies"]               = {},
+	["shareableDailies"]            = {},
+	["speakStupid"]                 = false,
+	["debug"] 		                = false,
+	["keepInviteUpOnDegroup"] 		= false,
+
+	["DasControl"] = {
+		["x"] = 0,
+		["y"] = 0,
+	},
+	["DasButton"] = {
+		["x"] = 0,
+		["y"] = 0,
+	},
+	["inactiveZones"]			= {
+		["hide"]				= true,
+	},
+	[849] = {
+		["relic"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["hunt"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["delve"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["boss"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+	},
+	[980] = {
+		["crow"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["craft"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["delve"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+		["boss"] = {
+			["invisible"] = false,
+			["active"] = true,
+		},
+	},
+    questShareString            = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite",
+	debugOutput		   			= false,
+	currentlyWithQuest 			= false,
+	currentQuestIndex 			= nil,
+	currentQuestName 			= nil,
+	autoTrack 					= false,
+	autoAcceptInvite 			= false,
+	autoAcceptInviteInterval 	= 5,
+	autoAcceptQuest		        = true,
+	autoAcceptShared 			= true,
+	autoDeclineShared 			= false,
+	autoAcceptAllDailies 		= false,
+	autoInvite 					= false,
+	autoLeave 					= true,
+	useGlobalSettings 			= true,
+	minimised 					= false,
+	locked 						= false,
+	hidden 						= false,
+	fontScale					= 1,
+	tooltipRight 				= false,
+	upsideDown 					= false,
+	autoHide 					= false,
+	autoMinimize 				= false,
+	autoShare 					= true,
+	hideCompleted				= false,
+	startupMinimized			= true,
+	lastLookingFor 				= "",
+	guildInviteNumber 			= 1,
+	guildInviteText,
+    questShareString            = "I can give a DailyAutoShare for <<1>>, type <<2>> for an instant invite",
+	listenInGuilds,
+    ["tracked"] = {
+		[684] = true,
+		[823] = true,
+		[849] = true,	-- Vvardenfell
+		[181] = false,
+	},
+}
+
+local function pointerUpSubzones()
+
+    -- Gold Coast
+    defaults[825]                       = defaults[823]
+
+    -- Capitals
+    defaults[19]                       = defaults[57]
+    defaults[383]                      = defaults[57]
+
+    -- Clockwork City
+    defaults[981]                       = defaults[980]
+    defaults[981]                       = defaults[980]
+    defaults[982]                       = defaults[980]
+    defaults.tracked[982]               = defaults.tracked[980]
+    defaults.tracked[983]               = defaults.tracked[980]
+    defaults.tracked[983]               = defaults.tracked[980]
+
+    -- Morrowind
+    defaults[921]                       = defaults[849]
+    defaults[922]                       = defaults[849]
+    defaults[923]                       = defaults[849]
+    defaults[924]                       = defaults[849]
+    defaults[925]                       = defaults[849]
+    defaults[961]                       = defaults[849]
+    defaults.tracked[921]               = defaults.tracked[849]
+    defaults.tracked[922]               = defaults.tracked[849]
+    defaults.tracked[923]               = defaults.tracked[849]
+    defaults.tracked[924]               = defaults.tracked[849]
+    defaults.tracked[925]               = defaults.tracked[849]
+    defaults.tracked[961]               = defaults.tracked[849]
+
+    -- Wrothgar
+    defaults[689]                       = defaults[684]
+    defaults[690]                       = defaults[684]
+    defaults[691]                       = defaults[684]
+    defaults[692]                       = defaults[684]
+    defaults[693]                       = defaults[684]
+    defaults[694]                       = defaults[684]
+    defaults.tracked[689]               = defaults.tracked[684]
+    defaults.tracked[690]               = defaults.tracked[684]
+    defaults.tracked[691]               = defaults.tracked[684]
+    defaults.tracked[692]               = defaults.tracked[684]
+    defaults.tracked[693]               = defaults.tracked[684]
+    defaults.tracked[694]               = defaults.tracked[684]
+end
+pointerUpSubzones()
+
+local characterName     = zo_strformat(GetUnitName('player'))
+
+local allDailyQuestIds = DAS_QUEST_IDS
+
+local em = EVENT_MANAGER
+
+local function debugOut(p1, p2, p3, p4, p5, p6, p7, p8)
+    if (not p2) then
+        d(p1)
+        return
+    end
+    if p8 then
+        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>> <<8>>", p1, p2, p3, p4, p5, p6, p7, p8))
+    elseif p7 then
+        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>> <<7>>", p1, p2, p3, p4, p5, p6, p7))
+    elseif p6 then
+        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>> <<6>>", p1, p2, p3, p4, p5, p6))
+    elseif p5 then
+        d(zo_strformat("<<1>> <<2>> <<3>> <<4>> <<5>>", p1, p2, p3, p4, p5))
+    elseif p4 then
+        d(zo_strformat("<<1>> <<2>> <<3>> <<4>>", p1, p2, p3, p4))
+    elseif p3 then
+        d(zo_strformat("<<1>> <<2>> <<3>>", p1, p2, p3))
+    else
+        d(zo_strformat("<<1>> <<2>>", p1, p2))
+    end
+end
+DAS.DebugOut = debugOut
+local p = debugOut
+
+function DAS.Report(text)
+	if not DAS.GetShutUp() then d(text) end
+end
+
+DAS.activeZoneQuests = {}
+
+--==============================
+--======= Event hooks  =========
+--==============================
+
+local function OnGroupTypeChanged(eventCode, unitTag)
+	if IsUnitGrouped("player") or not DAS.GetStopInviteOnDegroup() then return end
+	DAS.SetAutoInvite(false)
+end
+
+local function OnQuestAdded(eventCode, journalIndex, questName, objectiveName)
+
+	local zoneId = DAS.GetZoneId()
+	if not DAS.GetActiveIn(zoneId) 			then return end
+	if not GetIsQuestSharable(journalIndex) then return end
+	local shareables = DAS.shareables[zoneId] or {}
+
+	if nil ~= shareables[questName] then
+		DAS.LogQuest(questName, false)
+		zo_callLater(function() DAS.RefreshControl(true) end, 700)
+	end
+end
+
+local function OnQuestShared(eventCode, questId)
+	if not allDailyQuestIds[questId] then return end
+	local questName, _, _, displayName = GetOfferedQuestShareInfo(questId)
+	local zoneId = DAS.GetZoneId()
+	if nil ~= DAS.GetArrayEntry(DAS.shareables[zoneId], questName) then
+        if DAS.GetAutoDeclineShared() then
+            DAS.Report("DailyAutoShare declined a quest for you. Type /DailyAutoShare disabledecline to stop it from doing so.")
+            DeclineSharedQuest(questId)
+        else
+            AcceptSharedQuest(questId)
+            zo_callLater(function() DAS.RefreshControl(true) end, 500)
+        end
+    end
+end
+
+local function OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
+    return DAS.OnChatMessage(eventCode, channelType, fromName, messageText, _, fromDisplayName)
+end
+
+DAS.bingoFallback = {}
+function DAS.makeBingoTable(zoneId, tbl)
+	DAS.bingo[zoneId] = {}
+    DAS.bingoFallback[zoneId] = {}
+	for key, value in pairs(tbl) do
+        if type(value) == "table" then
+            local best = value[1]
+            for _, actualValue in ipairs(value) do
+                DAS.bingo[zoneId][actualValue] = key
+                DAS.bingoFallback[zoneId][actualValue] = best
+            end
+        else
+            DAS.bingo[zoneId][value] = key
+        end
+	end
+	return DAS.bingo[zoneId]
+end
+
+function DAS.getBingoTable(zoneId)
+    zoneId = zoneId or DAS.GetZoneId()
+    return DAS.bingo[zoneId] or {}
+end
+
+function DAS.SetChatListenerStatus(status)
+
+    DAS.channelTypes[CHAT_CHANNEL_SAY ]     = status
+    DAS.channelTypes[CHAT_CHANNEL_YELL]     = status
+    DAS.channelTypes[CHAT_CHANNEL_ZONE]     = status
+    DAS.channelTypes[CHAT_CHANNEL_WHISPER]  = status
+
+end
+
+
+local function OnPlayerActivated(eventCode)
+	local active 		= DAS.GetActiveIn()
+	DAS.SetHidden(not active)
+    DAS.SetAutoInvite(DAS.GetAutoInvite()) -- disables if we aren't group lead
+    DAS.SetChatListenerStatus(DAS.autoInviting)
+	DAS.RefreshControl(true)
+    DAS.guildInviteText = DAS.GetGuildInviteText()
+    DAS.cacheChatterData()
+end
+
+local function OnUnitCreated(eventCode, unitTag)
+    local unitZone = GetZoneId(GetUnitZoneIndex(unitTag))
+    if not DAS.GetActiveIn(unitZone) then return end
+    if GetUnitDisplayName(unitTag) == cachedDisplayName then return end
+    DAS.TryShareActiveDaily(unitZone)
+end
+
+local function OnQuestToolUpdate()
+	DAS.RefreshControl(true)
+end
+
+
+
+local function OnQuestRemoved(eventCode, isCompleted, journalIndex, questName, zoneIndex, poiIndex, questId)
+
+    -- is it a daily quest, and are we logging?
+    if not (allDailyQuestIds[questId] and DAS.GetActiveIn()) then return end
+
+	DAS.LogQuest(questName, isCompleted)
+
+    -- set auto invite off until the questlog has refreshed
+	local autoInvite = DAS.GetAutoInvite()
+    DAS.SetAutoInvite(false)
+
+
+    zo_callLater(function()
+        DAS.SetAutoInvite(autoInvite)
+        DAS.RefreshControl(true)
+    end, 1000)
+end
+
+local function deleteYesterdaysLog()
+	-- kill yesterday's log, we don't need it
+	local currentDate = tonumber(GetDate())
+	if (nil ~= DAS.globalSettings and nil ~= DAS.globalSettings.lastLogDate) and (DAS.globalSettings.lastLogDate < currentDate) then
+	if nil == DAS.Log then DAS.Log = {} end
+		DAS.Log[DAS.globalSettings.lastLogDate] = nil
+		DAS.globalSettings.lastLogDate = currentDate
+	end
+end
+
+local function hookQuestTracker()
+	local function refreshLabels()
+		DAS.RefreshLabels(false, true)
+	end
+	-- SetMapToQuestZone
+	ZO_PreHook(QUEST_TRACKER, "ForceAssist", refreshLabels)
+end
+
+--==============================
+--= DailyAutoShare_Initialize ==
+--==============================
+
+local function RegisterEventHooks()
+
+	DailyAutoShare.Fragment 	= ZO_HUDFadeSceneFragment:New(DasControl)
+
+	SCENE_MANAGER:GetScene("hud"  ):AddFragment(DailyAutoShare.Fragment)
+	SCENE_MANAGER:GetScene("hudui"):AddFragment(DailyAutoShare.Fragment)
+	hookQuestTracker()
+
+	em:RegisterForEvent("DailyAutoshare", EVENT_PLAYER_ACTIVATED, 		OnPlayerActivated)
+
+	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_ADDED, 			OnQuestToolUpdate)
+	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_REMOVED, 			OnQuestRemoved)
+	em:RegisterForEvent("DailyAutoshare", EVENT_TRACKING_UPDATE, 		OnQuestToolUpdate)
+
+	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_ADDED, 			OnQuestAdded)
+	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_REMOVED, 			OnQuestRemoved)
+	em:RegisterForEvent("DailyAutoshare", EVENT_QUEST_SHARED, 			OnQuestShared)
+
+
+	em:RegisterForEvent("DailyAutoshare", EVENT_UNIT_CREATED,	 		OnUnitCreated)
+	em:RegisterForEvent("DailyAutoshare", EVENT_UNIT_DESTROYED, 		OnGroupTypeChanged)
+
+	em:RegisterForEvent("DailyAutoShare", EVENT_CHAT_MESSAGE_CHANNEL,   OnChatMessage)
+	-- DasControl:OnMoveStop
+	-- DailyAutoShare.SaveControlLocation(self)
+end
+
+local currentDate = tonumber(GetDate())
+local function resetQuests()
+    DAS.todaysLog = {}
+    DAS.globalSettings.completionLog[currentDate] = DAS.todaysLog
+    DAS.RefreshControl(true)
+end
+
+-- has to be a local var, lua error if not
+-- Keep outside of function namespace so we can overwrite it for debugging
+local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08
+local function handleLog(forceReset)
+
+
+    DAS.todaysLog = DAS.globalSettings.completionLog[currentDate] or {}
+    local lastDate, logSize, counter = _, NonContiguousCount(DAS.todaysLog), 0
+
+    if forceReset then
+        return resetQuests()
+    end
+
+    for dateString, dateLog in pairs(DAS.todaysLog) do
+        counter = counter + 1
+        if counter < logSize-2 and dateString < currentDate then
+            DAS.globalSettings.completionLog[dateString] = nil
+        else
+            lastDate = dateString
+        end
+    end
+
+    local afterEight = tonumber(GetTimeString():sub(0, 2)) >= 08 -- has to be a local var, lua error if not
+    if (not afterEight) and DAS.todaysLog == {} and lastDate ~= dateString then
+        DAS.todaysLog = DAS.globalSettings.completionLog[lastDate]
+    end
+    DAS.globalSettings.completionLog[currentDate] = DAS.todaysLog
+end
+DAS.handleLog = handleLog
+
+local function minimiseOnStartup()
+	DAS.SetMinimized(DAS.GetSettings().startupMinimized)
+end
+--==============================
+--===== Rise, my minion!  ======
+--==============================
+
+function DailyAutoShare_Initialize(eventCode, addonName)
+
+	if addonName ~="DailyAutoShare" then return end
+
+	DailyAutoShare.settings = ZO_SavedVars:New("DAS_Settings", 0.2, nil, defaults)
+	DailyAutoShare.globalSettings = ZO_SavedVars:NewAccountWide("DAS_Globals", 0.2, "DAS_Global", defaults)
+    DAS.pdn = GetUnitDisplayName('player')
+
+	RegisterEventHooks()
+
+	DailyAutoShare.CreateMenu(DailyAutoShare.settings, defaults)
+	DAS.CreateGui()
+
+    -- local timetoreset = (GetTimeStamp() - 60*60*7)%86400
+    -- zo_callLater(resetQuests, timetoreset)
+
+
+    handleLog()
+    zo_callLater(OnPlayerActivated, 5000)
+    zo_callLater(minimiseOnStartup, 5500)
+	EVENT_MANAGER:UnregisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED)
+
+end
+
+
+ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_GUI",  GetString(DAS_SI_TOGGLE))
+ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_DAS_LIST", GetString(DAS_SI_MINIMISE))
+EVENT_MANAGER:RegisterForEvent("DailyAutoShare", EVENT_ADD_ON_LOADED, DailyAutoShare_Initialize)
diff --git a/textures/accept_down.dds b/textures/accept_down.dds
new file mode 100644
index 0000000..8a579fe
Binary files /dev/null and b/textures/accept_down.dds differ
diff --git a/textures/accept_up.dds b/textures/accept_up.dds
new file mode 100644
index 0000000..c37626d
Binary files /dev/null and b/textures/accept_up.dds differ
diff --git a/textures/down_down.dds b/textures/down_down.dds
new file mode 100644
index 0000000..996ddbb
Binary files /dev/null and b/textures/down_down.dds differ
diff --git a/textures/down_over.dds b/textures/down_over.dds
new file mode 100644
index 0000000..591a635
Binary files /dev/null and b/textures/down_over.dds differ
diff --git a/textures/down_up.dds b/textures/down_up.dds
new file mode 100644
index 0000000..d2b7282
Binary files /dev/null and b/textures/down_up.dds differ
diff --git a/textures/invite_active.dds b/textures/invite_active.dds
new file mode 100644
index 0000000..2bcf8a7
Binary files /dev/null and b/textures/invite_active.dds differ
diff --git a/textures/invite_down.dds b/textures/invite_down.dds
new file mode 100644
index 0000000..04279a2
Binary files /dev/null and b/textures/invite_down.dds differ
diff --git a/textures/invite_up.dds b/textures/invite_up.dds
new file mode 100644
index 0000000..c338bd7
Binary files /dev/null and b/textures/invite_up.dds differ
diff --git a/textures/reload_down.dds b/textures/reload_down.dds
new file mode 100644
index 0000000..b8cd53e
Binary files /dev/null and b/textures/reload_down.dds differ
diff --git a/textures/reload_up.dds b/textures/reload_up.dds
new file mode 100644
index 0000000..2c246ff
Binary files /dev/null and b/textures/reload_up.dds differ
diff --git a/textures/share_down.dds b/textures/share_down.dds
new file mode 100644
index 0000000..9789e8d
Binary files /dev/null and b/textures/share_down.dds differ
diff --git a/textures/share_up.dds b/textures/share_up.dds
new file mode 100644
index 0000000..1c379f6
Binary files /dev/null and b/textures/share_up.dds differ
diff --git a/textures/speaker_down.dds b/textures/speaker_down.dds
new file mode 100644
index 0000000..d0c5e14
Binary files /dev/null and b/textures/speaker_down.dds differ
diff --git a/textures/speaker_up.dds b/textures/speaker_up.dds
new file mode 100644
index 0000000..e665115
Binary files /dev/null and b/textures/speaker_up.dds differ
diff --git a/textures/speechbubble_down.dds b/textures/speechbubble_down.dds
new file mode 100644
index 0000000..6fc7c2a
Binary files /dev/null and b/textures/speechbubble_down.dds differ
diff --git a/textures/speechbubble_up.dds b/textures/speechbubble_up.dds
new file mode 100644
index 0000000..5cf4a0b
Binary files /dev/null and b/textures/speechbubble_up.dds differ
diff --git a/textures/up_down.dds b/textures/up_down.dds
new file mode 100644
index 0000000..c553b2c
Binary files /dev/null and b/textures/up_down.dds differ
diff --git a/textures/up_over.dds b/textures/up_over.dds
new file mode 100644
index 0000000..ea35d3c
Binary files /dev/null and b/textures/up_over.dds differ
diff --git a/textures/up_up.dds b/textures/up_up.dds
new file mode 100644
index 0000000..a2f7f06
Binary files /dev/null and b/textures/up_up.dds differ
diff --git a/textures/x_down.dds b/textures/x_down.dds
new file mode 100644
index 0000000..a1424fc
Binary files /dev/null and b/textures/x_down.dds differ
diff --git a/textures/x_up.dds b/textures/x_up.dds
new file mode 100644
index 0000000..cd4bd15
Binary files /dev/null and b/textures/x_up.dds differ
diff --git a/xml/Bindings.xml b/xml/Bindings.xml
new file mode 100644
index 0000000..c8c3915
--- /dev/null
+++ b/xml/Bindings.xml
@@ -0,0 +1,16 @@
+<Bindings>
+    <Layer name="SI_KEYBINDINGS_CATEGORY_GENERAL">
+        <Category name="DailyAutoshare">
+            <Action name="TOGGLE_DAS_GUI">
+                <Down>
+					DAS.SetHidden(not DAS.GetHidden())
+				</Down>
+            </Action>
+			<Action name="TOGGLE_DAS_LIST">
+                <Down>
+					 DAS.MinMaxButton()
+				</Down>
+            </Action>
+        </Category>
+    </Layer>
+</Bindings>
\ No newline at end of file