Today is Africa Day, commemorating the African Union’s founding.


If you want to be that person, it’s apparently also Geek Pride Day, but since so-called “geek culture” revolves so much around big-corporate-controlled media franchises…eh.

Probably more importantly where I live, it’s also Memorial Day in the United States, where we mourn those who have died in the line of military duty. It’d be nice if we could stop adding to their ranks. It’d also be nice if politicians could just once remember what the holiday is for and not wish us a “happy” one and opining about who is blessing the country, but baby steps, I guess…

For my own part, I didn’t get nearly as much accomplished as I wanted.

Uxuyu 🔗

The boring part is that I updated the .gitignore file to ignore the database.

I also took the first steps towards storing the currently known set of feeds, by sending the data (which I have been keeping track of for this purpose) to the new account-management thread.


Since worker threads continue to be slightly more useful than I expect, receiving that message is exactly symmetric to receiving a message in the main thread.

parentPort.on('message', (message) => {
  // Process the message

This was a big enough breakthrough that it warranted its own commit, this time through.

CPREP Background Generator 🔗

I’ve been fixing small issues with CPREP, like formatting and display, and adding some comments.

Because the map of skin tones is—bluntly—pretty terrible, I’ve added a supplemental set of skin colors that are less stupid from this image by A7N8X.

Von Luschan scale

To work with this, I added a simple function to just pull apart the red, green, and blue values and finds the nearest color on the chart. Why use RGB instead of HSL like I recommended in my post on colors the programming way? Because the hues are in the red-to-orange space and saturations are two-thirds to three-quarters, since skin colors are just different kinds of brown.

In the future, it might be worth doing the analysis and weighting the HSL components in a useful way, but until then, it comes down to something like this:

list.forEach(c => {
  const ccb = c[1] & 0x000000FF;
  const ccg = (c[1] & 0x0000FF00) >> 8;
  const ccr = (c[1] & 0x00FF0000) >> 16;
  const dr = ccr - cr;
  const dg = ccg - cg;
  const db = ccb - cb;
  const dist = dr * dr + dg * dg + db * db;

  if (dist < minDist) {
    minIndex = idx;
    minDist = dist;

  idx += 1;

(Actually, I need to patch the colors; I just realized that I got the order of operations wrong in the version on GitHub.)

You should recognize dist as (the square of) the Euclidean distance between two points. You might not recognize JavaScript’s bitwise operators. A single ampersand (&) is a binary-AND, which takes each bit in a number and produces an answer where the resulting bit is on (“1”) only when the corresponding input bits are on; don’t confuse this with the double-ampersand (&&), which is a logical-AND, doing the same for two conditions. There’s a corresponding binary-OR (|), of course. The right-shift operator (>>) drops the least-significant bit in the number of times mentioned in the second operand, so it basically divides by 2n.

So, ccb is the number representing a color with the non-blue components zeroed out, and bumped down to wipe out the lower four zeroes, if that makes sense.

Oh, and I also fixed the date. Somehow, I never noticed that the earliest day of the year was mysteriously going to be New Year’s Eve.

Bicker 🔗

I bumped a couple of libraries to their latest versions for security reasons. Nothing much exciting, there.

Menial Changes 🔗

Not yet (and maybe never) for the blog, but I’ve shifted over to Victor Mono in my IDEs and code editors. It has most of the same ligatures as the excellent Fira Code, but the italic forms are designed to resemble cursive letters. If your editor/environment supports displaying comments in italics, that emphasizes the comments nicely, with a less structured look than the surrounding code.

Victor Mono in Action

The idea has been making the rounds for a couple of years, at this point, but this is the first of the Free Software fonts that I’ve seen with both feature sets.

Next 🔗

You know the song, at this point. Mostly, Uxuyu still clearly needs attention to get where I want it, specifically storing the account information and using that to search all feeds while only displaying posts from people the user follows.

I have also hit enough minor snags in testing that I think it’s past time to add ESLint to the Uxuyu project. I’m not sure whether it’s Proton Native, the worker threads, or both, but minor syntax errors (the kind that Node.js usually ignores) have been causing fatal errors with no error message, so I’d rather have a tool shoulder some of this load than waste more time guessing what I did wrong the next time. That will probably mean at least a couple of days cleaning up possible issues.

Unfortunately, it looks like the SVG snippets in Character Creator have a non-commercial license, which (in my eyes) disqualifies them from use in CPREP. It’s a shame, since it was looking to be easy to generate a simple random headshot. So, now I’m on the hunt for an “actually Free” set of facial features.

However, I also have the seed of a new (unrelated) idea that might be interesting. We’ll see if I can pull together enough of a design to launch the project this week.

Credits: The header image is Africa and Europe from a Million Miles Away by NASA, dedicated to the public domain by policy.