antidogg

AntiDogg NFT Rarity display

// ==UserScript==
// @name         antidogg
// @version      0.1
// @description  AntiDogg NFT Rarity display
// @author       balldog
// @match        https://dexie.space/offers/col1lqdkghxfwj7v0ajka0ww4q5ljkzjh8xgm28h7e3s4sh03smrmxxsn8qcpw/*
// @icon        https://assets.spacescan.io/xch/img/col/icon/th/col1lqdkghxfwj7v0ajka0ww4q5ljkzjh8xgm28h7e3s4sh03smrmxxsn8qcpw.webp
// @namespace https://greasyfork.org/users/983945
// ==/UserScript==

console.debug('BallDog Rarity running')

// Utilities
// ==================================================

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms))
}

async function $(selector, { intervalMs=50, root=document }={}) {
  while(true) {
    const element = root.querySelector(selector)
    if (element) {
      return element;
    }
    await sleep(intervalMs)
  }
}

function safe$(selector, { root=document }={}) {
  const element = root.querySelector(selector)
  if (element) { return element; }
  else { return {}; }
}

async function $$(selector, { intervalMs=50, root=document }={}) {
  while(true) {
    const element = root.querySelectorAll(selector)
    if (element.length > 0) {
      return [...element];
    }
    await sleep(intervalMs)
  }
}

function createEl(tag, { on, className, textContent, style, ...attributes }={}) {
  const el = document.createElement(tag)
  for (const [attr, val] of Object.entries(attributes)) {
    el.setAttribute(attr, val)
  }
  if (className) { el.className = className; }
  if (textContent) { el.textContent = textContent; }
  if (style) { el.style = style; }
  if (on) {
    for (const [eventName, listener] of Object.entries(on)) {
      el.addEventListener(eventName, listener)
    }
  }
  return el
}


// Main
// ==================================================

function rarityGauge(rarity) {
  const gauge = createEl('div', {
    className: 'rarity-gauge',
    style: 'display: flex; flex-flow: row nowrap; align-items: flex-end; height: 20px;'
  })
  const LEVELS = [2078,1000,500,200,100,50,0]
  const LEVEL_COLORS = [,'grey','blue','green','#d0d056','orange','red']
  const NEUTRAL_COLOR = ['rgba(200,200,200,0.1)']
  const level = LEVELS.findIndex(max => rarity > max)
  const levelColor = LEVEL_COLORS[level]
  const levelStyle = c => [
    `background: ${c >= level ? NEUTRAL_COLOR : levelColor}`,
    `border-radius: 2px`,
    `width: 5px`,
    `margin: 0.5px`,
    `height: ${Math.ceil(c / LEVELS.length * 60 + 40)}%`,
  ].join('; ')
  gauge.innerHTML = `
    ${LEVELS.slice(0, LEVELS.length - 2).map((l, i) => (`
      <div style="${levelStyle(i + 1)}"></div>
    `)).join('\n')}
  `
  return gauge;
}

function getRarity(name) {
  const [ ,num] = name.match(/#([0-9]+)/) || []
  if (num === undefined) {
    console.debug(`Couldn't find rarity for "${name}".`)
    return null;
  }
  const rarity = rarityRanking.indexOf(num)+1
  if (rarity < 0) {
    console.debug(`Couldn't find rarity for "${name}".`)
    return null;
  }
  return rarity
}

async function main() {
  console.debug('main()')
  const nftsTable = await $('table.min-w-full')
  console.debug('nftsTable:', nftsTable)

  async function addRarityToRows() {
    if (!nftsTable.querySelector('.rarity-th')) {
      const headerCols = await $$('thead th', { root: nftsTable })
      const rarityTh = createEl('th', {
        textContent: 'Rarity',
        className: 'rarity-th w-[80px] py-2 text-left text-xs font-medium tracking-wider text-gray-500'
      })
      headerCols[0].insertAdjacentElement('afterend', rarityTh)

    }

    const nftRows = await $$('tbody tr', { root: nftsTable })
    nftRows.forEach(row => {
      if (row.querySelector('.rarity')) { return; }

      const name = safe$('.truncate.text-xs.tracking-tight', { root: row }).textContent

      const rarityTd = createEl('td', {
        className: 'rarity whitespace-nowrap py-2.5 px-2.5 text-xxs text-gray-400',
      })
      const rarity = getRarity(name)

      if (typeof rarity === 'number') {
        const rarityStr = rarity.toString()
        rarityTd.appendChild(rarityGauge(rarity))
        rarityTd.appendChild(document.createTextNode(rarityStr))
      }

      row.firstChild.insertAdjacentElement('afterend', rarityTd)
    })
  }

  async function handleAddRarityBtnClick() {
    if (window.addingRarity) {
      window.addingRarity()
    } else {

      const cb = addRarityToRows

      cb();

      const mutationObserver = new MutationObserver(() => {
        cb();
      });
      mutationObserver.observe(nftsTable, {
        childList: true,
        subtree: true,
      });

      // Cleanup
      window.addingRarity = () => {
        mutationObserver.disconnect();

        $$('.rarity').then(tds => tds.forEach(td => {
          td.parentElement.removeChild(td)
        }))
        $('.rarity-th').then(th => th.parentElement.removeChild(th))

        window.addingRarity = null;
      }
    }
  }

  const controlsContainer = createEl('div', {
    className: 'relative inline-block text-left',
  })
  const addRarityBtn = createEl('button', {
    className: 'inline-flex w-full justify-center rounded-md border border-gray-300 bg-white py-1.5 px-3 text-xs text-sm font-medium hover:bg-gray-50 focus:outline-none !py-1 mono',
    textContent: 'Toggle rarity',
    on: {
      click: handleAddRarityBtnClick,
    }
  })

  controlsContainer.appendChild(addRarityBtn)

  document.querySelector('.flex-1.text-sm').parentElement.appendChild(controlsContainer)

  handleAddRarityBtnClick()
}

window.addEventListener("load", main, false);

const rarityRanking = ["439","2051","942","1148","873","1318","1782","900","1426","477","408","937","1398","584","189","212","680","617","1416","109","664","690","232","522","249","1972","596","1071","1253","1827","444","1745","1470","971","1553","952","1268","47","1549","1072","536","856","529","1514","181","1287","1160","1508","1512","1309","624","1685","1292","62","1463","153","835","842","1272","494","1195","1443","660","1740","916","1167","2020","1118","303","1711","510","1672","318","592","343","826","747","1606","1912","1775","637","2028","709","1913","1971","1129","180","61","337","238","65","1413","229","1479","259","1259","1381","222","1192","865","1273","887","1605","843","150","1323","1222","1857","1726","2022","1980","1890","2024","493","1931","758","610","996","364","361","1524","1797","1314","1296","1322","860","717","1541","341","1966","686","437","565","396","1656","457","653","1572","1131","1193","443","587","1043","794","1152","920","561","282","275","732","1852","209","883","656","487","48","370","179","880","716","990","1603","1620","1143","915","1594","33","1934","3","384","1373","1366","2034","453","481","2052","2068","691","977","1522","1854","604","532","183","193","2011","1932","951","145","1607","790","89","410","751","721","1164","311","1022","517","1891","1263","1555","1425","1065","805","1217","1040","1658","1909","947","1015","1828","831","1517","1796","426","1086","1247","1166","255","541","1099","1774","1069","2021","1750","841","825","2019","949","1847","701","970","1872","69","1355","1556","618","1374","82","938","1350","1901","666","105","397","300","144","74","1719","1953","981","1335","1275","1732","2071","2006","309","1173","1005","566","348","694","549","461","2","1380","1833","301","1628","421","888","1969","1785","388","2005","2002","679","488","1570","844","1328","1227","376","215","999","322","37","725","820","931","1754","2048","1151","1952","551","901","1999","1641","1261","1459","1246","1175","1060","1103","221","1453","682","667","658","926","639","1694","98","330","553","281","54","92","1955","283","1851","102","1445","2035","107","813","1467","754","1076","336","1787","849","2025","907","369","256","1801","425","1266","1593","365","1986","93","1743","1886","974","560","958","387","676","1300","175","2031","1365","492","515","120","1037","735","799","1178","1442","1291","1578","932","1004","853","497","1576","578","1560","142","1100","407","1371","1838","1842","784","921","1363","423","315","640","649","1964","1281","1184","623","1538","1410","170","612","1417","165","1661","1283","924","946","1561","1427","615","788","823","872","1077","1133","1473","126","645","1860","1494","1256","859","683","166","1528","1414","435","948","470","1446","740","299","1590","1144","1315","1533","1731","217","711","1552","1832","1311","285","413","704","1104","1618","1088","352","1302","398","134","197","1109","928","1462","741","1482","1083","1182","1984","2001","1616","1926","1061","715","1534","1389","1845","1197","49","861","1091","1399","2010","484","579","824","1158","1063","791","138","1240","1813","1456","117","1472","1019","913","1140","857","525","463","1370","1480","1816","319","855","1608","1748","1709","1136","1495","1319","1725","1018","1510","1537","152","720","628","254","1457","1692","16","1379","1994","1792","1324","1751","262","854","1521","631","1858","25","1356","286","1600","1753","993","1736","1848","973","520","863","836","1372","1110","700","1868","157","1383","1929","1542","1802","591","1536","1232","1682","626","811","1924","294","670","185","1659","1540","909","1583","2040","1308","1759","220","1307","1567","1599","1701","1053","1943","672","608","1977","1621","943","737","228","1921","1012","227","2041","1428","1840","2065","1082","944","1681","1823","136","1270","1252","1505","1461","1331","2003","12","2063","659","446","1734","316","1121","468","822","90","1285","1589","445","910","1676","63","8","1002","1388","1409","719","1746","1830","1419","1312","1036","611","1159","878","132","1487","1342","1904","833","1448","1820","77","460","1809","1729","474","467","803","1449","1258","1614","91","1476","511","1569","320","377","870","194","2060","172","1011","806","58","714","734","697","1777","765","1881","712","571","755","2070","1255","1201","1713","547","1805","1295","1907","236","155","1529","1189","1880","1956","1058","548","386","652","1465","736","1191","533","1527","158","1511","1200","1717","882","225","257","925","1101","2013","1923","1728","809","964","678","1183","1654","346","983","2058","1343","648","1778","1265","1498","1329","1779","292","491","1395","523","290","277","911","1915","914","307","885","1094","13","1506","18","1163","1975","1297","1125","2077","2033","373","1376","1211","1254","1334","1062","569","1959","231","581","368","485","412","599","505","1339","987","1811","1581","1481","442","687","770","240","5","1664","749","669","469","385","1985","1683","902","1703","1327","456","1995","247","1017","252","1050","1458","2055","1939","1604","785","116","436","862","1157","583","324","392","1038","780","1332","1752","1471","1906","1360","507","1720","1401","168","840","1179","1239","1293","1403","1501","1757","959","1402","1387","1691","314","869","594","1781","1033","274","1634","1286","781","1321","2000","115","280","161","60","1878","1168","1003","884","1394","1507","706","1767","1893","305","590","586","1107","1147","417","1230","1424","609","927","235","2004","163","1773","1724","847","539","797","1073","673","1700","514","1981","1917","191","490","1351","403","1241","1224","454","540","419","1469","378","1262","1591","1653","70","2039","1688","777","1433","1884","1294","713","1080","1396","1762","289","1111","1357","1888","1761","1288","406","544","1723","342","738","504","789","1358","1478","1922","1400","1622","957","124","1112","723","894","19","967","1714","1737","345","1814","1052","1056","1137","174","104","945","821","577","213","767","261","812","605","980","297","936","433","1824","1513","538","1525","2059","466","1996","199","728","1304","119","1856","272","245","595","207","1850","906","125","81","1625","22","1277","1987","331","730","537","1451","1048","2049","210","1202","35","1057","1341","1441","950","956","808","890","1812","681","1215","1123","1973","1437","45","51","32","344","1340","459","1377","1864","68","1693","1066","817","1776","1093","2008","1404","1034","1992","1586","1749","757","201","1001","391","1031","1067","868","1320","1064","1652","1431","1090","1611","1911","367","851","773","129","1610","1763","1095","986","1092","546","1364","1503","1489","1174","1898","1968","550","1900","1722","759","1046","1989","1678","146","40","893","101","1699","1267","746","651","110","1392","1023","379","1613","768","1021","1837","960","898","988","1563","88","2050","1229","440","94","1562","634","2036","1165","186","451","1074","1130","1949","1310","934","1935","1588","1464","1706","969","1368","2044","96","585","1568","1601","572","782","1615","1784","483","1406","1546","675","1491","933","1945","1862","1299","564","1348","1958","954","1075","940","480","1565","473","643","1573","160","1439","575","218","1879","1013","1391","1557","288","1566","447","1948","598","567","2056","95","1821","1666","325","264","332","2076","1499","703","154","962","1","1029","1887","99","1747","1612","1353","1421","991","1544","7","1484","2045","1238","1716","839","1375","580","545","1596","698","1407","975","1755","131","1207","438","1930","1715","472","1718","1030","208","24","521","234","1794","1739","83","1819","1181","801","1078","766","1120","778","242","1452","1206","828","1369","632","1336","1705","9","2037","696","422","1835","2064","796","2043","2046","1806","1895","265","968","597","323","1497","479","787","727","482","810","190","260","1436","984","2053","1115","1575","148","1710","223","1735","2057","393","1430","877","1940","665","783","846","383","287","1535","219","171","866","1548","1650","1000","192","1793","867","1384","1897","1228","1865","1908","1698","1434","1139","995","1771","1382","1574","922","253","196","429","1825","358","130","108","1420","1680","994","39","568","961","302","1006","1916","1640","502","1795","589","164","1519","1432","1791","335","671","677","1708","874","1405","542","2038","1496","1669","374","205","1772","1531","1804","1397","668","1515","1330","1415","1667","441","1826","1216","177","762","114","1617","1009","57","455","1836","633","1677","1592","356","556","620","663","328","1274","1587","382","1204","137","349","1154","753","450","291","896","23","143","1798","742","1156","1687","989","1829","1220","2023","1047","684","1282","1679","699","1807","1697","1026","2014","1316","1905","333","334","1483","1815","834","1822","1313","779","296","4","405","606","43","818","2029","1800","1571","871","1290","601","689","1346","244","1161","518","486","1347","574","1738","1354","1558","394","635","1970","2061","1662","1081","786","173","1927","1235","308","243","121","1210","1122","266","151","1941","52","432","113","1914","638","1276","1630","339","15","1359","1132","1378","1124","203","1423","603","804","743","1213","905","570","613","1042","1947","362","250","1279","976","1874","1475","1712","1186","530","724","1875","1142","752","489","499","662","176","939","1492","1855","748","1689","763","641","1386","760","1485","2026","503","600","1493","178","338","1579","1284","71","733","202","1097","582","1871","516","464","293","149","73","1839","1422","1894","123","509","237","1119","1049","963","1337","1114","86","979","2027","1180","891","133","1817","1408","1135","1223","1306","1903","449","1695","418","224","233","269","815","655","508","1846","1928","918","1803","350","1041","1044","935","524","317","1892","1671","1089","1925","997","912","619","1185","295","216","674","284","875","807","1155","44","140","1257","1876","731","6","774","1808","1113","1326","416","1032","29","230","56","1853","1028","1668","650","1172","59","1244","832","1233","2017","1831","1333","1418","1609","1799","372","886","1249","465","636","1896","1758","1084","816","506","1108","621","2042","375","1486","1670","1367","2069","771","1883","903","929","654","476","526","1965","622","685","1278","800","1982","1225","30","400","1962","1251","1660","1636","251","2072","535","1543","543","792","401","1134","1744","26","1866","1393","312","1624","1141","2032","1079","371","908","761","1447","1243","1153","27","64","195","661","267","1054","1209","85","845","1020","955","2016","498","1490","141","241","1068","798","1500","1523","411","1684","496","354","169","1983","414","1946","1520","1951","1116","992","1863","1349","1024","1564","1260","919","552","562","1554","1673","2054","819","795","351","409","1899","1208","1345","360","1303","1502","1585","1760","850","395","147","66","1196","271","1997","876","1978","1106","1877","629","2009","1559","204","1412","67","1788","775","1938","528","705","1704","112","1707","79","28","2047","321","353","347","1577","1039","558","1203","1841","248","1466","304","415","188","162","827","1637","1580","1087","1035","897","692","381","1176","76","1769","1298","156","359","772","1629","431","1810","1889","904","1440","930","769","1655","357","1733","693","1756","1096","46","614","1550","1742","278","1639","1844","1014","838","1869","17","355","2012","1584","1770","1450","1361","273","1149","428","111","458","1117","1665","475","1702","327","513","1647","1870","1199","198","527","1974","2007","573","978","1993","20","1518","100","72","534","50","1539","1674","1085","462","306","53","1649","630","1226","298","1289","1768","187","1597","1530","858","310","702","404","965","555","78","647","389","1933","1411","657","1790","707","366","1098","776","420","1221","1967","1979","14","1619","276","1998","559","695","848","10","1214","1643","1245","226","1250","1873","1867","1212","1146","471","1190","430","478","495","1234","1902","1582","1051","744","642","1325","1944","1170","710","1942","326","531","627","1177","708","1635","1010","2074","1171","1644","895","1595","953","576","764","41","879","616","118","1960","270","1344","892","985","756","135","688","1786","1264","1696","1642","1963","1205","1645","1301","1102","1126","966","1765","1976","127","864","313","1007","1633","1338","519","1675","593","1455","1474","1138","881","726","1059","917","1504","1882","1721","1730","11","1429","1843","899","1516","554","1741","1936","239","55","1988","380","2030","452","923","42","1551","1602","1128","2067","214","36","75","434","87","802","729","1025","722","1016","644","602","1454","2073","814","211","34","424","1477","1194","793","852","1150","1169","1632","1545","557","1920","512","500","1162","1780","1764","1686","1663","889","1317","1627","2018","1690","1198","448","1237","972","1961","402","2062","739","1248","1626","139","1045","106","1526","1362","1818","1008","329","1861","1950","1280","1231","563","1509","1271","390","501","1990","1859","1954","1783","1305","399","1631","1269","750","1547","31","97","122","268","646","1444","1390","1145","182","982","1435","1657","607","2015","2075","830","1127","1070","38","1885","1385","1834","279","200","941","258","427","1105","718","1646","1218","1789","745","1242","1937","1236","1438","1468","1957","837","246","1991","263","167","1187","159","340","1910","1352","1638","21","1648","1919","1532","1598","1460","1623","1766","2066","625","1488","363","1219","1918","184","1055","80","206","1188","1027","829","1651","588","103","998","128","84","1727","1849"]