changeset 109:caa482329919

POI optimization
author Nenue
date Mon, 10 Jul 2017 18:34:11 -0400
parents b67ba1078824
children f6ef9a9f5476
files ClassPlanShipments.lua FlightMap.lua MapFrame.lua QuestPOI.lua QuestPOI.xml WorldMap.lua WorldMap.xml WorldPlan.lua WorldPlan.toc WorldPlan.xml WorldQuests.lua WorldQuests.xml
diffstat 12 files changed, 833 insertions(+), 847 deletions(-) [+]
line wrap: on
line diff
--- a/ClassPlanShipments.lua	Sat Jun 03 17:20:14 2017 -0400
+++ b/ClassPlanShipments.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -107,12 +107,14 @@
       AddShipmentInfo(AK_NOTES, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString)
     end
 
-    local talentTrees = CG_GetTalentTrees(garrisonType, select(3, UnitClass("player")));
+
+    local talentTrees = C_Garrison.GetTalentTreeIDsByClassID(garrisonType, select(3, UnitClass("player")));
     -- this is a talent that has completed, but has not been seen in the talent UI yet.
     local completeTalentID = CG_GetCompleteTalent(garrisonType);
-    --print('Talents:')
+    print('Talents:')
     if (talentTrees) then
-      for treeIndex, tree in ipairs(talentTrees) do
+      for treeIndex, treeID in ipairs(talentTrees) do
+        local _, _, tree = C_Garrison.GetTalentTreeInfoForID(garrisonType, treeID);
         for talentIndex, talent in ipairs(tree) do
           local showTalent = false;
           if (talent.isBeingResearched) or (talent.id == completeTalentID) then
--- a/FlightMap.lua	Sat Jun 03 17:20:14 2017 -0400
+++ b/FlightMap.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -71,7 +71,7 @@
 function WorldPlanDataProvider:RefreshAllData()
   local print = print
   print('|cFFFF0088'..self.owningMap:GetName()..':RefreshAllData()|r')
-
+  db.PinStrata = 'HIGH'
 
   local pinsToRemove = {};
   for questId in pairs(self.activePins) do
--- a/MapFrame.lua	Sat Jun 03 17:20:14 2017 -0400
+++ b/MapFrame.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -102,7 +102,7 @@
     [1] = {'TOPLEFT', 'TOPLEFT', 0, 0, WorldMapFrameNavBarOverlay},
     [2] = {'BOTTOMRIGHT', 'BOTTOMRIGHT', 0, 0, WorldMapFrameNavBarOverlay},
   },
-
+  [WorldMapFrameTitleText] = { hidden = true },
   [WorldMapFrameBotLeftCorner] = { hidden = true},
   [WorldMapFramePortraitFrame] = { hidden = true},
   [WorldMapFramePortrait] = { hidden = true, },
--- a/QuestPOI.lua	Sat Jun 03 17:20:14 2017 -0400
+++ b/QuestPOI.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -336,7 +336,8 @@
   --DEFAULT_CHAT_FRAME:AddMessage('|cFFFFFF00'..self:GetName()..'|r:OnHide()')
   self:HideOrShowFrames(false)
   -- reset flags
-  self:SetAlpha(db.PinAlpha)
+  self.icon:SetAlpha(db.PinAlpha)
+  self.RewardBorder:SetAlpha(db.PinAlpha)
   self.isAnimating = nil
   --if db.Config.DebugEnabled then
   --  db.log(tostring(self.questID) .. ' ' .. tostring(self.title) .. "\n" .. tostring(REWARD_TYPE_NAMES[self.rewardType]) .. ' ' .. tostring(self.itemName) .. ' ' .. tostring(self.itemNumber) .. "\n|cFFFF4400" .. (self.hideReason or 'NO_MESSAGE') .. "|r\n|cFF00FFFF" ..  debugstack(2,3,0) .. '|r')
@@ -453,7 +454,6 @@
 
 local updateTime, markTime
 function QuestPOI:OnUpdate (sinceLast)
-  -- control update check intervals
 
   if self.toAlpha then
     if not self.alphaStart then
@@ -487,18 +487,14 @@
 
     else
       self.toAlpha = nil
-    end
-
-    if not self.toAlpha then
       self.alphaStart = nil
-    else
-      self.alphaStart = GetTime()
     end
 
     self.icon:SetAlpha(alpha)
     self.RewardBorder:SetAlpha(alpha)
   end
 
+  -- control update check intervals
   self.throttle = (self.throttle or self.updateRate) + sinceLast
   if self.throttle >= self.updateRate then
     -- factor overtime into the throttle timer
@@ -521,16 +517,12 @@
   if not self.dataLoaded then
     local dataLoaded = self:GetData()
     if dataLoaded and not tContains(db.UpdatedPins, self) then
-      -- self.PendingFade:Stop()
-      -- scale info from the parent module is needed, so deal with it there
       print('|cFF00FF88  queueing for update')
       self.isNew = true
-      tinsert(db.UpdatedPins, self)
-    else
-
-      --print('|cFFFF4400OnUpdate(|r'..self:GetID()..'|cFFFF4400)|r poll failed')
+      self.toAlpha = nil
+      self.alphaStart = nil
+      self:Refresh()
     end
-    return
   end
 
   if self.isStale then
@@ -972,10 +964,8 @@
       self.isNew = nil
     end
   else
-    if not self.toAlpha then
-      icon:SetAlpha(0)
-      iconBorder:SetAlpha(0)
-    end
+    icon:SetAlpha(self.toAlpha or 0)
+    iconBorder:SetAlpha(self.toAlpha or 0)
   end
 
   if self.itemName then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QuestPOI.xml	Mon Jul 10 18:34:11 2017 -0400
@@ -0,0 +1,128 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+
+    <Script file="QuestPOI.lua" />
+
+
+
+    <Button name="WorldPlanQuestPin" virtual="true" hidden="true" mixin="WorldPlanPOIMixin">
+        <Animations>
+            <AnimationGroup parentKey="FadeIn" setToFinalAlpha="true" looping="NONE">
+                <Alpha parentKey="Icon" childKey="icon" duration="0.45" fromAlpha="0" toAlpha="1" order="1" />
+                <Alpha parentKey="Border" childKey="RewardBorder" duration="0.45" fromAlpha="0" toAlpha="1" order="1" />
+                <Scripts>
+                    <OnPlay>
+                        self:GetParent():OnAnimStart()
+                    </OnPlay>
+                    <OnStop>
+                        self:GetParent():OnAnimStop()
+                    </OnStop>
+                    <OnFinished>
+                        self:GetParent():OnAnimStop()
+                    </OnFinished>
+                </Scripts>
+            </AnimationGroup>
+        </Animations>
+        <Layers>
+            <Layer level="BACKGROUND" textureSubLevel="-2">
+                <Texture parentKey="HighlightBorder"  file="Interface\UNITPOWERBARALT\Generic1Target_Circular_Frame" desaturated="true">
+                    <Anchors>
+                        <Anchor point="CENTER" />
+                    </Anchors>
+                </Texture>
+                <Texture parentKey="EliteBorder" atlas="worldquest-questmarker-dragon" useAtlasSize="true" hidden="true">
+                    <Anchors>
+                        <Anchor point="TOPRIGHT" x="6" y="6" />
+                        <Anchor point="BOTTOMLEFT" x="-6" y="-6" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="BACKGROUND" textureSubLevel="-1">
+                <Texture parentKey="RewardBorder" file="Interface\Minimap\UI-Minimap-Background" desaturated="true" alpha="0">
+                    <Anchors>
+                        <Anchor point="CENTER" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer textureSubLevel="0">
+
+                <Texture parentKey="IconBackdrop" file="Interface\Minimap\UI-Minimap-Background">
+                    <Anchors>
+                        <Anchor point="CENTER" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="ARTWORK" textureSubLevel="2">
+                <Texture parentKey="icon" nonBlocking="true" setAllPoints="true" alpha="0">
+                    <Anchors>
+                        <Anchor point="CENTER" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="OVERLAY">
+                <Texture parentKey="tagIcon" nonBlocking="true" setAllPoints="false">
+                    <Size x="12" y="12" />
+                    <Anchors>
+                        <Anchor point="BOTTOMRIGHT" x="1" y="-1" />
+                    </Anchors>
+                </Texture>
+            </Layer>
+            <Layer level="HIGHLIGHT">
+                <Texture parentKey="highlight" alphaMode="ADD" alpha="1" file="Interface\UNITPOWERBARALT\Generic1Target_Circular_Frame" desaturated="true">
+                    <Anchors>
+                        <Anchor point="BOTTOMLEFT" />
+                        <Anchor point="TOPRIGHT" />
+                    </Anchors>
+                </Texture>
+
+            </Layer>
+        </Layers>
+        <Scripts>
+            <OnLoad method="OnLoad" />
+            <OnEvent method="OnEvent" />
+            <OnUpdate method="OnUpdate" />
+            <OnShow method="OnShow" />
+            <OnHide method="OnHide" />
+            <OnMouseDown method="OnMouseDown" />
+            <OnEnter method="OnEnter" />
+            <OnLeave method="OnLeave" />
+        </Scripts>
+        <Frames>
+            <Frame parentKey="Overlay" name="$parentOverlay" setAllPoints="true" hidden="true">
+                <!--
+                <Scripts>
+                  <OnShow>
+                    local out = debugstack(3,3,1)
+                    out = out:gsub("Interface%\\AddOns\\", "|cFFFF00FF\\|r")
+                    print('POI', self:GetName().. ':OnShow()\n' .. out:gsub("Interface%\\", "|cFF00FFFF\\|r"))
+                  </OnShow>
+                  <OnHide>
+                    local out = debugstack(3,3,1)
+                    out = out:gsub("Interface%\\AddOns\\", "|cFFFF00FF\\|r")
+                    print('POI', self:GetName().. ':OnHide()\n' .. out:gsub("Interface%\\", "|cFF00FFFF\\|r"))
+                  </OnHide>
+                </Scripts>
+                -->
+                <Layers>
+                    <Layer level="OVERLAY">
+                        <FontString inherits="WorldPlanNumberFontThin" parentKey="count">
+                            <Anchors>
+                                <Anchor point="BOTTOM" x="0" y="0" />
+                            </Anchors>
+                        </FontString>
+                        <FontString inherits="WorldPlanNumberFont" parentKey="timeLabel">
+                            <Anchors>
+                                <Anchor point="TOP" x="0" y="0" />
+                            </Anchors>
+                        </FontString>
+                        <FontString inherits="WorldPlanNumberFontThin" parentKey="Description">
+                            <Anchors>
+                                <Anchor point="TOP" relativePoint="BOTTOM" relativeKey="$parent.count" x="0" y="0" />
+                            </Anchors>
+                        </FontString>
+                    </Layer>
+                </Layers>
+            </Frame>
+        </Frames>
+    </Button>
+</Ui>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WorldMap.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -0,0 +1,660 @@
+-- WorldPlan
+-- WorldMap.lua
+-- Created: 11/2/2016 3:40 PM
+-- %file-revision%
+
+local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or nop
+local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or nop
+local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or nop
+local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or nop
+local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or nop
+local _, db = ...
+local Module = {
+  UsedPositions = {},
+}
+WorldPlanMapMixin = Module
+
+local _G = _G
+local type, tostring, tonumber, pairs, ipairs = type, tostring, tonumber, pairs, ipairs
+local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
+local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented
+local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID
+local TQ_IsActive = C_TaskQuest.IsActive
+local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData
+local pairs, ipairs, tinsert, tremove, wipe = pairs, ipairs, tinsert, tremove, table.wipe
+local GetTaskInfo, GetTasksTable, HaveQuestData = GetTaskInfo, GetTasksTable, HaveQuestData
+local GetTime = GetTime
+local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget
+local tonumber, abs = tonumber, math.abs
+local GetQuestLogRewardInfo = GetQuestLogRewardInfo
+local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID
+local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete
+local HaveQuestRewardData = HaveQuestRewardData
+local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
+local InCombatLockdown, hooksecurefunc = InCombatLockdown, hooksecurefunc
+
+local ToggleButton = {}
+local BROKEN_ISLES_ID, DALARAN_ID, AZSUNA_ID, VALSHARAH_ID, HIGHMOUNTAIN_ID, STORMHEIM_ID, SURAMAR_ID, EOA_ID = 1007, 1014, 1015,1018, 1024, 1017, 1033, 1096
+local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70',  [AZSUNA_ID] = 'Azsuna',  [VALSHARAH_ID] = "Val'sharah",
+  [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim',  [SURAMAR_ID] = 'Suramar',  [EOA_ID] = 'EyeOfAszhara', }
+
+local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
+local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
+local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
+local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
+local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
+local SCALE_FACTORS = { 0.25, 0.7, 1 }
+
+local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard
+local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton
+local defaults = {}
+local completedQuests = {}
+
+local continentScanned
+local layoutDirty = true
+local bountiesDirty = true
+local artifactPowerDirty = true
+local hooksDirty = true
+local currentScale = WorldMapDetailFrame:GetScale()
+local canTargetQuests
+local isDataLoaded = true
+local artifactKnowledgeLevel
+local superTrackedQuestID
+local lastRefresh
+local refreshReason
+
+local bountyQuests = {}
+local bountyInfo = {}
+local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
+
+local totalPins = 0
+local numShown = 0
+local numLoaded = 0
+local numOverlays = 1
+local scaleConstant = 1
+local pinBaseIndex = 1550
+local overlayBaseIndex = 1600
+
+local artifactKnowldegeSpells = {
+  [207856] = true,
+  [209203] = true,
+  [209204] = true,
+  [209205] = true,
+  [209206] = true,
+  [209207] = true,
+  [209208] = true,
+  [209209] = true,
+  [209210] = true,
+  [209211] = true,
+  [209212] = true,
+  [219978] = true,
+  [227852] = true,
+  [236477] = true,
+  [236489] = true,
+  [236302] = true,
+  [236488] = true,
+  [236490] = true,
+  [240475] = true,
+  [243176] = true,
+  [243177] = true,
+  [243178] = true,
+  [243182] = true,
+  [243183] = true,
+  [243187] = true,
+  [245133] = true,
+}
+
+--%debug%
+local SetTimedCallbackForAllPins = function(seconds, callback)
+  C_Timer.After(seconds, function()
+    for id, pin in pairs(WorldPlanQuests.QuestsByID) do
+      callback(pin)
+    end
+  end)
+end
+
+function Module:OnLoad()
+  --print('|cFFFF4400'..self:GetName()..':OnLoad()')
+
+  self:SetParent(WorldMapFrame.UIElementsFrame)
+  WorldPlan:AddHandler(self, defaults)
+
+  for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
+    db.QuestsByZone[areaID] = {}
+  end
+
+  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
+  self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
+  self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
+  self:RegisterEvent('SKILL_LINES_CHANGED')
+  self:RegisterEvent('ARTIFACT_UPDATE')
+  self:RegisterEvent('QUEST_LOG_UPDATE')
+  self:RegisterEvent('UNIT_SPELLCAST_STOP')
+end
+
+function Module:OnEvent (event, ...)
+  print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...)
+  if (event == 'QUEST_LOG_UPDATE') then
+    self:UpdateBounties(event)
+  elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
+    local questID = ...
+    if questID and db.QuestsByID[questID] then
+      completedQuests[questID] = true
+      db.QuestsByID[questID]:Release()
+    end
+    self:Refresh(event)
+  elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
+    self:Refresh(event)
+  elseif event == 'ARTIFACT_UPDATE' then
+    self:UpdateArtifactPower()
+  elseif event == 'MODIFIER_STATE_CHANGED' then
+    self:UpdateModifierState()
+  elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
+    if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
+      db.QuestsByID[superTrackedQuestID].isStale = true
+    end
+    local newID = GetSuperTrackedQuestID()
+    if newID and db.QuestsByID[newID] then
+      db.QuestsByID[newID].isStale = true
+    end
+  elseif event == 'UNIT_SPELLCAST_STOP' then
+    local name, _, _, _, spellID = ...
+    if artifactKnowldegeSpells[spellID] then
+      db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')')
+      self:UpdateArtifactPower()
+    end
+  end
+end
+
+function Module:OnUpdate(sinceLast)
+  if WorldPlanData.DebugEnabled then
+    if self.refreshBenchMarkTicker then
+      --print(self.refreshBenchMarkTicker)
+      self.refreshBenchMarkTicker =   self.refreshBenchMarkTicker - 1
+
+      if self.refreshBenchMarkTicker == 0 then
+
+        self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000)
+        self.debugMessage:SetText(self.refreshTime)
+        self.refreshBenchMarkTicker = nil
+      end
+    else
+      self.refreshBenchMark = GetTime()
+    end
+  end
+
+  if self.filtersDirty or self.isStale then
+    self:Refresh()
+  end
+
+  if #db.UpdatedPins >= 1 then
+    --print('|cFF00FF88pending update', #db.UpdatedPins)
+    self:UpdateNext()
+  end
+end
+
+local callbacks = {}
+callbacks.ClickWorldMapActionButton = function(WorldQuests)
+  WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
+end
+callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests)
+  WorldQuests:UpdateTaskPOIs()
+end
+callbacks.WorldMapFrame_UpdateMap = function(WorldQuests)
+  WorldQuests:RefreshIfChanged('WMF_UPDATE')
+end
+callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests)
+  WorldQuests:RefreshIfChanged('WMF_REANCHOR')
+end
+
+callbacks[BountyBoard] = {}
+callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests)
+  WorldQuests:UpdateBounties('BOUNTY_SELECTED')
+  for questID, pin in pairs(db.QuestsByID) do
+    pin.checkCriteria = true
+    pin:Refresh()
+  end
+end
+
+callbacks[ActionButton] = {}
+callbacks[ActionButton].UpdateCastingState = function(WorldQuests)
+  for questID, pin in pairs(db.QuestsByID) do
+    pin.checkCursor = true
+    pin:Refresh()
+  end
+end
+
+callbacks.UseWorldMapActionButtonSpellOnQuest = function(questID)
+  local pin = db.QuestsByID[questID]
+  -- calling this implies that the pin is used in some way
+  if pin then
+    db.log(pin.title ..  ' completed by spell?', IsQuestComplete(pin.questID))
+    pin:OnFilters()
+    pin.isStale = true
+  end
+end
+
+function Module:SetupCallbacks()
+  if InCombatLockdown() then
+    return true
+  end
+  print('SetupCallbacks()')
+  for target, arg in pairs(callbacks) do
+    --print(type(target))
+    if type(target) == 'table' then
+      local callerName = target:GetName() or tostring(target)
+      for name, method  in pairs(arg) do
+        --print(callerName, arg)
+        hooksecurefunc(target, name, function(...)
+          self:OnSecureHook(callerName .. '.' .. name, method, ...)
+        end)
+      end
+    else
+      hooksecurefunc(target, function(...)
+        self:OnSecureHook(target, arg, ...)
+      end)
+    end
+  end
+end
+
+function Module:Setup()
+  --print('|cFFFF4400'..self:GetName()..':Setup()')
+  for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
+    db.QuestsByZone[mapID] = {}
+  end
+
+  hooksDirty = self:SetupCallbacks()
+
+  self:SetAllPoints(WorldMapFrame.UIElementsFrame)
+  self:UpdateArtifactPower()
+  self:UpdateBounties('SETUP')
+  self:Show()
+end
+
+function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
+  if isNewMap or self.isStale then
+    print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
+    layoutDirty = true
+    self:Refresh('WORLD_MAP_CHANGED')
+  end
+end
+
+function Module:OnConfigUpdate()
+  --print('|cFFFFFF00OnConfigUpdate()|r')
+  if db.Config.FadeWhileGrouped then
+    db.PinAlpha = 0.15
+  else
+    db.PinAlpha = 1
+  end
+
+  if not db.Config.EnablePins then
+    for _, pin in pairs(db.QuestsByID) do
+      pin:SetShown(false)
+    end
+  end
+end
+
+function Module:OnSecureHook(callbackName, func, ...)
+  print('|cFFFF4400'..callbackName..'|r', ...)
+  func(self, ...)
+end
+
+function Module:UpdateModifierState()
+
+end
+
+function Module:UpdateTaskPOIs()
+  canTargetQuests = SpellCanTargetQuest()
+  for i = 1, NUM_WORLDMAP_TASK_POIS do
+    local poiFrame = _G['WorldMapFrameTaskPOI'..i]
+    if poiFrame and poiFrame.worldQuest then
+      local pin = db.QuestsByID[poiFrame.questID]
+      if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then
+        poiFrame:Show()
+      else
+        poiFrame:Hide()
+      end
+    end
+  end
+end
+-- re-anchors and scales pins that have had either of these changed due to data loading delays
+function Module:UpdateNext()
+  --print('|cFF00FF88UpdateNext()')
+  local pin = tremove(db.UpdatedPins)
+  pin:OnFilters()
+
+  local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
+  --print(pin.title, pin.dataLoaded  and not pin.filtered, scaleFactor)
+  if pin.used then
+    pin:SetShown(true)
+    pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
+    pin:Refresh()
+  else
+    print('|cFFFF4400flagging queued pin that got hidden:', pin.title)
+    pin.isStale = true
+  end
+end
+
+function Module:UpdateBounties(...)
+  bountiesDirty = nil
+  print('|cFF00FF88BountyInfo()|r', ...)
+  wipe(db.BountiesByFactionID)
+  wipe(db.BountiesByQuestID)
+
+  db.selectedBounty = nil
+  selectedBountyIndex = BountyBoard:GetSelectedBountyIndex()
+  db.Bounties, bountyDisplayLocation, bountyLockedQuestID = GetQuestBountyInfoForMapID(db.currentMapID, db.Bounties)
+  local numBounties = 0
+  for index, info in ipairs(db.Bounties) do
+      numBounties = numBounties + 1
+      info.index = index
+      info.complete =  IsQuestComplete(info.questID)
+      if not info.complete then
+        db.BountiesByFactionID[info.factionID] = info
+        db.BountiesByQuestID[info.questID] = info
+        if index == selectedBountyIndex then
+          db.selectedBounty = info
+          selectedBountyQuestID = info.questID
+        end
+        print(' ', index, info.factionID, GetQuestLogTitle(GetQuestLogIndexByID(info.questID)), info.complete, (index == selectedBountyIndex) and 'SELECTED' or '')
+      end
+  end
+end
+
+-- check current artifact knowledge and update pins accordingly
+function Module:UpdateArtifactPower(overrideLevel)
+  if InCombatLockdown() then
+    artifactPowerDirty = true
+    return
+  end
+
+  print('|cFF00FF88UpdateArtifactPower()|r')
+  local _, akLevel = GetCurrencyInfo(1171)
+  if overrideLevel then
+    akLevel = overrideLevel
+  end
+
+  --db.print('current AK', akLevel)
+  if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then
+    --print('new ak level', akLevel)
+    db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel))
+    for _, pin in pairs(db.QuestsByID) do
+      if (pin.rewardType == REWARD_ARTIFACT_POWER) then
+        print(pin.title, pin.itemNumber)
+        local newAP = pin:UpdateArtifactPower()
+        if newAP then
+          pin.itemNumber = newAP
+          print(newAP)
+        else
+          pin.dataLoaded = nil
+        end
+        pin.isStale = true
+      end
+    end
+    artifactKnowledgeLevel = akLevel
+  end
+  artifactPowerDirty = nil
+end
+
+local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
+function Module:Refresh(...)
+
+  if hooksDirty then
+    hooksDirty = self:SetupCallbacks()
+  end
+
+
+  if not self:IsVisible() then
+    print('|cFFFF4400Refresh()|r', ...)
+    return
+  else
+    if lastRefresh == GetTime() then
+      print('|cFFFF4400multiple refreshes tried')
+    end
+    lastRefresh = GetTime()
+    print(msg, lastRefresh, ...)
+  end
+
+
+  if bountiesDirty then
+    self:UpdateBounties()
+  end
+
+  if not db.Config.EnablePins then
+    numShown = 0
+    self.refreshBenchMark = GetTime()
+    self.refreshBenchMarkTicker = 2
+    print('starting bench', self.refreshBenchMark)
+    return
+  end
+
+  scaleConstant = db.isContinentMap and 2 or 3
+  canTargetQuests = SpellCanTargetQuest()
+
+  for index, pin in pairs(db.QuestsByID) do
+    pin.used = nil
+  end
+
+  self:UpdateAnchors(...)
+
+  if artifactPowerDirty and not InCombatLockdown() then
+    self:UpdateArtifactPower()
+  end
+  -- calculate quests shown
+  numShown = 0
+  numLoaded = 0
+  for questID, pin in pairs(db.QuestsByID) do
+    local oV = pin:IsShown()
+    if pin.used then
+      print('show', pin.title)
+      pin.throttle = 1
+      pin:SetShown(true)
+      numShown = numShown + 1
+      if pin.dataLoaded then
+        numLoaded = numLoaded + 1
+      end
+
+      pin.checkCriteria = true
+      pin.checkFilters = true
+      pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
+
+    else
+      if pin:IsShown() then
+        print('|cFFFF4400need to remove', pin.title)
+
+      end
+
+      pin.hideReason = "Not used in map area " .. (db.currentMapID)
+      pin:SetShown(false)
+    end
+
+  end
+
+
+--
+  self.refreshBenchMark = GetTime()
+  self.refreshBenchMarkTicker = 2
+  print('starting bench', self.refreshBenchMark)
+
+--
+
+  layoutDirty = nil
+  self.isStale = nil
+  self.sizesDirty = nil
+  self.isZoomDirty = nil
+
+  if WorldPlanSummary then
+    WorldPlanSummary.isStale = true
+  end
+
+end
+
+function Module:RefreshIfChanged(event)
+  local scaleCheck = WorldMapDetailFrame:GetScale()
+  refreshReason = nil
+  if scaleCheck ~= currentScale then
+    refreshReason = 'map scale updated'
+    currentScale = scaleCheck
+    layoutDirty = true
+  elseif self.isStale or layoutDirty then
+    refreshReason = 'layout is marked dirty'
+  end
+  if not refreshReason then
+    return
+  end
+
+  if self:IsVisible() then
+    print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
+    self:Refresh(event)
+  else
+    print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
+    self.isStale = true
+  end
+end
+
+-- Walks the current map tree and fires updates as needed
+function Module:UpdateAnchors (event)
+  wipe(self.UsedPositions)
+  local hostWidth, hostHeight = WorldMapPOIFrame:GetSize()
+
+  if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then
+    self.hostWidth, self.hostHeight = hostWidth, hostHeight
+    layoutDirty = true
+  end
+
+  print('|cFF00FF00UpdateAnchors()', event)
+  local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
+  if isMicroDungeon then
+    return
+  end
+
+  isDataLoaded = true
+  local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID)
+  if taskInfo then
+    self:UpdateQuestsForMap(taskInfo, db.currentMapID)
+  end
+  local numZones = MC_GetNumZones(db.currentMapID)
+  if numZones then
+    for i = 1, numZones do
+      local mapAreaID = MC_GetZoneInfo(db.currentMapID, i)
+      local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID)
+
+      db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {}
+
+      if taskInfo then
+        self:UpdateQuestsForMap(taskInfo, mapAreaID)
+      end
+    end
+  end
+end
+
+-- Attempt to display the pins for quests in taskInfo
+function Module:UpdateQuestsForMap(taskInfo, mapID)
+  print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
+  if db.QuestsByZone[mapID] then
+    wipe(db.QuestsByZone[mapID])
+  elseif db.isBrokenIsle then
+    continentScanned = true
+  end
+  db.PinStrata = WorldMapFrame_InWindowedMode() and 'HIGH' or 'FULLSCREEN'
+  print('layoutDirty =',layoutDirty)
+
+  for index, info in pairs(taskInfo) do
+    local questID, x, y = info.questId, info.x, info.y
+    local pin = self:AcquirePin(info)
+    if pin then
+      if pin.canShow then
+        pin.used = true
+        print('using', pin.title, (pin.owningFrame ~= WorldMapFrame))
+        if layoutDirty or (pin.owningFrame ~= WorldMapFrame) then
+          local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1]
+          pin.owningFrame = WorldMapFrame
+          pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
+
+        end
+        if db.QuestsByZone[mapID] then
+          db.QuestsByZone[mapID][questID] = pin
+        end
+      else
+        print('|cFFFF4400discarding|r', pin.title)
+      end
+    end
+  end
+end
+
+-- locates or creates a corresponding pin frame for the provided TaskInfo data
+function Module:AcquirePin (info)
+  local questID = info.questId
+  if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then
+    return nil
+  end
+  local pin = db.QuestsByID[questID]
+  -- check to avoid creating unnecessary frames
+  if IsQuestComplete(questID) or completedQuests[questID] then
+    completedQuests[questID] = true
+    if pin then
+      pin:Release()
+    end
+    return nil
+  end
+
+  if not pin then
+    local numFree = #db.FreePins
+    if numFree >= 1 then
+      pin = tremove(db.FreePins, numFree)
+      print('|cFF00FF00Acquire()|r Re-using', pin:GetName())
+    else
+      totalPins = totalPins + 1
+      local name = 'WorldPlanQuestMarker' .. numOverlays
+      print('|cFF00FF00Acquire()|r Creating', name)
+      pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
+
+      pin:SetID(totalPins)
+      numOverlays = numOverlays + 1
+      --pin.iconBorder:SetVertexColor(0,0,0,1)
+    end
+    pin.questID = questID
+    pin.throttle = pin.updateRate
+    pin.currentWidth = nil
+
+    db.QuestsByID[questID] = pin
+    tinsert(db.UsedPins, pin)
+  end
+
+  if info then
+    pin.inProgress = info.inProgress
+    pin.floor = info.floor
+    pin.numObjectives = info.numObjectives or 0
+    if info.x and info.y then
+      if (info.x ~= pin.x) or (info.y ~= pin.y) then
+        pin.isStale = true
+        --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
+      end
+    end
+  end
+
+  pin.x = info.x or pin.x
+  pin.y = info.y or pin.y
+
+  if not HaveQuestRewardData(questID) then
+    TQ_RequestPreloadRewardData(questID);
+  end
+
+  if (not pin.dataLoaded) then
+    local dataLoaded = pin:GetData()
+    if dataLoaded then
+      WorldPlan.dataFlush = true
+    else
+      isDataLoaded = false
+    end
+  end
+
+  pin:OnFilters()
+  pin.isActive = TQ_IsActive(questID)
+  --rprint(pin:GetID(), pin.filtered, pin.used)
+  return pin
+end
+
+function Module:Debug(...)
+  print(...)
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WorldMap.xml	Mon Jul 10 18:34:11 2017 -0400
@@ -0,0 +1,28 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+  <Script file="WorldMap.lua" />
+
+
+  <Frame name="$parentQuests" mixin="WorldPlanMapMixin" parent="WorldPlan">
+
+    <Scripts>
+      <OnLoad method="OnLoad" />
+      <OnEvent method="OnEvent" />
+      <OnUpdate method="OnUpdate" />
+      <OnShow method="OnShow" />
+    </Scripts>
+    <Layers>
+
+      <Layer level="OVERLAY">
+        <FontString parentKey="debugMessage" inherits="GameFontNormal">
+          <Anchors>
+            <Anchor point="TOP" x="0" y="-8" />
+
+          </Anchors>
+        </FontString>
+      </Layer>
+    </Layers>
+
+  </Frame>
+
+  </Ui>
\ No newline at end of file
--- a/WorldPlan.lua	Sat Jun 03 17:20:14 2017 -0400
+++ b/WorldPlan.lua	Mon Jul 10 18:34:11 2017 -0400
@@ -15,9 +15,6 @@
 
 -- Define tables here so the pointers match up
 WorldPlanCore = { defaults = {}, modules = {}, TaskQueue = {}, }
-WorldPlanQuestsMixin = {
-  UsedPositions = {},
-}
 WorldPlanPOIMixin = {}
 WorldPlanSummaryMixin = {}
 db.filtersDirty = true
--- a/WorldPlan.toc	Sat Jun 03 17:20:14 2017 -0400
+++ b/WorldPlan.toc	Mon Jul 10 18:34:11 2017 -0400
@@ -10,7 +10,8 @@
 ## OptionalDeps: Veneer
 
 WorldPlan.xml
-WorldQuests.xml
+QuestPOI.xml
+WorldMap.xml
 FilterBar.xml
 FlightMap.xml
 ClassPlan.xml
--- a/WorldPlan.xml	Sat Jun 03 17:20:14 2017 -0400
+++ b/WorldPlan.xml	Mon Jul 10 18:34:11 2017 -0400
@@ -2,7 +2,6 @@
 ..\FrameXML\UI.xsd">
 
   <Script file="WorldPlan.lua" />
-  <Script file="QuestPOI.lua" />
 
   <Font name="WorldPlanFont" font="Interface\AddOns\WorldPlan\Font\ArchivoNarrow-Regular.ttf" height="12" outline="NORMAL" virtual="true" />
   <Font name="WorldPlanNumberFont" font="Interface\AddOns\WorldPlan\Font\ArchivoNarrow-Bold.ttf" height="10" outline="NORMAL" virtual="true" />
@@ -13,149 +12,6 @@
   </GameTooltip>
 
 
-  <Button name="VeneerWQCompassTemplate" virtual="true" hidden="true">
-    <Size x="50" y="36" />
-    <Anchors>
-      <Anchor point="TOP" />
-    </Anchors>
-    <Layers>
-      <Layer level="ARTWORK">
-        <Texture parentKey="icon" name="$parentIcon" setAllPoints="false">
-          <Anchors>
-            <Anchor point="TOPLEFT" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer level="OVERLAY">
-        <FontString inherits="VeneerFont" parentKey="label">
-          <Anchors>
-            <Anchor point="LEFT" relativePoint="RIGHT" relativeKey="$parent.icon" />
-          </Anchors>
-        </FontString>
-      </Layer>
-    </Layers>
-  </Button>
-
-  <Button name="WorldPlanQuestPin" virtual="true" hidden="true" mixin="WorldPlanPOIMixin">
-    <Animations>
-      <AnimationGroup parentKey="FadeIn" setToFinalAlpha="true" looping="NONE">
-        <Alpha parentKey="Icon" childKey="icon" duration="0.45" fromAlpha="0" toAlpha="1" order="1" />
-        <Alpha parentKey="Border" childKey="RewardBorder" duration="0.45" fromAlpha="0" toAlpha="1" order="1" />
-        <Scripts>
-          <OnPlay>
-            self:GetParent():OnAnimStart()
-          </OnPlay>
-          <OnStop>
-            self:GetParent():OnAnimStop()
-          </OnStop>
-          <OnFinished>
-            self:GetParent():OnAnimStop()
-          </OnFinished>
-        </Scripts>
-      </AnimationGroup>
-    </Animations>
-    <Layers>
-      <Layer level="BACKGROUND" textureSubLevel="-2">
-        <Texture parentKey="HighlightBorder"  file="Interface\UNITPOWERBARALT\Generic1Target_Circular_Frame" desaturated="true">
-          <Anchors>
-            <Anchor point="CENTER" />
-          </Anchors>
-        </Texture>
-        <Texture parentKey="EliteBorder" atlas="worldquest-questmarker-dragon" useAtlasSize="true" hidden="true">
-          <Anchors>
-            <Anchor point="TOPRIGHT" x="6" y="6" />
-            <Anchor point="BOTTOMLEFT" x="-6" y="-6" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer level="BACKGROUND" textureSubLevel="-1">
-        <Texture parentKey="RewardBorder" file="Interface\Minimap\UI-Minimap-Background" desaturated="true" alpha="0">
-          <Anchors>
-            <Anchor point="CENTER" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer textureSubLevel="0">
-
-        <Texture parentKey="IconBackdrop" file="Interface\Minimap\UI-Minimap-Background">
-          <Anchors>
-            <Anchor point="CENTER" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer level="ARTWORK" textureSubLevel="2">
-        <Texture parentKey="icon" nonBlocking="true" setAllPoints="true" alpha="0">
-          <Anchors>
-            <Anchor point="CENTER" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer level="OVERLAY">
-        <Texture parentKey="tagIcon" nonBlocking="true" setAllPoints="false">
-          <Size x="12" y="12" />
-          <Anchors>
-            <Anchor point="BOTTOMRIGHT" x="1" y="-1" />
-          </Anchors>
-        </Texture>
-      </Layer>
-      <Layer level="HIGHLIGHT">
-        <Texture parentKey="highlight" alphaMode="ADD" alpha="1" file="Interface\UNITPOWERBARALT\Generic1Target_Circular_Frame" desaturated="true">
-          <Anchors>
-            <Anchor point="BOTTOMLEFT" />
-            <Anchor point="TOPRIGHT" />
-          </Anchors>
-        </Texture>
-
-      </Layer>
-    </Layers>
-    <Scripts>
-      <OnLoad method="OnLoad" />
-      <OnEvent method="OnEvent" />
-      <OnUpdate method="OnUpdate" />
-      <OnShow method="OnShow" />
-      <OnHide method="OnHide" />
-      <OnMouseDown method="OnMouseDown" />
-      <OnEnter method="OnEnter" />
-      <OnLeave method="OnLeave" />
-    </Scripts>
-    <Frames>
-      <Frame parentKey="Overlay" name="$parentOverlay" setAllPoints="true" hidden="true">
-        <!--
-        <Scripts>
-          <OnShow>
-            local out = debugstack(3,3,1)
-            out = out:gsub("Interface%\\AddOns\\", "|cFFFF00FF\\|r")
-            print('POI', self:GetName().. ':OnShow()\n' .. out:gsub("Interface%\\", "|cFF00FFFF\\|r"))
-          </OnShow>
-          <OnHide>
-            local out = debugstack(3,3,1)
-            out = out:gsub("Interface%\\AddOns\\", "|cFFFF00FF\\|r")
-            print('POI', self:GetName().. ':OnHide()\n' .. out:gsub("Interface%\\", "|cFF00FFFF\\|r"))
-          </OnHide>
-        </Scripts>
-        -->
-        <Layers>
-          <Layer level="OVERLAY">
-            <FontString inherits="WorldPlanNumberFontThin" parentKey="count">
-              <Anchors>
-                <Anchor point="BOTTOM" x="0" y="0" />
-              </Anchors>
-            </FontString>
-            <FontString inherits="WorldPlanNumberFont" parentKey="timeLabel">
-              <Anchors>
-                <Anchor point="TOP" x="0" y="0" />
-              </Anchors>
-            </FontString>
-            <FontString inherits="WorldPlanNumberFontThin" parentKey="Description">
-              <Anchors>
-                <Anchor point="TOP" relativePoint="BOTTOM" relativeKey="$parent.count" x="0" y="0" />
-              </Anchors>
-            </FontString>
-          </Layer>
-        </Layers>
-      </Frame>
-    </Frames>
-  </Button>
 
   <Frame name="WorldPlan" mixin="WorldPlanCore" parent="UIParent">
     <KeyValues>
--- a/WorldQuests.lua	Sat Jun 03 17:20:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,657 +0,0 @@
--- WorldPlan
--- WorldQuests.lua
--- Created: 11/2/2016 3:40 PM
--- %file-revision%
-
-local print = DEVIAN_WORKSPACE and function(...) _G.print('WorldQuests', ...) end or nop
-local rprint = DEVIAN_WORKSPACE and function(...) _G.print('WQRefresh', ...) end or nop
-local qprint = DEVIAN_WORKSPACE and function(...) _G.print('POI', ...) end or nop
-local wprint = DEVIAN_WORKSPACE and function(...) _G.print('WP', ...) end or nop
-local mprint = DEVIAN_WORKSPACE and function(...) _G.print('Canvas', ...) end or nop
-local _, db = ...
-local Module = WorldPlanQuestsMixin
-
-local _G = _G
-local type, tostring, tonumber, pairs, ipairs = type, tostring, tonumber, pairs, ipairs
-local MC_GetNumZones, MC_GetZoneInfo = C_MapCanvas.GetNumZones, C_MapCanvas.GetZoneInfo
-local TQ_GetQuestsForPlayerByMapID = C_TaskQuest.GetQuestsForPlayerByMapID -- This function is not yet documented
-local TQ_GetQuestZoneID = C_TaskQuest.GetQuestZoneID
-local TQ_IsActive = C_TaskQuest.IsActive
-local TQ_RequestPreloadRewardData = C_TaskQuest.RequestPreloadRewardData
-local pairs, ipairs, tinsert, tremove, wipe = pairs, ipairs, tinsert, tremove, table.wipe
-local GetTaskInfo, GetTasksTable, HaveQuestData = GetTaskInfo, GetTasksTable, HaveQuestData
-local GetTime = GetTime
-local SpellCanTargetQuest, IsQuestIDValidSpellTarget = SpellCanTargetQuest, IsQuestIDValidSpellTarget
-local tonumber, abs = tonumber, math.abs
-local GetQuestLogRewardInfo = GetQuestLogRewardInfo
-local GetCurrentMapAreaID, GetMapInfo, GetMapNameByID = GetCurrentMapAreaID, GetMapInfo, GetMapNameByID
-local GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete = GetQuestBountyInfoForMapID, GetQuestLogTitle, GetQuestLogIndexByID, IsQuestComplete
-local HaveQuestRewardData = HaveQuestRewardData
-local TQ_GetQuestLocation = C_TaskQuest.GetQuestLocation
-local InCombatLockdown, hooksecurefunc = InCombatLockdown, hooksecurefunc
-
-local ToggleButton = {}
-local BROKEN_ISLES_ID, DALARAN_ID, AZSUNA_ID, VALSHARAH_ID, HIGHMOUNTAIN_ID, STORMHEIM_ID, SURAMAR_ID, EOA_ID = 1007, 1014, 1015,1018, 1024, 1017, 1033, 1096
-local WORLD_QUEST_MAPS = { [DALARAN_ID] = 'Dalaran70',  [AZSUNA_ID] = 'Azsuna',  [VALSHARAH_ID] = "Val'sharah",
-  [HIGHMOUNTAIN_ID] = 'Highmountain', [STORMHEIM_ID] = 'Stormheim',  [SURAMAR_ID] = 'Suramar',  [EOA_ID] = 'EyeOfAszhara', }
-
-local REWARD_CASH = WORLD_QUEST_REWARD_TYPE_FLAG_GOLD
-local REWARD_ARTIFACT_POWER = WORLD_QUEST_REWARD_TYPE_FLAG_ARTIFACT_POWER
-local REWARD_GEAR = WORLD_QUEST_REWARD_TYPE_FLAG_EQUIPMENT
-local REWARD_CURRENCY = WORLD_QUEST_REWARD_TYPE_FLAG_ORDER_RESOURCES
-local REWARD_REAGENT = WORLD_QUEST_REWARD_TYPE_FLAG_MATERIALS
-local SCALE_FACTORS = { 0.25, 0.7, 1 }
-
-local BountyBoard = WorldMapFrame.UIElementsFrame.BountyBoard
-local ActionButton = WorldMapFrame.UIElementsFrame.ActionButton
-local defaults = {}
-local completedQuests = {}
-
-local continentScanned
-local layoutDirty = true
-local bountiesDirty = true
-local artifactPowerDirty = true
-local hooksDirty = true
-local currentScale = WorldMapDetailFrame:GetScale()
-local canTargetQuests
-local isDataLoaded = true
-local artifactKnowledgeLevel
-local superTrackedQuestID
-local lastRefresh
-local refreshReason
-
-local bountyQuests = {}
-local bountyInfo = {}
-local bountyDisplayLocation, bountyLockedQuestID, selectedBountyIndex, selectedBountyQuestID
-
-local totalPins = 0
-local numShown = 0
-local numLoaded = 0
-local numOverlays = 1
-local scaleConstant = 1
-local pinBaseIndex = 1550
-local overlayBaseIndex = 1600
-
-local artifactKnowldegeSpells = {
-  [207856] = true,
-  [209203] = true,
-  [209204] = true,
-  [209205] = true,
-  [209206] = true,
-  [209207] = true,
-  [209208] = true,
-  [209209] = true,
-  [209210] = true,
-  [209211] = true,
-  [209212] = true,
-  [219978] = true,
-  [227852] = true,
-  [236477] = true,
-  [236489] = true,
-  [236302] = true,
-  [236488] = true,
-  [236490] = true,
-  [240475] = true,
-  [243176] = true,
-  [243177] = true,
-  [243178] = true,
-  [243182] = true,
-  [243183] = true,
-  [243187] = true,
-  [245133] = true,
-}
-
---%debug%
-local SetTimedCallbackForAllPins = function(seconds, callback)
-  C_Timer.After(seconds, function()
-    for id, pin in pairs(WorldPlanQuests.QuestsByID) do
-      callback(pin)
-    end
-  end)
-end
-
-function Module:OnLoad()
-  --print('|cFFFF4400'..self:GetName()..':OnLoad()')
-
-  self:SetParent(WorldMapFrame.UIElementsFrame)
-  WorldPlan:AddHandler(self, defaults)
-
-  for areaID, fileName in pairs(WORLD_QUEST_MAPS) do
-    db.QuestsByZone[areaID] = {}
-  end
-
-  -- WORLD_MAP_UPDATE and PLAYER_ENTERING_WORLD are passed down from a higher level
-  self:RegisterEvent('WORLD_QUEST_COMPLETED_BY_SPELL')
-  self:RegisterEvent('SUPER_TRACKED_QUEST_CHANGED')
-  self:RegisterEvent('SKILL_LINES_CHANGED')
-  self:RegisterEvent('ARTIFACT_UPDATE')
-  self:RegisterEvent('QUEST_LOG_UPDATE')
-  self:RegisterEvent('UNIT_SPELLCAST_STOP')
-end
-
-function Module:OnEvent (event, ...)
-  print('|cFFFFFF00OnEvent() '..event..'|r', GetTime(), ...)
-  if (event == 'QUEST_LOG_UPDATE') then
-    self:UpdateBounties(event)
-  elseif event == 'WORLD_QUEST_COMPLETED_BY_SPELL' then
-    local questID = ...
-    if questID and db.QuestsByID[questID] then
-      completedQuests[questID] = true
-      db.QuestsByID[questID]:Release()
-    end
-    self:Refresh(event)
-  elseif event == 'SKILL_LINES_CHANGED' or event == 'CURRENT_SPELL_CAST_CHANGED' then
-    self:Refresh(event)
-  elseif event == 'ARTIFACT_UPDATE' then
-    self:UpdateArtifactPower()
-  elseif event == 'MODIFIER_STATE_CHANGED' then
-    self:UpdateModifierState()
-  elseif event == 'SUPER_TRACKED_QUEST_CHANGED' then
-    if superTrackedQuestID and db.QuestsByID[superTrackedQuestID] then
-      db.QuestsByID[superTrackedQuestID].isStale = true
-    end
-    local newID = GetSuperTrackedQuestID()
-    if newID and db.QuestsByID[newID] then
-      db.QuestsByID[newID].isStale = true
-    end
-  elseif event == 'UNIT_SPELLCAST_STOP' then
-    local name, _, _, _, spellID = ...
-    if artifactKnowldegeSpells[spellID] then
-      db.log('AK spellcast ended ' .. tostring(name) .. ' ('.. tostring(spellID)..')')
-      self:UpdateArtifactPower()
-    end
-  end
-end
-
-function Module:OnUpdate(sinceLast)
-  if WorldPlanData.DebugEnabled then
-    if self.refreshBenchMarkTicker then
-      --print(self.refreshBenchMarkTicker)
-      self.refreshBenchMarkTicker =   self.refreshBenchMarkTicker - 1
-
-      if self.refreshBenchMarkTicker == 0 then
-
-        self.refreshTime = floor((GetTime() - self.refreshBenchMark) * 1000)
-        self.debugMessage:SetText(self.refreshTime)
-        self.refreshBenchMarkTicker = nil
-      end
-    else
-      self.refreshBenchMark = GetTime()
-    end
-  end
-
-  if self.filtersDirty or self.isStale then
-    self:Refresh()
-  end
-
-  if #db.UpdatedPins >= 1 then
-    --print('|cFF00FF88pending update', #db.UpdatedPins)
-    self:UpdateNext()
-  end
-end
-
-local callbacks = {}
-callbacks.ClickWorldMapActionButton = function(WorldQuests)
-  WorldQuests:Refresh('CLICK_MAP_ACTION_BUTTON')
-end
-callbacks.WorldMap_UpdateQuestBonusObjectives = function(WorldQuests)
-  WorldQuests:UpdateTaskPOIs()
-end
-callbacks.WorldMapFrame_UpdateMap = function(WorldQuests)
-  WorldQuests:RefreshIfChanged('WMF_UPDATE')
-end
-callbacks.WorldMapScrollFrame_ReanchorQuestPOIs = function (WorldQuests)
-  WorldQuests:RefreshIfChanged('WMF_REANCHOR')
-end
-
-callbacks[BountyBoard] = {}
-callbacks[BountyBoard].SetSelectedBountyIndex = function(WorldQuests)
-  WorldQuests:UpdateBounties('BOUNTY_SELECTED')
-  for questID, pin in pairs(db.QuestsByID) do
-    pin.checkCriteria = true
-    pin:Refresh()
-  end
-end
-
-callbacks[ActionButton] = {}
-callbacks[ActionButton].UpdateCastingState = function(WorldQuests)
-  for questID, pin in pairs(db.QuestsByID) do
-    pin.checkCursor = true
-    pin:Refresh()
-  end
-end
-
-callbacks.UseWorldMapActionButtonSpellOnQuest = function(questID)
-  local pin = db.QuestsByID[questID]
-  -- calling this implies that the pin is used in some way
-  if pin then
-    db.log(pin.title ..  ' completed by spell?', IsQuestComplete(pin.questID))
-    pin:OnFilters()
-    pin.isStale = true
-  end
-end
-
-function Module:SetupCallbacks()
-  if InCombatLockdown() then
-    return true
-  end
-  print('SetupCallbacks()')
-  for target, arg in pairs(callbacks) do
-    --print(type(target))
-    if type(target) == 'table' then
-      local callerName = target:GetName() or tostring(target)
-      for name, method  in pairs(arg) do
-        --print(callerName, arg)
-        hooksecurefunc(target, name, function(...)
-          self:OnSecureHook(callerName .. '.' .. name, method, ...)
-        end)
-      end
-    else
-      hooksecurefunc(target, function(...)
-        self:OnSecureHook(target, arg, ...)
-      end)
-    end
-  end
-end
-
-function Module:Setup()
-  --print('|cFFFF4400'..self:GetName()..':Setup()')
-  for mapID, mapName in pairs(WORLD_QUEST_MAPS) do
-    db.QuestsByZone[mapID] = {}
-  end
-
-  hooksDirty = self:SetupCallbacks()
-
-  self:SetAllPoints(WorldMapFrame.UIElementsFrame)
-  self:UpdateArtifactPower()
-  self:UpdateBounties('SETUP')
-  self:Show()
-end
-
-function Module:OnMapInfo(isBrokenIsle, isZoomedOut, mapAreaID, isNewMap, isMapOpen)
-  if isNewMap or self.isStale then
-    print('|cFF0088FFOnMapInfo()|r, mapAreaID =', mapAreaID,'visible =', isMapOpen, 'changed =', isNewMap)
-    layoutDirty = true
-    self:Refresh('WORLD_MAP_CHANGED')
-  end
-end
-
-function Module:OnConfigUpdate()
-  --print('|cFFFFFF00OnConfigUpdate()|r')
-  if db.Config.FadeWhileGrouped then
-    db.PinAlpha = 0.15
-  else
-    db.PinAlpha = 1
-  end
-
-  if not db.Config.EnablePins then
-    for _, pin in pairs(db.QuestsByID) do
-      pin:SetShown(false)
-    end
-  end
-end
-
-function Module:OnSecureHook(callbackName, func, ...)
-  print('|cFFFF4400'..callbackName..'|r', ...)
-  func(self, ...)
-end
-
-function Module:UpdateModifierState()
-
-end
-
-function Module:UpdateTaskPOIs()
-  canTargetQuests = SpellCanTargetQuest()
-  for i = 1, NUM_WORLDMAP_TASK_POIS do
-    local poiFrame = _G['WorldMapFrameTaskPOI'..i]
-    if poiFrame and poiFrame.worldQuest then
-      local pin = db.QuestsByID[poiFrame.questID]
-      if pin and pin.used and canTargetQuests and IsQuestIDValidSpellTarget(pin.questID) then
-        poiFrame:Show()
-      else
-        poiFrame:Hide()
-      end
-    end
-  end
-end
--- re-anchors and scales pins that have had either of these changed due to data loading delays
-function Module:UpdateNext()
-  --print('|cFF00FF88UpdateNext()')
-  local pin = tremove(db.UpdatedPins)
-  pin:OnFilters()
-
-  local scaleFactor = SCALE_FACTORS[(pin.dataLoaded and not pin.filtered) and scaleConstant or 1]
-  --print(pin.title, pin.dataLoaded  and not pin.filtered, scaleFactor)
-  if pin.used then
-    pin:SetShown(true)
-    pin:SetAnchor(nil, pin.x, pin.y, self.hostWidth, self.hostHeight, scaleFactor)
-    pin:Refresh()
-  else
-    print('|cFFFF4400flagging queued pin that got hidden:', pin.title)
-    pin.isStale = true
-  end
-end
-
-function Module:UpdateBounties(...)
-  bountiesDirty = nil
-  print('|cFF00FF88BountyInfo()|r', ...)
-  wipe(db.BountiesByFactionID)
-  wipe(db.BountiesByQuestID)
-
-  db.selectedBounty = nil
-  selectedBountyIndex = BountyBoard:GetSelectedBountyIndex()
-  db.Bounties, bountyDisplayLocation, bountyLockedQuestID = GetQuestBountyInfoForMapID(db.currentMapID, db.Bounties)
-  local numBounties = 0
-  for index, info in ipairs(db.Bounties) do
-      numBounties = numBounties + 1
-      info.index = index
-      info.complete =  IsQuestComplete(info.questID)
-      if not info.complete then
-        db.BountiesByFactionID[info.factionID] = info
-        db.BountiesByQuestID[info.questID] = info
-        if index == selectedBountyIndex then
-          db.selectedBounty = info
-          selectedBountyQuestID = info.questID
-        end
-        print(' ', index, info.factionID, GetQuestLogTitle(GetQuestLogIndexByID(info.questID)), info.complete, (index == selectedBountyIndex) and 'SELECTED' or '')
-      end
-  end
-end
-
--- check current artifact knowledge and update pins accordingly
-function Module:UpdateArtifactPower(overrideLevel)
-  if InCombatLockdown() then
-    artifactPowerDirty = true
-    return
-  end
-
-  print('|cFF00FF88UpdateArtifactPower()|r')
-  local _, akLevel = GetCurrencyInfo(1171)
-  if overrideLevel then
-    akLevel = overrideLevel
-  end
-
-  --db.print('current AK', akLevel)
-  if akLevel and (akLevel ~= artifactKnowledgeLevel) or (not artifactKnowledgeLevel) then
-    --print('new ak level', akLevel)
-    db.log('AK update ' .. tostring(artifactKnowledgeLevel) .. ' to '.. tostring(akLevel))
-    for _, pin in pairs(db.QuestsByID) do
-      if (pin.rewardType == REWARD_ARTIFACT_POWER) then
-        print(pin.title, pin.itemNumber)
-        local newAP = pin:UpdateArtifactPower()
-        if newAP then
-          pin.itemNumber = newAP
-          print(newAP)
-        else
-          pin.dataLoaded = nil
-        end
-        pin.isStale = true
-      end
-    end
-    artifactKnowledgeLevel = akLevel
-  end
-  artifactPowerDirty = nil
-end
-
-local msg = '|cFF00FF88WorldQuests:Refresh()|r|cFF00FFFF'
-function Module:Refresh(...)
-
-  if hooksDirty then
-    hooksDirty = self:SetupCallbacks()
-  end
-
-
-  if not self:IsVisible() then
-    print('|cFFFF4400Refresh()|r', ...)
-    return
-  else
-    if lastRefresh == GetTime() then
-      print('|cFFFF4400multiple refreshes tried')
-    end
-    lastRefresh = GetTime()
-    print(msg, lastRefresh, ...)
-  end
-
-
-  if bountiesDirty then
-    self:UpdateBounties()
-  end
-
-  if not db.Config.EnablePins then
-    numShown = 0
-    self.refreshBenchMark = GetTime()
-    self.refreshBenchMarkTicker = 2
-    print('starting bench', self.refreshBenchMark)
-    return
-  end
-
-  scaleConstant = db.isContinentMap and 2 or 3
-  canTargetQuests = SpellCanTargetQuest()
-
-  for index, pin in pairs(db.QuestsByID) do
-    pin.used = nil
-  end
-
-  self:UpdateAnchors(...)
-
-  if artifactPowerDirty and not InCombatLockdown() then
-    self:UpdateArtifactPower()
-  end
-  -- calculate quests shown
-  numShown = 0
-  numLoaded = 0
-  for questID, pin in pairs(db.QuestsByID) do
-    local oV = pin:IsShown()
-    if pin.used then
-      print('show', pin.title)
-      pin.throttle = 1
-      pin:SetShown(true)
-      numShown = numShown + 1
-      if pin.dataLoaded then
-        numLoaded = numLoaded + 1
-      end
-
-      pin.checkCriteria = true
-      pin.checkFilters = true
-      pin:Refresh('WORLDMAP_REFRESH ' .. GetTime())
-
-    else
-      if pin:IsShown() then
-        print('|cFFFF4400need to remove', pin.title)
-
-      end
-
-      pin.hideReason = "Not used in map area " .. (db.currentMapID)
-      pin:SetShown(false)
-    end
-
-  end
-
-
---
-  self.refreshBenchMark = GetTime()
-  self.refreshBenchMarkTicker = 2
-  print('starting bench', self.refreshBenchMark)
-
---
-
-  layoutDirty = nil
-  self.isStale = nil
-  self.sizesDirty = nil
-  self.isZoomDirty = nil
-
-  if WorldPlanSummary then
-    WorldPlanSummary.isStale = true
-  end
-
-end
-
-function Module:RefreshIfChanged(event)
-  local scaleCheck = WorldMapDetailFrame:GetScale()
-  refreshReason = nil
-  if scaleCheck ~= currentScale then
-    refreshReason = 'map scale updated'
-    currentScale = scaleCheck
-    layoutDirty = true
-  elseif self.isStale or layoutDirty then
-    refreshReason = 'layout is marked dirty'
-  end
-  if not refreshReason then
-    return
-  end
-
-  if self:IsVisible() then
-    print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
-    self:Refresh(event)
-  else
-    print('|cFF00FFFFRefreshIfChanged()|r', refreshReason)
-    self.isStale = true
-  end
-end
-
--- Walks the current map tree and fires updates as needed
-function Module:UpdateAnchors (event)
-  wipe(self.UsedPositions)
-  local hostWidth, hostHeight = WorldMapPOIFrame:GetSize()
-
-  if (hostWidth ~= self.hostWidth) or (hostHeight ~= self.hostHeight) then
-    self.hostWidth, self.hostHeight = hostWidth, hostHeight
-    layoutDirty = true
-  end
-
-  print('|cFF00FF00UpdateAnchors()', event)
-  local mapFileName, textureHeight, textureWidth, isMicroDungeon, microDungeonMapName = GetMapInfo()
-  if isMicroDungeon then
-    return
-  end
-
-  isDataLoaded = true
-  local taskInfo = TQ_GetQuestsForPlayerByMapID(db.currentMapID)
-  if taskInfo then
-    self:UpdateQuestsForMap(taskInfo, db.currentMapID)
-  end
-  local numZones = MC_GetNumZones(db.currentMapID)
-  if numZones then
-    for i = 1, numZones do
-      local mapAreaID = MC_GetZoneInfo(db.currentMapID, i)
-      local taskInfo = TQ_GetQuestsForPlayerByMapID(mapAreaID, db.currentMapID)
-
-      db.QuestsByZone[mapAreaID] = db.QuestsByZone[mapAreaID] or {}
-
-      if taskInfo then
-        self:UpdateQuestsForMap(taskInfo, mapAreaID)
-      end
-    end
-  end
-end
-
--- Attempt to display the pins for quests in taskInfo
-function Module:UpdateQuestsForMap(taskInfo, mapID)
-  print('|cFF00FF00UpdateQuestsForMap()|r', GetMapNameByID(mapID), GetMapNameByID(db.currentMapID), layoutDirty)
-  if db.QuestsByZone[mapID] then
-    wipe(db.QuestsByZone[mapID])
-  elseif db.isBrokenIsle then
-    continentScanned = true
-  end
-  db.PinStrata = WorldMapFrame_InWindowedMode() and 'HIGH' or 'FULLSCREEN'
-  print('layoutDirty =',layoutDirty)
-
-  for index, info in pairs(taskInfo) do
-    local questID, x, y = info.questId, info.x, info.y
-    local pin = self:AcquirePin(info)
-    if pin then
-      if pin.canShow then
-        pin.used = true
-        print('using', pin.title, (pin.owningFrame ~= WorldMapFrame))
-        if layoutDirty or (pin.owningFrame ~= WorldMapFrame) then
-          local scaleFactor = SCALE_FACTORS[(not pin.filtered and scaleConstant) or 1]
-          pin.owningFrame = WorldMapFrame
-          pin:SetAnchor(WorldMapPOIFrame, x, y, self.hostWidth, self.hostHeight, scaleFactor)
-
-        end
-        if db.QuestsByZone[mapID] then
-          db.QuestsByZone[mapID][questID] = pin
-        end
-      else
-        print('|cFFFF4400discarding|r', pin.title)
-      end
-    end
-  end
-end
-
--- locates or creates a corresponding pin frame for the provided TaskInfo data
-function Module:AcquirePin (info)
-  local questID = info.questId
-  if not (questID and QuestUtils_IsQuestWorldQuest(questID)) then
-    return nil
-  end
-  local pin = db.QuestsByID[questID]
-  -- check to avoid creating unnecessary frames
-  if IsQuestComplete(questID) or completedQuests[questID] then
-    completedQuests[questID] = true
-    if pin then
-      pin:Release()
-    end
-    return nil
-  end
-
-  if not pin then
-    local numFree = #db.FreePins
-    if numFree >= 1 then
-      pin = tremove(db.FreePins, numFree)
-      print('|cFF00FF00Acquire()|r Re-using', pin:GetName())
-    else
-      totalPins = totalPins + 1
-      local name = 'WorldPlanQuestMarker' .. numOverlays
-      print('|cFF00FF00Acquire()|r Creating', name)
-      pin = CreateFrame('Frame', name, WorldMapPOIFrame, 'WorldPlanQuestPin')
-
-      pin:SetID(totalPins)
-      numOverlays = numOverlays + 1
-      --pin.iconBorder:SetVertexColor(0,0,0,1)
-    end
-    pin.questID = questID
-    pin.throttle = pin.updateRate
-    pin.currentWidth = nil
-
-    db.QuestsByID[questID] = pin
-    tinsert(db.UsedPins, pin)
-  end
-
-  if info then
-    pin.inProgress = info.inProgress
-    pin.floor = info.floor
-    pin.numObjectives = info.numObjectives or 0
-    if info.x and info.y then
-      if (info.x ~= pin.x) or (info.y ~= pin.y) then
-        pin.isStale = true
-        --rprint('|cFFFF4400SetCoords|r', info.x, info.y)
-      end
-    end
-  end
-
-  pin.x = info.x or pin.x
-  pin.y = info.y or pin.y
-
-  if not HaveQuestRewardData(questID) then
-    TQ_RequestPreloadRewardData(questID);
-  end
-
-  if (not pin.dataLoaded) then
-    local dataLoaded = pin:GetData()
-    if dataLoaded then
-      WorldPlan.dataFlush = true
-    else
-      isDataLoaded = false
-    end
-  end
-
-  pin:OnFilters()
-  pin.isActive = TQ_IsActive(questID)
-  --rprint(pin:GetID(), pin.filtered, pin.used)
-  return pin
-end
-
-function Module:Debug(...)
-  print(...)
-end
\ No newline at end of file
--- a/WorldQuests.xml	Sat Jun 03 17:20:14 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
-..\FrameXML\UI.xsd">
-  <Script file="WorldQuests.lua" />
-
-
-  <Frame name="$parentQuests" mixin="WorldPlanQuestsMixin" parent="WorldPlan">
-
-    <Scripts>
-      <OnLoad method="OnLoad" />
-      <OnEvent method="OnEvent" />
-      <OnUpdate method="OnUpdate" />
-      <OnShow method="OnShow" />
-    </Scripts>
-    <Layers>
-
-      <Layer level="OVERLAY">
-        <FontString parentKey="debugMessage" inherits="GameFontNormal">
-          <Anchors>
-            <Anchor point="TOP" x="0" y="-8" />
-
-          </Anchors>
-        </FontString>
-      </Layer>
-    </Layers>
-
-  </Frame>
-
-  </Ui>
\ No newline at end of file