import { esc, renderThumbHtml } from "./dom.js"; import { tokenizeQuery, matchesAllTokens, displaySku, keySkuForRow, parsePriceToNumber, } from "./sku.js"; import { loadIndex, loadRecent } from "./state.js"; import { aggregateBySku } from "./catalog.js"; import { loadSkuRules } from "./mapping.js"; function normStoreLabel(s) { return String(s || "").trim().toLowerCase(); } function abbrevStoreLabel(s) { const t = String(s || "").trim(); if (!t) return ""; return t.split(/\s+/)[0] || t; } function readLinkHrefForSkuInStore(listingsLive, canonSku, storeLabelNorm) { // Prefer the most recent-ish url if multiple exist; stable enough for viz. let bestUrl = ""; let bestScore = -1; function scoreUrl(u) { if (!u) return -1; let s = u.length; if (/\bproduct\/\d+\//.test(u)) s += 50; if (/[a-z0-9-]{8,}/i.test(u)) s += 10; return s; } for (const r of listingsLive) { if (!r || r.removed) continue; const store = normStoreLabel(r.storeLabel || r.store || ""); if (store !== storeLabelNorm) continue; const skuKey = String( rulesCache?.canonicalSku(keySkuForRow(r)) || keySkuForRow(r) ); if (skuKey !== canonSku) continue; const u = String(r.url || "").trim(); const sc = scoreUrl(u); if (sc > bestScore) { bestScore = sc; bestUrl = u; } else if (sc === bestScore && u && bestUrl && u < bestUrl) { bestUrl = u; } } return bestUrl; } // small module-level cache so we can reuse in readLinkHrefForSkuInStore let rulesCache = null; export async function renderStore($app, storeLabelRaw) { const storeLabel = String(storeLabelRaw || "").trim(); const storeLabelShort = abbrevStoreLabel(storeLabel) || (storeLabel ? storeLabel : "Store"); $app.innerHTML = `