Root cause: gearDetectSlot used substring matching. The Body keyword
'gi' (for gi/jacket) appears inside the word 'leggings' (l-e-g-g-i-n-g-s),
so EVERY leggings item was classified as Body:
- Legs slot showed '(no data)' — its equipped item was mis-detected
- Body slot showed leggings items as top candidates (176 score)
Fix: word-boundary regex match (\bgi\b) so 'gi' only matches as a
standalone word. Also protects against 'cap' in 'capacity' etc.
- Added filter dropdowns to the panel: Armor (Light/Heavy/Cloth/All)
and Weapon (2H/Estoc/Longsword/Great Mace/Club/Axe/Scythe).
Persisted in localStorage. Default: Light armor, 2H weapons.
Filters exclude non-matching items from armory/buy candidates
(equipped item always shown regardless).
- Fixed gearPlayerLevel(): now reads STATE.level first (battle
parser caches it), then the hv-cfg-btn label (Lv195), then
level_readout. Previously fell back to 155 when the level readout
used CSS fonts — this excluded the Lv171 equipped Estoc from
candidates, causing 'vs ?' in the upgrade line.
- Upgrade line now always shows a real number (scores equipped
directly if it missed candidates).
Also scrapes correctly on equipment pages: clicking Analyze there
refreshes equipped slots from dynjs_equip store.
- enhanceGearAnalysis now also fires on Character > Equipment pages
(id=eqsb), not just Bazaar (equiplist)
- On equipment pages only the Analyze button shows (Rescan hidden —
no store/inventory data to rescan there, but the localStorage DB
is still accessible for the comparison)
- Clicking Analyze on ss=eq rescrapes equipped slots + opens panel
with stored/purchasable comparisons from localStorage
Root cause: both buttons were inserted inside the armory <form>.
HTML <button> defaults to type=submit — clicking submitted the form,
the page reloaded, and the panel (which renders 300ms later) was
destroyed. The split-second flash was the panel before the reload.
Fix: type='button' on both buttons. Panel now stays up.
- Gear panel: wrapped autoScrapeGear() and buildGearPanel() in try/catch.
An exception during scrape (new store-scan loop) killed the onclick
handler before the panel was scheduled — panel never appeared.
- Removed renderProgressPanel() call (Daily Activities window) per user
request — not used.
New src/gear-analysis.js — ports analyze_gear.py scoring to JS:
- gearScoreArmor() / gearScoreWeapon() — same weights as Python
- gearDetectSlot() / gearIsTwoHandWeapon() / gearUsable()
- analyzeGear() — scores equipped vs armory vs buy per slot
UI on Armory pages (above equiplist):
- 🔍 Analyze Gear — rescrapes current page, shows per-slot panel
with top 4 candidates, scores, prices, and upgrade highlights
- 🔄 Clear Buy + Rescan — wipes stale buy data, rescrapes, analyzes
scrapeBuyPage() now also scavenges the full dynjs_eqstore for items
not visible in the current filter tab — one Purchase visit captures
the entire store (429+ items), no need to click through tabs.
Console API: HV.analyzeGear(), HV.gearPanel(), HV.clearBuy()