Full Code of t3dotgg/paycheck-extension for AI

main 8d2992cff295 cached
4 files
7.3 KB
1.9k tokens
4 symbols
1 requests
Download .txt
Repository: t3dotgg/paycheck-extension
Branch: main
Commit: 8d2992cff295
Files: 4
Total size: 7.3 KB

Directory structure:
gitextract_dhrx6ujw/

├── .gitignore
├── README.md
├── main.js
└── manifest.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
npm-debug.log
node_modules/
dist/
tmp/

.DS_STORE
.idea


================================================
FILE: README.md
================================================
# PayCheck for Twitter

tl;dr - I made an extension that (poorly) estimates how much money a tweet is worth

[Now on the Chrome Web Store](https://chrome.google.com/webstore/detail/paycheck-for-twitter/ldgffedhocinnolmaaecnppdfmmofilp)

# HOW TO INSTALL MANUALLY

1. Download latest .zip from [releases](https://github.com/t3dotgg/paycheck-extension/releases)
2. Unzip the file
3. Go to `chrome://extensions/` in your browser
4. Enable developer mode
5. Click "Load unpacked"
6. Select the folder you unzipped
7. Copilot wrote these instructions for me so I hope they're good enough


================================================
FILE: main.js
================================================
function convertToRawCount(internationalInputString) {
  const numberPattern = /([\d,.]+)([kmb]*)/i;
  const matches = internationalInputString.match(numberPattern);

  if (!matches) {
    return NaN; // Return NaN if the input doesn't match the expected pattern
  }

  const numericPart = matches[1];
  const multiplier = matches[2].toLowerCase();

  let numericValue;

  const lastChars = [
    numericPart.slice(-1),
    numericPart.slice(-2, -1),
    numericPart.slice(-3, -2),
  ];

  // Check if second or third to last character are , or . to handle international numbers
  if (lastChars.includes(".") || lastChars.includes(",")) {
    const parts = numericPart.replace(",", ".").split(".");
    const integerPart = parts[0].replace(/[,]/g, "");
    const decimalPart = parts[1] ? parts[1] : "0";
    numericValue = parseFloat(integerPart + "." + decimalPart);
  } else {
    numericValue = parseFloat(numericPart.replaceAll(",", ""));
  }

  let factor = 1;

  switch (multiplier) {
    case "k":
      factor = 1000;
      break;
    case "m":
      factor = 1000000;
      break;
    case "b":
      factor = 1000000000;
      break;
  }

  return Math.round(numericValue * factor);
}

function convertToDollars(number) {
  const rawCount = convertToRawCount(number);

  const processed = rawCount * 0.000026;
  if (processed < 0.1) return processed.toFixed(5);
  return processed.toFixed(2);
}

const globalSelectors = {};
globalSelectors.postCounts = `[role="group"][id*="id__"]:only-child`;
globalSelectors.articleDate = `[role="article"][aria-labelledby*="id__"][tabindex="-1"] time`;
globalSelectors.analyticsLink = " :not(.dollarBox)>a[href*='/analytics']";
globalSelectors.viewCount =
  globalSelectors.postCounts + globalSelectors.analyticsLink;

const innerSelectors = {};
innerSelectors.dollarSpot = "div div:first-child";
innerSelectors.viewSVG = "div div:first-child svg";
innerSelectors.viewAmount = "div div:last-child span span span";
innerSelectors.articleViewAmount = "span div:first-child span span span";

function doWork() {
  const viewCounts = Array.from(
    document.querySelectorAll(globalSelectors.viewCount)
  );

  const articleViewDateSections = document.querySelectorAll(globalSelectors.articleDate);

  if (articleViewDateSections.length) {
    // the rootDateViewsSection will always be the parent->parent->parent of the last element of the articleDate querySelectorAll result
    let rootDateViewsSection = articleViewDateSections[articleViewDateSections.length - 1].parentElement.parentElement.parentElement;

    // if there is one child, that means it's an old tweet with no viewcount
    // if there are more than 4, we already added the paycheck value
    if (rootDateViewsSection?.children?.length !== 1 && rootDateViewsSection?.children.length < 4) {
      // clone 2nd and 3rd child of rootDateViewsSection
      const clonedDateViewSeparator =
        rootDateViewsSection?.children[1].cloneNode(true);
      const clonedDateView = rootDateViewsSection?.children[2].cloneNode(true);

      // insert clonedDateViews and clonedDateViewsTwo after the 3rd child we just cloned
      rootDateViewsSection?.insertBefore(
        clonedDateViewSeparator,
        rootDateViewsSection?.children[2].nextSibling
      );
      rootDateViewsSection?.insertBefore(
        clonedDateView,
        rootDateViewsSection?.children[3].nextSibling
      );

      // get view count value from 'clonedDateViewsTwo'
      const viewCountValue = clonedDateView?.querySelector(
        innerSelectors.articleViewAmount
      )?.textContent;
      const dollarAmount = convertToDollars(viewCountValue);

      // replace textContent in cloned clonedDateViews (now 4th child) with converted view count value
      clonedDateView.querySelector(
        innerSelectors.articleViewAmount
      ).textContent = "$" + dollarAmount;

      // remove 'views' label
      clonedDateView.querySelector(`span`).children[1].remove();
    }
  }

  for (const view of viewCounts) {
    // only add the dollar box once
    if (!view.classList.contains("replaced")) {
      // make sure we don't touch this one again
      view.classList.add("replaced");

      // get parent and clone to make dollarBox
      const parent = view.parentElement;
      const dollarBox = parent.cloneNode(true);
      dollarBox.classList.add("dollarBox");

      // insert dollarBox after view count
      parent.parentElement.insertBefore(dollarBox, parent.nextSibling);

      // remove view count icon
      const oldIcon = dollarBox.querySelector(innerSelectors.viewSVG);
      oldIcon?.remove();

      // swap the svg for a dollar sign
      const dollarSpot = dollarBox.querySelector(innerSelectors.dollarSpot)
        ?.firstChild?.firstChild;
      dollarSpot.textContent = "$";

      // magic alignment value
      dollarSpot.style.marginTop = "-0.6rem";
    }

    // get the number of views and calculate & set the dollar amount
    const dollarBox = view.parentElement.nextSibling.firstChild;
    const viewCount = view.querySelector(
      innerSelectors.viewAmount
    )?.textContent;
    if (viewCount == undefined) continue;
    const dollarAmountArea = dollarBox.querySelector(innerSelectors.viewAmount);
    dollarAmountArea.textContent = convertToDollars(viewCount);
  }
}

function throttle(func, limit) {
  let lastFunc;
  let lastRan;
  return function () {
    const context = this;
    const args = arguments;
    if (!lastRan) {
      func.apply(context, args);
      lastRan = Date.now();
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(function () {
        if (Date.now() - lastRan >= limit) {
          func.apply(context, args);
          lastRan = Date.now();
        }
      }, limit - (Date.now() - lastRan));
    }
  };
}

// Function to start MutationObserver
const observe = () => {
  const runDocumentMutations = throttle(() => {
    requestAnimationFrame(doWork);
  }, 1000);

  const observer = new MutationObserver((mutationsList) => {
    if (!mutationsList.length) return;
    runDocumentMutations();
  });

  observer.observe(document, {
    childList: true,
    subtree: true,
  });
};

observe();


================================================
FILE: manifest.json
================================================
{
  "manifest_version": 3,
  "name": "PayCheck for X (Formerly Twitter)",
  "description": "See (a very VERY rough idea of) how much money a post is worth",
  "version": "0.0.3",
  "icons": {
    "16": "/assets/PCX-icon-16.png",
    "32": "/assets/PCX-icon-32.png",
    "48": "/assets/PCX-icon-48.png",
    "128": "/assets/PCX-icon-128.png"
  },
  "author": "Theo",
  "content_scripts": [
    {
      "run_at": "document_end",
      "matches": [
        "https://twitter.com/*",
        "https://mobile.twitter.com/*",
        "https://tweetdeck.twitter.com/*",
        "https://x.com/*"
      ],
      "js": ["main.js"]
    }
  ]
}
Download .txt
gitextract_dhrx6ujw/

├── .gitignore
├── README.md
├── main.js
└── manifest.json
Download .txt
SYMBOL INDEX (4 symbols across 1 files)

FILE: main.js
  function convertToRawCount (line 1) | function convertToRawCount(internationalInputString) {
  function convertToDollars (line 47) | function convertToDollars(number) {
  function doWork (line 68) | function doWork() {
  function throttle (line 151) | function throttle(func, limit) {
Condensed preview — 4 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (8K chars).
[
  {
    "path": ".gitignore",
    "chars": 56,
    "preview": "npm-debug.log\nnode_modules/\ndist/\ntmp/\n\n.DS_STORE\n.idea\n"
  },
  {
    "path": "README.md",
    "chars": 583,
    "preview": "# PayCheck for Twitter\n\ntl;dr - I made an extension that (poorly) estimates how much money a tweet is worth\n\n[Now on the"
  },
  {
    "path": "main.js",
    "chars": 6163,
    "preview": "function convertToRawCount(internationalInputString) {\n  const numberPattern = /([\\d,.]+)([kmb]*)/i;\n  const matches = i"
  },
  {
    "path": "manifest.json",
    "chars": 633,
    "preview": "{\n  \"manifest_version\": 3,\n  \"name\": \"PayCheck for X (Formerly Twitter)\",\n  \"description\": \"See (a very VERY rough idea "
  }
]

About this extraction

This page contains the full source code of the t3dotgg/paycheck-extension GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 4 files (7.3 KB), approximately 1.9k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!