Bitcoin Forum
May 10, 2024, 01:17:52 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 »
1  Bitcoin / Project Development / Re: Compiling KeyHunt_Cuda with gpu support on: April 28, 2024, 10:15:19 PM
Any ideas please??
I've never used this tool, but, taking a quick peek at the code, it looks to me like the cause of your error message might be a bug...

The code starting at line 290 in Main.cpp looks like this:

Code:
			else if (optArg.equals("-l", "--list")) {
#ifdef WIN64
GPUEngine::PrintCudaInfo();
#else
printf("GPU code not compiled, use -DWITHGPU when compiling.\n");
#endif
return 0;
}

That #ifdef should probably be #ifdef WITHGPU, not #ifdef WIN64.

(Take the above with a grain of salt, though; like I said, I've never used this tool, much less tried to compile it.)
2  Other / Meta / Re: [theymos] Bug with Merit (for sending) on: April 28, 2024, 02:18:04 PM
Lol. I've reached my monthly limit, so all I could send you was 0.002e3 Merits.
Haha. I sent you 1000e-3 merits; don't spend them all in one place. Cheesy (Putting a minus sign before the exponent divides the significand instead of multiplying it.)

Hasn't anybody tried to use the infinity symbol to give the maximum? Smiley
That's a cool idea. Maybe theymos could make it so that sending someone * merits results in you sending them the maximum you can. (An asterisk is easy to type, and if you squint, it looks a bit like a tiny bomb that's just started to explode, so it kind of makes sense, too, as in "merit bombing" someone.) Grin
3  Other / Meta / Re: [theymos] Bug with Merit (for sending) on: April 25, 2024, 02:31:06 AM
Hehe, this is not a bug, it's just how PHP handles string -> number conversions. (If I had to guess, I'd say that there's an (int) cast happening on $_POST['merits'].)

Interestingly, the rules allow for scientific notation (more specifically: E notation), so something like 2e1 means 2*10^1 = 20 merits. Even in the context of an (int) cast, I think the leading number can have a decimal point, so another way to send someone 20 merits would be to send them 0.02e3 merits.
4  Other / Meta / Re: Long codes messing up the post history appearance. Solutions? on: April 16, 2024, 02:50:35 PM
I don't know why this is happening but it is probably a bug and looks like it's time for another PowerGlove SMF forum patch  Cheesy
Jeebus, I'm busy, yo. You can't just say "PowerGlove" every time this forum needs patchin'. (I'm just kidding, you totally can.) Grin

Hang on... I've already done this one, haven't I? Undecided

(In all seriousness, this problem has already been fixed, but it fell off of theymos' radar and has just been collecting dust. I recently reminded theymos about it, and I'm pretty certain he'll accept/merge the patch once I'm finished with one last testing/polishing pass. It's good/fortunate timing that logfiles posted a new topic about this, though, because the approach that PX-Z came up with a few posts up is smarter/neater than the approach I used originally, so I'll probably end up revising the patch as a result. @PX-Z: Nice job, man!)

That makes me think it's a css thing that may be very easy to fix.
I mean, you're not wrong, and there is a simple CSS fix for this (see shahzadafzal's posts here and here).

But, if you look at the stylesheet, it's pretty obvious that the SMF devs didn't want [code] to be presented that way (with "wrapped" contents), and I agree with them. So, while the simple CSS tweak is tempting, I don't think that's the right solution here: changing how code renders in response to a pretty specific layout bug seems clumsy/ill-considered to me.

(BTW, last time this came up, you mentioned something similar happening when replying to wide-code-containing PMs: I've got a patch for that, too, and I'll include it when I update that topic.) Wink
5  Other / Meta / Re: Mixers to be banned on: April 15, 2024, 12:29:23 AM
Sort of makes you wonder if the rest of the stuff I say that people immediately try to dismiss is worth taking a closer look at...
Dude. That helping-yourself-to-airdrops thing stunk up your reputation bad. You went behind theymos' back and used the coins that you were entrusted with for personal gain; I'm not talking about the minor forkcoins you were gifted, I'm talking about the airdrops that you somehow concluded you were personally entitled to. If at any point you said something along the lines of: "You know what? That was actually wrong of me, and I'm sorry that I did that.", then, I think more people would take you seriously. (If you have already apologized, and I missed that, then please accept my apology for still giving you shit about it, but all I've ever read about it from you has been the insistence that you did nothing wrong.)



On-topic: In the context of the existing mixer ban, I think theymos made the right call here. Technically, Jambler is doing the mixing, not the partner site(s). If you read their FAQ, /faq.php#faq-2.6]2.6 states (emphasis mine): "[banned mixer] conducts and provides all financial transactions, for this reason a letter of guarantee is issued by the platform itself."; the fact that their model makes you interact with their backend through a third party, doesn't really change anything. I mean, it's a bummer, and I hate this the-cypherpunks-won-the-battle-but-lost-the-war road that Bitcointalk seems to be heading down, but, yeah, it is what it is... (It's not like theymos can thumb his nose at the regulators and the ongoing crackdown on privacy; decisions made long ago mean that Bitcointalk's whole technical and legal setup is too fragile to withstand a conflict of that nature.)
6  Other / Meta / Re: Identifying the linked-to post in a topic (SMF patch) on: April 11, 2024, 03:13:05 AM
Hmm... I never noticed that the last (bold-faced) item in the link-tree is an actual link:



It has its text-decoration set to none and its cursor set to default, so it's easy to miss, I guess, but it kind of makes sense in a weird way; it's like it's saying: "this is where you are, yo." Cheesy

Anyway, if that's an idea that's worth repeating, then the second diff for style C should be like this:

Code:
--- baseline/Themes/default/Display.template.php	2010-10-22 01:38:35.000000000 +0000
+++ modified/Themes/default/Display.template.php 2024-04-11 01:21:29.000000000 +0000
@@ -359,33 +359,34 @@
  echo '
  <a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['label'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . $message['member']['online']['label'] . '" border="0" />' : $message['member']['online']['label'], '</a>';
  }
  }
  // Otherwise, show the guest's email.
  elseif (empty($message['member']['hide_email']))
  echo '
  <br />
  <br />
  <a href="mailto:', $message['member']['email'], '">', ($settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/email_sm.gif" alt="' . $txt[69] . '" title="' . $txt[69] . '" border="0" />' : $txt[69]), '</a>';
 
  // Done with the information about the poster... on to the post itself.
+ $is_requested_message = isset($context['requested_msg']) && $context['requested_msg'] == $message['id'];
  echo '
  </div>
  </td>
  <td valign="top" width="85%" height="100%">
  <table width="100%" border="0"><tr>
  <td valign="middle"><a href="', $message['href'], '"><img src="', $message['icon_url'] . '" alt="" border="0" /></a></td>
  <td valign="middle">
  <div style="font-weight: bold;" id="subject_', $message['id'], '">
- <a href="', $message['href'], '">', $message['subject'], '</a>
+ <a ', $is_requested_message ? 'style="color: black; text-decoration: none; cursor: default;" ' : '', 'href="', $message['href'], '">', $message['subject'], '</a>
  </div>';
 
  // If this is the first post, (#0) just say when it was posted - otherwise give the reply #.
  echo '
  <div class="smalltext">&#171; <b>', !empty($message['counter']) ? $txt[146] . ' #' . $message['counter'] : '', ' ', $txt[30], ':</b> ', $message['time'], ' &#187;</div></td>
  <td align="', !$context['right_to_left'] ? 'right' : 'left', '" valign="bottom" height="20" style="font-size: smaller;">';
 
  // Can they reply? Have they turned on quick reply?
  if ($context['can_reply'] && !empty($options['display_quick_reply']))
  echo '
  <a href="', $scripturl, '?action=post;quote=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';num_replies=', $context['num_replies'], ';sesc=', $context['session_id'], '" onclick="doQuote(', $message['id'], ', \'', $context['session_id'], '\'); return false;">', $reply_button, '</a>';

(I see references in SMF to a "nav" class for the link-tree, and a reference to a "navPages" class for the page-list; makes me think that the idiomatic way to repeat this idea would be to add a "navMessage" class instead of doing this with an inline style.)

@theymos: I know this is off-topic, but, seeing as though you're watching the thread, and while I've got links on my mind: if/when you find some time, maybe you could quickly tackle this one? (I think that suggestion makes a lot of sense; when LoyceV first mentioned it, I remember thinking: "Ooh, that's a nice little improvement.")

P.S. I blew all of my theymos-sMerit on your April Fools gag, so I won't be able to merit your posts for a bit. Wink
7  Other / Meta / Re: Identifying the linked-to post in a topic (SMF patch) on: April 08, 2024, 10:36:28 PM
- Change the color of the entire post <tr>, using a different color than the usual alternating blue and grey (but not too different).
Yep. That's pretty much the first thing I tried, but, I couldn't find a color that struck a nice balance between (effectively) highlighting the post, and not drifting too far away from the SMF aesthetic. Maybe I wasn't persistent enough, and someone else might have better luck, but every time I managed to get the post to stand out, it looked ugly/wrong to me, and every time I managed to make it look nice/right, the post didn't really stand out.

- Add a little red(?) asterisk or something in the lower-right corner of the post icon (ie. td.td_headerandpost table tbody tr td a img).
Messing with the post icon is a cool idea...

Maybe this one's too subtle, but, a drop shadow on the icon looks kind of nice:



(That's a style="filter: drop-shadow(0 0 2px #355d8099);" on the <img> element; the #355d8099 is a 60% opacity dark/desaturated blue that I color-picked from the top-most gradient on the SMF menu.)
8  Other / Meta / Re: Identifying the linked-to post in a topic (SMF patch) on: April 07, 2024, 11:52:21 PM
Sometimes the post you're looking for will not even be on the landing page after clicking on the link. (...) Will this pose a problem or it happens too few times for it to actually matter.
Missing/deleted posts won't confuse this patch. What'll happen is that none of the posts will be "marked". (Typically, when I land on a topic-page that's missing the post I was looking for, I usually know that's what's happened because the viewport hasn't snapped to a post, and I can still see the SMF menu; that'll still be the case with this patch.)

In terms of hard-coding any styles in general, is there any reason you are not avoiding the <span> all together and adding an "id" to the <a> element, then just adding to the CSS file?
That's a cool idea (that is, using a content string on a ::before pseudo-element), but, besides the advantage of avoiding adding a <span> element (which, all concerned parties seem to agree will either not disturb, or be pretty easy to adjust their parsers for), there are a few drawbacks (in no particular order):

(*) To me, it feels unnatural to put something in the global stylesheet for such a specific, single use-case. (Though, I'm aware that that's mostly a matter of preference, and I do see some other used-just-once stuff in the stylesheet already. I guess, if I were building a new frontend for Bitcointalk from scratch, I'd probably be inclined to avoid inline styles and to observe stricter separation between content and presentation.)

(*) With this patch, there's no avoiding having to make a small change to Display.php and a small change to Display.template.php (with or without your CSS idea). So, involving the stylesheet would add a third patch-point. Needing 3 co-ordinating pieces for this feature to work makes things a little more fragile and complicated than they should be, I think. (I'm also inclined to believe that theymos is more likely to decide to sit down and review/merge a patch, when that patch involves no more components/changes than necessary.)

(*) When the "marker" is added this way (via a ::before pseudo-element), it forms part of the actual subject-line link (as opposed to sitting next to it in a sibling element), and so, when you hover over it, for example, it looks/responds like it's just some extra characters in the subject-line (which is undesirable for a few reasons, but, the main one, I guess, is that I don't want to introduce any unnecessary confusion around where the marker ends and the subject-line begins; if someone tries, for example, to artificially place the marker into their subject-line before posting, then I want there to be some semi-obvious difference between a genuine marker and a "fake" one). It also picks up the link's color (which lowers the contrast of the marker), and its opacity value ends up affecting a small part of the link's :hover text decoration, which looks kind of messy.

But, I believe the best approach is option A, (...) I would just add maybe a color change, or a different font size, to make this situation stand out more than just italics.
I've looked at a lot of hues by going around the color wheel in ~15 degree increments, and, maybe I'm just really picky, but they all look "wrong" to me in one way or another. What does end up working rather nicely, though, is making the subject-line black. Another thing that works pretty nicely is underlining the subject-line. Underlining also kind of makes sense semantically, in a weird way: Normally, you only see the subject-line underlined when you're about to click on it, but, in this context, you already have clicked on the link (otherwise you wouldn't be seeing it rendered differently to begin with).

Style C

This one just makes the subject-line link black.



Code:
--- baseline/Sources/Display.php	2011-02-07 16:45:09.000000000 +0000
+++ modified/Sources/Display.php 2024-04-04 00:02:44.000000000 +0000
@@ -230,24 +230,25 @@
  SELECT COUNT(*)
  FROM {$db_prefix}messages
  WHERE ID_MSG < $virtual_msg
  AND ID_TOPIC = $topic", __FILE__, __LINE__);
  list ($context['start_from']) = mysql_fetch_row($request);
  mysql_free_result($request);
  }
 
  // We need to reverse the start as well in this case.
  $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $topicinfo['numReplies'] - $context['start_from'];
 
  $context['robot_no_index'] = true;
+ $context['requested_msg'] = $virtual_msg;
  }
  }
 
  // Create a previous next string if the selected theme has it as a selected option.
  $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
 
  // Check if spellchecking is both enabled and actually working. (for quick reply.)
  $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
 
  // Censor the title...
  censorText($topicinfo['subject']);
  $context['page_title'] = $topicinfo['subject'];

Code:
--- baseline/Themes/default/Display.template.php	2010-10-22 01:38:35.000000000 +0000
+++ modified/Themes/default/Display.template.php 2024-04-07 23:42:42.000000000 +0000
@@ -359,33 +359,34 @@
  echo '
  <a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['label'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . $message['member']['online']['label'] . '" border="0" />' : $message['member']['online']['label'], '</a>';
  }
  }
  // Otherwise, show the guest's email.
  elseif (empty($message['member']['hide_email']))
  echo '
  <br />
  <br />
  <a href="mailto:', $message['member']['email'], '">', ($settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/email_sm.gif" alt="' . $txt[69] . '" title="' . $txt[69] . '" border="0" />' : $txt[69]), '</a>';
 
  // Done with the information about the poster... on to the post itself.
+ $is_requested_message = isset($context['requested_msg']) && $context['requested_msg'] == $message['id'];
  echo '
  </div>
  </td>
  <td valign="top" width="85%" height="100%">
  <table width="100%" border="0"><tr>
  <td valign="middle"><a href="', $message['href'], '"><img src="', $message['icon_url'] . '" alt="" border="0" /></a></td>
  <td valign="middle">
  <div style="font-weight: bold;" id="subject_', $message['id'], '">
- <a href="', $message['href'], '">', $message['subject'], '</a>
+ <a ', $is_requested_message ? 'style="color: black;" ' : '', 'href="', $message['href'], '">', $message['subject'], '</a>
  </div>';
 
  // If this is the first post, (#0) just say when it was posted - otherwise give the reply #.
  echo '
  <div class="smalltext">&#171; <b>', !empty($message['counter']) ? $txt[146] . ' #' . $message['counter'] : '', ' ', $txt[30], ':</b> ', $message['time'], ' &#187;</div></td>
  <td align="', !$context['right_to_left'] ? 'right' : 'left', '" valign="bottom" height="20" style="font-size: smaller;">';
 
  // Can they reply? Have they turned on quick reply?
  if ($context['can_reply'] && !empty($options['display_quick_reply']))
  echo '
  <a href="', $scripturl, '?action=post;quote=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';num_replies=', $context['num_replies'], ';sesc=', $context['session_id'], '" onclick="doQuote(', $message['id'], ', \'', $context['session_id'], '\'); return false;">', $reply_button, '</a>';

Style D

This one puts a text-decoration: underline on the subject-line link.



Code:
--- baseline/Sources/Display.php	2011-02-07 16:45:09.000000000 +0000
+++ modified/Sources/Display.php 2024-04-04 00:02:44.000000000 +0000
@@ -230,24 +230,25 @@
  SELECT COUNT(*)
  FROM {$db_prefix}messages
  WHERE ID_MSG < $virtual_msg
  AND ID_TOPIC = $topic", __FILE__, __LINE__);
  list ($context['start_from']) = mysql_fetch_row($request);
  mysql_free_result($request);
  }
 
  // We need to reverse the start as well in this case.
  $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $topicinfo['numReplies'] - $context['start_from'];
 
  $context['robot_no_index'] = true;
+ $context['requested_msg'] = $virtual_msg;
  }
  }
 
  // Create a previous next string if the selected theme has it as a selected option.
  $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
 
  // Check if spellchecking is both enabled and actually working. (for quick reply.)
  $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
 
  // Censor the title...
  censorText($topicinfo['subject']);
  $context['page_title'] = $topicinfo['subject'];

Code:
--- baseline/Themes/default/Display.template.php	2010-10-22 01:38:35.000000000 +0000
+++ modified/Themes/default/Display.template.php 2024-04-07 23:43:30.000000000 +0000
@@ -359,33 +359,34 @@
  echo '
  <a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['label'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . $message['member']['online']['label'] . '" border="0" />' : $message['member']['online']['label'], '</a>';
  }
  }
  // Otherwise, show the guest's email.
  elseif (empty($message['member']['hide_email']))
  echo '
  <br />
  <br />
  <a href="mailto:', $message['member']['email'], '">', ($settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/email_sm.gif" alt="' . $txt[69] . '" title="' . $txt[69] . '" border="0" />' : $txt[69]), '</a>';
 
  // Done with the information about the poster... on to the post itself.
+ $is_requested_message = isset($context['requested_msg']) && $context['requested_msg'] == $message['id'];
  echo '
  </div>
  </td>
  <td valign="top" width="85%" height="100%">
  <table width="100%" border="0"><tr>
  <td valign="middle"><a href="', $message['href'], '"><img src="', $message['icon_url'] . '" alt="" border="0" /></a></td>
  <td valign="middle">
  <div style="font-weight: bold;" id="subject_', $message['id'], '">
- <a href="', $message['href'], '">', $message['subject'], '</a>
+ <a ', $is_requested_message ? 'style="text-decoration: underline;" ' : '', 'href="', $message['href'], '">', $message['subject'], '</a>
  </div>';
 
  // If this is the first post, (#0) just say when it was posted - otherwise give the reply #.
  echo '
  <div class="smalltext">&#171; <b>', !empty($message['counter']) ? $txt[146] . ' #' . $message['counter'] : '', ' ', $txt[30], ':</b> ', $message['time'], ' &#187;</div></td>
  <td align="', !$context['right_to_left'] ? 'right' : 'left', '" valign="bottom" height="20" style="font-size: smaller;">';
 
  // Can they reply? Have they turned on quick reply?
  if ($context['can_reply'] && !empty($options['display_quick_reply']))
  echo '
  <a href="', $scripturl, '?action=post;quote=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';num_replies=', $context['num_replies'], ';sesc=', $context['session_id'], '" onclick="doQuote(', $message['id'], ', \'', $context['session_id'], '\'); return false;">', $reply_button, '</a>';

(The four styles are conceptually orthogonal: A = subject-in-italics, B = subject-with-graphical-prefix, C = subject-in-black, D = subject-underlined. A + D = in italics and underlined, D + B = underlined and with a graphical prefix, etc.; I think, if it were up to me, I might just go with C: it's nice and simple, with plenty of contrast, so it's really easy to pick out the "marked" post, and it still looks SMFish to my eyes. Though, for some types of color blindness, I can see other choices/combinations making sense.)
9  Other / Meta / Re: Identifying the linked-to post in a topic (SMF patch) on: April 05, 2024, 03:57:39 PM
PowerGlove, you seem to know a lot about the custom SMF front end, so let me ask you a question: (...)
I can only guess at what those might be. I think a satisfying answer would have to come from theymos.

I think your changes are too subtle to quickly identify the post I'm looking for.
Yep. I can appreciate that point of view. It's worth pointing out, though, that it's difficult to gauge things just by looking at the example images in the OP; when you see either style A or style B in its proper context (that is, when a differently-rendered post is surrounded by posts that aren't rendered differently), then the differently-rendered post stands out pretty obviously (at least, to my eyes it does).

BPIP grabs this title for the smerit log as well (...)
Oops, how could I forget about you and suchmoon? My bad. Wink

(...) Style C?  Or too obvious?
I think that one is maybe a little too loud. (But, I'm aware that I lean pretty subtle most of the time.)

I mean, my point of view isn't really any more valuable than anyone else's, so if most people think/feel that something a bit more obvious is necessary, then I'm happy to produce patches for styles C/D/E/etc. based on any idea(s) that people like.

One thing to consider, though, is that some users are running modified/customized stylesheets, so a robust solution should try to avoid relying on hard-coded color values (from that point of view, styles A and B are nice and resilient; they'll likely work as intended with any custom stylesheet).

Personally, I think style B has quite a lot of promise; the way it's presented in the OP looks pretty good to me as-is, but the HTML for that style (<span style="opacity: 30%;">&#8702;&nbsp;</span>) actually has two degrees of freedom to play with: both the opacity value and the specific Unicode symbol can make a pretty big visual difference. For example, if you bump the opacity up to 60% and change the symbol from U+21FE to U+2B0A (so, <span style="opacity: 60%;">&#11018;&nbsp;</span>), then, it'll look like this:



I suppose, if I ignore my thoughts about custom-stylesheet resilience, and do a slightly taller glyph (U+2BAF), in 60% opacity primary blue, or something, then it's easy to get it to pretty much jump out from the page (<span style="color: #0000ff99;">&#11183;&nbsp;</span>):



(Something to consider when picking a glyph, is that some of them can either render quite differently or be missing entirely on some devices/browsers/fonts; if that ends up being an actual issue, then, I think what I'll do is bake the symbol into a little transparent PNG, and re-work the patch around that.)
10  Other / Meta / Identifying the linked-to post in a topic (SMF patch) on: April 04, 2024, 01:31:44 AM
Hey, everybody! Smiley

This suggestion came from Cyrus, and I think it's a really good idea, so I thought I'd sink some time into it, and put together a patch.

Basically, the idea is to make it easier to identify the target post after clicking an ordinary post link, like: https://bitcointalk.org/index.php?topic=4193.msg60743#msg60743.

Normally, the (optional) fragment identifier at the end of the URL (#msg60743 in the example link) suffices to position the viewport so that the linked-to post is obvious/unambiguous. But, sometimes that mechanism isn't precise enough, like when the post is the last or second-to-last one on its page (then, I often find myself hovering over the subject link and comparing it to the address bar to confirm that I'm reading the right post).

I also sometimes lose track of the linked-to post when I scroll around the page for a bit to get some context before reading the actual post (then, I find myself going to the address bar and hitting Enter so that the browser snaps to the right post again).

In the worst case, both of those situations occur: After landing on the relevant topic-page, you scroll around a bit for some context, then you use the Enter trick to snap to the right post, but that's not reliable for the last or second-to-last post, so you have to do the address-comparing thing too. Cheesy

I also have to imagine that report-handling would be a little more pleasant for moderators if they had a reliable way to always quickly identify the linked-to post.

Anyway, it's tempting to make the linked-to post really stand out by putting a differently-colored background or border on it, or an inset/outset box-shadow or something, but, all the variations of that idea that I tried ended up looking pretty naff (and, anyway, I don't really like messing with the SMF aesthetic that a lot of veteran members prefer as-is). In this case, I think it's wiser to just do something really subtle and "quiet" (after all, the forum has been just fine for a long time without this, so I don't think it should be something that jumps out from the page and draws your eye too much; it should just be something that people who know what to look for, will look for).

I've done this patch in two styles:

Style A

This one just makes the subject-line of the linked-to post render differently than normal (with font-style: italic).



Code:
--- baseline/Sources/Display.php	2011-02-07 16:45:09.000000000 +0000
+++ modified/Sources/Display.php 2024-04-04 00:02:44.000000000 +0000
@@ -230,24 +230,25 @@
  SELECT COUNT(*)
  FROM {$db_prefix}messages
  WHERE ID_MSG < $virtual_msg
  AND ID_TOPIC = $topic", __FILE__, __LINE__);
  list ($context['start_from']) = mysql_fetch_row($request);
  mysql_free_result($request);
  }
 
  // We need to reverse the start as well in this case.
  $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $topicinfo['numReplies'] - $context['start_from'];
 
  $context['robot_no_index'] = true;
+ $context['requested_msg'] = $virtual_msg;
  }
  }
 
  // Create a previous next string if the selected theme has it as a selected option.
  $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
 
  // Check if spellchecking is both enabled and actually working. (for quick reply.)
  $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
 
  // Censor the title...
  censorText($topicinfo['subject']);
  $context['page_title'] = $topicinfo['subject'];

Code:
--- baseline/Themes/default/Display.template.php	2010-10-22 01:38:35.000000000 +0000
+++ modified/Themes/default/Display.template.php 2024-04-04 00:03:41.000000000 +0000
@@ -359,32 +359,33 @@
  echo '
  <a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['label'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . $message['member']['online']['label'] . '" border="0" />' : $message['member']['online']['label'], '</a>';
  }
  }
  // Otherwise, show the guest's email.
  elseif (empty($message['member']['hide_email']))
  echo '
  <br />
  <br />
  <a href="mailto:', $message['member']['email'], '">', ($settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/email_sm.gif" alt="' . $txt[69] . '" title="' . $txt[69] . '" border="0" />' : $txt[69]), '</a>';
 
  // Done with the information about the poster... on to the post itself.
+ $is_requested_message = isset($context['requested_msg']) && $context['requested_msg'] == $message['id'];
  echo '
  </div>
  </td>
  <td valign="top" width="85%" height="100%">
  <table width="100%" border="0"><tr>
  <td valign="middle"><a href="', $message['href'], '"><img src="', $message['icon_url'] . '" alt="" border="0" /></a></td>
  <td valign="middle">
- <div style="font-weight: bold;" id="subject_', $message['id'], '">
+ <div style="font-weight: bold;', $is_requested_message ? ' font-style: italic;' : '', '" id="subject_', $message['id'], '">
  <a href="', $message['href'], '">', $message['subject'], '</a>
  </div>';
 
  // If this is the first post, (#0) just say when it was posted - otherwise give the reply #.
  echo '
  <div class="smalltext">&#171; <b>', !empty($message['counter']) ? $txt[146] . ' #' . $message['counter'] : '', ' ', $txt[30], ':</b> ', $message['time'], ' &#187;</div></td>
  <td align="', !$context['right_to_left'] ? 'right' : 'left', '" valign="bottom" height="20" style="font-size: smaller;">';
 
  // Can they reply? Have they turned on quick reply?
  if ($context['can_reply'] && !empty($options['display_quick_reply']))
  echo '
  <a href="', $scripturl, '?action=post;quote=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';num_replies=', $context['num_replies'], ';sesc=', $context['session_id'], '" onclick="doQuote(', $message['id'], ', \'', $context['session_id'], '\'); return false;">', $reply_button, '</a>';

Style B

This one places a small, low-opacity Unicode arrow just before the subject-line of the linked-to post.



Code:
--- baseline/Sources/Display.php	2011-02-07 16:45:09.000000000 +0000
+++ modified/Sources/Display.php 2024-04-04 00:02:44.000000000 +0000
@@ -230,24 +230,25 @@
  SELECT COUNT(*)
  FROM {$db_prefix}messages
  WHERE ID_MSG < $virtual_msg
  AND ID_TOPIC = $topic", __FILE__, __LINE__);
  list ($context['start_from']) = mysql_fetch_row($request);
  mysql_free_result($request);
  }
 
  // We need to reverse the start as well in this case.
  $_REQUEST['start'] = empty($options['view_newest_first']) ? $context['start_from'] : $topicinfo['numReplies'] - $context['start_from'];
 
  $context['robot_no_index'] = true;
+ $context['requested_msg'] = $virtual_msg;
  }
  }
 
  // Create a previous next string if the selected theme has it as a selected option.
  $context['previous_next'] = $modSettings['enablePreviousNext'] ? '<a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=prev#new">' . $txt['previous_next_back'] . '</a> <a href="' . $scripturl . '?topic=' . $topic . '.0;prev_next=next#new">' . $txt['previous_next_forward'] . '</a>' : '';
 
  // Check if spellchecking is both enabled and actually working. (for quick reply.)
  $context['show_spellchecking'] = !empty($modSettings['enableSpellChecking']) && function_exists('pspell_new');
 
  // Censor the title...
  censorText($topicinfo['subject']);
  $context['page_title'] = $topicinfo['subject'];

Code:
--- baseline/Themes/default/Display.template.php	2010-10-22 01:38:35.000000000 +0000
+++ modified/Themes/default/Display.template.php 2024-04-04 00:05:27.000000000 +0000
@@ -359,33 +359,34 @@
  echo '
  <a href="', $scripturl, '?action=pm;sa=send;u=', $message['member']['id'], '" title="', $message['member']['online']['label'], '">', $settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/im_' . ($message['member']['online']['is_online'] ? 'on' : 'off') . '.gif" alt="' . $message['member']['online']['label'] . '" border="0" />' : $message['member']['online']['label'], '</a>';
  }
  }
  // Otherwise, show the guest's email.
  elseif (empty($message['member']['hide_email']))
  echo '
  <br />
  <br />
  <a href="mailto:', $message['member']['email'], '">', ($settings['use_image_buttons'] ? '<img src="' . $settings['images_url'] . '/email_sm.gif" alt="' . $txt[69] . '" title="' . $txt[69] . '" border="0" />' : $txt[69]), '</a>';
 
  // Done with the information about the poster... on to the post itself.
+ $is_requested_message = isset($context['requested_msg']) && $context['requested_msg'] == $message['id'];
  echo '
  </div>
  </td>
  <td valign="top" width="85%" height="100%">
  <table width="100%" border="0"><tr>
  <td valign="middle"><a href="', $message['href'], '"><img src="', $message['icon_url'] . '" alt="" border="0" /></a></td>
  <td valign="middle">
  <div style="font-weight: bold;" id="subject_', $message['id'], '">
- <a href="', $message['href'], '">', $message['subject'], '</a>
+ ', $is_requested_message ? '<span style="opacity: 30%;">&#8702;&nbsp;</span>' : '', '<a href="', $message['href'], '">', $message['subject'], '</a>
  </div>';
 
  // If this is the first post, (#0) just say when it was posted - otherwise give the reply #.
  echo '
  <div class="smalltext">&#171; <b>', !empty($message['counter']) ? $txt[146] . ' #' . $message['counter'] : '', ' ', $txt[30], ':</b> ', $message['time'], ' &#187;</div></td>
  <td align="', !$context['right_to_left'] ? 'right' : 'left', '" valign="bottom" height="20" style="font-size: smaller;">';
 
  // Can they reply? Have they turned on quick reply?
  if ($context['can_reply'] && !empty($options['display_quick_reply']))
  echo '
  <a href="', $scripturl, '?action=post;quote=', $message['id'], ';topic=', $context['current_topic'], '.', $context['start'], ';num_replies=', $context['num_replies'], ';sesc=', $context['session_id'], '" onclick="doQuote(', $message['id'], ', \'', $context['session_id'], '\'); return false;">', $reply_button, '</a>';

As always, everyone's thoughts/notes/votes are appreciated. Wink

@theymos: Style A doesn't add or remove any markup, so post scrapers (probably) won't be affected by the change. Style B introduces a new <span> element just before the <a> element that wraps the subject-line, so if that's the one you like (assuming that you like either one to begin with), then LoyceV and TryNinja would probably appreciate some notice before you merge it, so that they can tweak their scrapers if necessary.
11  Economy / Games and rounds / Re: [Results 2nd Edition] 🥧 Bitcointalk Pie Baking Contest 🥧 on: April 03, 2024, 11:45:12 AM


Congrats to the winners! Smiley

3 mBTC sent (4cb6051dff10c58898c505028750866bde54cc3216a29fdb22d0d471f46ebaf1).

@GazetaBitcoin: Well done on back-to-back wins! You're a man of many talents!! Cheesy (P.S. Remember to get back to me at some point about the BCA voting; the only way you'll rope me into vote-counting duty next year is by confirming that those two alternative counts I left in the relevant thread didn't contain any mistakes.) Tongue

@RickDeckard: Thanks for organizing this event for a second time. You did a really great job, man! Wink
12  Economy / Reputation / Re: Reee: Which campaign has the most spammers? on: March 11, 2024, 10:01:10 AM
@powerGlove is this possible? I know you're a tech wizard.
I'm not the best person to ask; I don't keep a close eye on that space (AI, that is).

The LLM stuff in particular is pretty underwhelming, IMO: it's like having really convenient access to someone that's read every book in the library, but can only remember some of it, and didn't really understand any of it...

I hope that these types of posts don't become the norm on Bitcointalk: they're seriously tedious to read [1]. It's obvious to me (and many others) when someone's post is either superficially perfect but totally worthless, or when their post isn't worthless (because it has original thinking embedded in it), but it's clearly written at a level that's beyond the author (as in, the presentation is sophisticated, but the ideas are not). In either case (that is, the text was either generated or improved with AI), you're not fooling as many people as you might think, so, why not just relax, and be yourself? I mean, I get not wanting to sound like a dumbass, but if you're not a dumbass, then, that will shine through, trust me, and if you are a dumbass, then, well... that will shine through, too; there's no hiding it, I'm afraid: all the paraphrasing in the world can't make a stupid idea smart (you might succeed in making a stupid idea sound smart, but it will still be a stupid idea).

Anyway, if I were you, I'd stop using Grammarly (they seem to have rebuilt their product, and they're now leaning pretty hard into the "AI revolution").

[1] I've been considering an approach for some time now to get ahead of this kind of non-organic posting: I think giving each member a way to quickly "delete" posts (just from their own point of view) would be cool. But, that's not really an interesting idea on its own, where it gets compelling is when you allow people to divide their own personal modlog into named "channels" that are then made available for other users to subscribe to. So, nutildah, for example, might have one named "AI shitposts" and if I were subscribed to it, then any AI shitpost (in his estimation) that he deletes would be omitted from my view, too. That way, there's some tooling for users to take issues like these into their own hands, and because the moderators themselves aren't involved, no one can really moan about being censored or having their rights violated and suchlike, because it's their peers effectively telling them to shut up. I could also see some campaign managers picking a few very trusted user-modlog-channels to be subscribed to (either all the time, or maybe just when they're counting posts), which would make it easier for them to avoid paying for spam.
13  Bitcoin / Development & Technical Discussion / Re: PY21 - A simple BIP39 mnemonic generator in PYTHON on: March 08, 2024, 01:39:38 AM
Do you think it would be better if I generated more bits of entropy and then keeping 128 of them? Instead of zfill or repeating the process if bits are less than 128.
Yup, in the context of your script, slicing a length-128 string from a larger string of random 1s and 0s would work (that is, it would correct the bias, because the high-order bit would then have a 50/50 chance of being either 1 or 0).

But, the way that you posed that option as an alternative to zfill makes me think you don't fully understand the source of this bias. I hope you don't find the following explanation tiresome, I just know that if it were me in your shoes, I'd really appreciate someone taking pains to help me understand the potential hole in my thinking:

Let's imagine a toy version of this problem where you're trying to generate just 4 (rather than 128) bits of entropy with a coin. Let's not go down the rabbit hole of coin fairness, entropy extraction, and tossing technique. (I have a sometimes-sophomoric, or, as my wife would say, "bloody stupid" sense of humor, especially when I'm in a good mood, so "tossing technique" just gave me the giggles. Don't toss while flipping coins, yeah?) Cheesy

There are only 16 possible ways for 4 coin-tosses-in-a-row to end up, so let's put them all in a table (ignore the last 4 columns for now):

OutcomePatternBinaryDecimalf1($pcv)f2($pcv)f3($pcv)f4($pcv)
#1HHHH111115"0b1111""1111""1111""HHHH"
#2HHHT111014"0b1110""1110""1110""HHHT"
#3HHTH110113"0b1101""1101""1101""HHTH"
#4HHTT110012"0b1100""1100""1100""HHTT"
#5HTHH101111"0b1011""1011""1011""HTHH"
#6HTHT101010"0b1010""1010""1010""HTHT"
#7HTTH10019"0b1001""1001""1001""HTTH"
#8HTTT10008"0b1000""1000""1000""HTTT"
#9THHH01117"0b111""111""0111""THHH"
#10THHT01106"0b110""110""0110""THHT"
#11THTH01015"0b101""101""0101""THTH"
#12THTT01004"0b100""100""0100""THTT"
#13TTHH00113"0b11""11""0011""TTHH"
#14TTHT00102"0b10""10""0010""TTHT"
#15TTTH00011"0b1""1""0001""TTTH"
#16TTTT00000"0b0""0""0000""TTTT"

The first four columns are: 1. the possibility/outcome # (1 through 16, so, every possible outcome accounted for), 2. the heads-or-tails pattern corresponding to each outcome (H = heads, T = tails), 3. the same heads-or-tails pattern but in base-2 (1 = heads, 0 = tails), and 4. the heads-or-tails pattern converted from base-2 into base-10.

The last four columns involve the imaginary variable $pcv (previous column's value) and the following definitions:

Code:
f1 = lambda x: bin(x)
f2 = lambda x: x[2:]
f3 = lambda x: x.zfill(4)
f4 = lambda x: x.replace('0', 'T').replace('1', 'H')

Now, the first thing to think about when looking at that table is if there are any "bad" or "low entropy" outcomes in it? The answer to that is no: as long as each outcome is equally probable, then any given outcome is just as "entropic" as any other outcome. HTTH is just as good as TTTT, savvy? That means that, tempting though it is, it's a mistake to use the string length of the values in the f2($pcv) column to decide whether or not you "have enough entropy" (to be clear, it's a mistake to base that decision on anything about a single outcome). If you discard outcomes whenever len(f2($pcv)) != 4, then you're only ensuring that the pattern will always begin with a heads instead of a tails (check the table to confirm that).

The second thing to think about when looking at that table is if the final patterns in the f4($pcv) column ever disagree with the source patterns in column 2? They don't. So, you can rest assured that the zfill(128) that was present in your original script was correct (that is, it was only restoring 0s that, in some sense, were there from the start, and were "lost" during an int to str conversion). You can/should pat yourself on the back for getting it right the first time. Wink

There are at least two other bugs in your script though (beyond the bias bug, which we'll call Bug #1):

Bug #2

You need a zfill(32) before passing the hexadecimal representation of your entropy into bytes.fromhex (otherwise, you'll occasionally pass it an odd number of nibbles, which will cause it to raise a ValueError).

Bug #3

You need a zfill(256) at the end of the line that calculates your sha256_bin variable (otherwise, your checksum, and therefore the last word of your mnemonic, will be wrong 50% of the time).

For an example, try manually setting your entropy to cc399b43e82bfbc07f2fe3fd1f13ed41.

Your script will spit out the following mnemonic: slow smoke special space sausage then witness wise wonder weasel win lobster

Ian's script (and mine) will spit out this instead: slow smoke special space sausage then witness wise wonder weasel win lion

The reason your wonder weasel only managed to win a lobster instead of a lion, is because you're miscalculating the checksum bits as 1001 instead of 0001. Smiley

(I'm going to be too busy to respond for a while. I'll take a peek at this thread again in a few weeks' time.)
14  Bitcoin / Development & Technical Discussion / Re: PY21 - A simple BIP39 mnemonic generator in PYTHON on: March 06, 2024, 12:23:19 PM
Hello, I just updated the OP with this:

Code:
entropy = bin(int(token_hex(16), 16))[2:]
while len(entropy) != 128:
    entropy = bin(int(token_hex(16), 16))[2:]

so now, if the entropy is less than 128, it repeats the process until it is 128 bits long.
You've introduced a small bias by doing that...

This is a pattern that I see pretty often: an attempt to make things "more secure" that ends up backfiring.

Think of it like this: by predicating that loop on the entropy being exactly 128 bits long, you've removed the possibility of your program ever generating a 128-bit value with the high-order bit set to 0. That means, in hexadecimal terms, your entropy will always start with an 8, 9, A, B, C, D, E, or F (0 through 7 are no longer possible). In BIP39 terms, the first word of your mnemonic will always start with one of the letters L through Z (no matter how many times you run your script, you'll never generate a mnemonic that starts with an A-word, for example).

I think that what you were doing before with the zfill was better. (But, if you change it back, you should be aware that that will reveal a different bug that's hiding in your code: bytes.fromhex always expects a string with an even number of nibbles. That is, bytes.fromhex('abcd') will return b'\xab\xcd', but bytes.fromhex('abc') won't return b'\x0a\xbc', as you might expect, instead, it will raise a ValueError. So, there's a ~6% chance that your script will fail on any given invocation. Try it yourself, run the original version of your script again and again in a terminal and you'll encounter that problem eventually and get a traceback that'll point to the offending line.)

Please don't feel discouraged. It's cool that you're learning Bitcoin by programming little bits and pieces of it yourself, and then sharing your code: that's a really effective way to learn in my experience, so keep it up, dude. Wink

I don't know about you, but I really appreciate seeing other people's takes on problems that I've recently solved myself, especially if they involve techniques that I may not be familiar with. So, here's my take on a 12-word BIP39 mnemonic generator in Python:

Code:
#!/usr/bin/env python3

# Don't use this for anything serious; it *probably* works as intended, but I haven't tested it much (I wrote it quickly for apogio).

import base64

import lzma

import secrets

import hashlib

bip39_words: list[str] = lzma.decompress(base64.b85decode('{Wp48S^xk9=GL@E0stWa761SMbT8$j;4?ZDBwYY7n21WR2~SMNj7l(<JR*YqdhorTGI^h5s6rBe;k9*`P;vADxW!uq6ud9G`Ryq|uIakUrKX0S{>^H;DHJAH%e&gKef~1EXSD0Us}VywB$hQSCL24wlCsKYCV<&UARZHOh)&>5DZ-~ie;w#}??6<JOl|mq9eKdcew;FDEcSIuPSsz9ifo`zRLj%vg=z0~cu*vAMA6cb5GSaXO7n>$%xTl&8@gxbgANqLq@*=qXFu|h=a2+%Xss$^84V29ubWU|Jis}ZeS^SfW}jww7nw9K&Cx%HKy;0Y37#)`+p3zY1bZ`7k+YIMR3u^uY^9ccN{kp=S?u6N4zisDC8gkIJo$^^m6wM^a$8H3bAYEsAIc966#xe{9j&hY0zxEiT${N!QqS^qX$el?jg>&rnPf$K-yrI;)DRZN%5N67_SO#n=yj@!>$4Hz)evAV5=sYEQS$z7tp@GUj@>>S;S=L=!OK{Jtif0|-p%w0w#bxt71|pkbpS}&H*pv#^=Et7p$ITGaVb29^yoJQ!zsLIcy9`T(hCW;CliZjzHlUHk5C~^7<s${pyjkGSHqDb$3%6Ql)O^B*BWTyC_6sP9t*>_nJ1EUY6*S-;1uIhueo7A2kS$(TLIuv1k&86r%i)z0*-`orY@!pD9im@rths?CuQ90QmSY+!iP@8%nQ%d2Mnv#BVLo#w-6V9c5aG@e2d9O-C!?y>GSCUs5I^54+iV}u#dj~6%nU^oJ!C{P_)~vNh$*wcdG_&J;l!^sRRdSF->(8X?IogT__SWD7&M;TnqE9)DN*23c>sJsQxXi3;5J6DDh(_H0P%C?nxktxwmY48AW19?`wuF+F(0QfgOO}Ojr7j3KfbBaY+=fiqt?}oNK#yaFde;{ARhlk@2*Yh;H++vcQgmvVuv4wKzHFO&Ru(cfJW=QuOvQu>M0i6U6^04<N3c${Mzk9WOh3^h|Bx=-7U{ac`Tojgk$wjm&2*;dbo8XCFVx7vftB*T#;^eJ6Rv>JXbcxiR-dL7D_vpPfb6ZAR`2uHBG)agXV6VC2h%>;B+vg*v^Xsw3(RIEe8ls@DQbyP-deH3-Hb)O_0nXteO2F_5u@cpMV^*D4qiuN<at4zRaHb_%+w4o!3z1x|G(S0Q4-8w6cmtHv6}zRL00x0v3*+4}~6x$RUNbD{rKGJe~n>SK-`U!)6zJN$A6{Hhkj+D@VTMcYtaNfsu>Wn{j~^6xu22NN$^PmEmEl*lr<Iq~?ayQ?Mq+_SAf1u3uKb)!FG*pd}Y`;RydQ_jhBV3IJyYbiO@nL6xCOD-B1(}2VUEWj<scNhas{F%K!5FcMIvQCKN3TK-vuB#u@5a)O*CA;1@r33JxK6ZcOff;l0Rb)DDIUIdWU2Lrg_nT~!OmX{$$FBD%4V7TQ-RCP1rhG&giyB}eTE*eNPEK0{F<j^TrG8NOn8ylmgdaL)Ull(-8%}RdS!ufXK%-KAb8qY!&DKNMg|}L7tSo2p<DN>~k&2zu1nq>@!y1*ypM67Y`iGod_AKq<bEWq&l@ZliOe+DODTaDj3TR|GzSq{ygZN5;^38}PCZxI0%CH=5UB@k%2Mgh6zQ_-s+Kb_kVRfhG^$Y0oOW2zmlc2Ay=$M;wjEA_a!!f;^Si^ZbTV#OV)if)Fr5(zM@iXYVO_6G(ooKRa&RFfYbR~k(4Pj|mmG17{dcNunx0U|P=4}B;hEo8nj=OBMER5&p=;yBKPt~g@_oib!r>_r-*jlOyBOA{KNrg}5Ac0RMtO%k2jizS0XF!`YtPkPQ`ImjU%rS#KF}#sq+r|(L72zb1TC2;dOS~ikeihcHtjY!p{N`Z*Q+Cx&oG&bsXVozbAQj&R&`HmZr4)YnH?nY^m}If@mU2OBIw{C4^z1meuyEu;2#(@;2Osppn@|UV6U2xJvDC)cQ<bcDUd=$-N=fQT+iEI(H+Q?DeL|cvnMVG}N$??c0$9l~YqMpU!4~#FrCo0^q9I#GD;e^^M&&}sesOl$cqh^&2$>`(jFILY>=0`+;VLBTS|!3}0QE&E(EzgOrO8NIJOzT>^p}ISTqQSGa0npbKH^kf2A+%8xf8FWGBc;!h)Vd2IuWu!v6lNZ{yVZpjQ$0$y<=)J7sK?*>Vv>n?iROPvbL3X*R&VFHz8cX8#e-z!_RyxYIU<(6gQ_4b(OE?b)!x=RJf;~4bi0p=4VlSVImRd!l7a7cE+)`2rKn4pAw_LqwZx&RWLHTaB*I{-F6zLlIF;yxKK4;IvNZ6t|?^jhonkM3>Vwmf(Vk0@EB2?UeVdB;Yb|Kd;W%R3JWCWlnF(sPu^{(m8)`sb8503#A0k-zZPD`M9T*&C+y`J9JD_0->(14<!m6W^O9yW6f0a!h*#%-1<bd5h^ziFcpp3$isdCU5BaIyH%tA&lv4a|IxD^z(ppfd%c?gp?Gm_dVP{9B9W#N5rKm47h>W>=Y!~_Y8&AfDjoh)LpK6g5a&}4OZ^ryKhc3JF+hme1Be32X32Sb{U6qNKLDpmXx~u;TgGnn6m@#M;b$CnfIq7~tRFqGO>Nx0>tP_m`QW>a`i!TRAZ%h<ymlLNjB`3I{j`y3}_zXntLR;@~&3)~<SBdxVe0Vg1MkQ0{lkTd<V%5*B=I_`q1$F~Qo;N&nXC7gDm!Z10oRnT>#-uM7BMo<Ke_<Kq)X1`x)B&Tdx7}z^L;s$YvfhGzZb!JuDEVsZ{LZI)c>C{dn$iVRKwHz-B)^APT2#W+FMad$_X#-BM+bg%Rf2oYfSf2eeAFo8OyWD>GfI>IduIKFJlGhOb<V;Yf~s`G!GBuy(f*5CW8~~c@!93tes7Fv+xF^laoI;vh^GK8{~-#$l}0k8xt46LDlynQhn%mpy?WuiuL+BT|KVa4iu(b)bcYP332V(60%B)Cf6xDm6x1cy=}#}NP4<RI&@N3E1HwLQ8&=yzW5DJ>tF)718Oq4s#zK*RIUGa7k|k$4HOG>9RiJM;@2yK=NBbEC6*Kd&2VV<iJZVy`q}J4-fIAR*IEm-W-NnbBMc#b?aqo*UzFd_rO0R?FJ!b=1U)c-%YZf(a552_x+NG~95C6Wn-z7rXYz#GCH#5xo1SKQEpVCZu?gKLp>qPUxacYwN@0mswW469o32{DJf=y*CU9V7)?7loOwYQ9_8JLIotvhv~&Wz%i0Z!05V1|QY@4L4jp;%<jo0f%IrpPHnzrf*|6Y7jJ9)F6*Of5>JOM*dix({v*!!8Z=C&nDTk&RqqACXz9fO2kwe61+}5DG1WkN7Hp0~$f1@=n~e=))pi@!)Tac?masVzC?^p0gZWN%vmU+jb}&3M!$|S+EHr+mGIU0i;)%3RPlu5L-Y@1H-swrrU`hjMq%4nK}+=J_f-N8;rWk>@YoZbR~hDP?=07HhnK7Yha4mRW0EOgl>Q5h&N?zt#<Q0@0*u}Wxt8X07JQtoelXwG`h;N8T#%3L&tG0GNEUaabE7}x+<Lgx`Z&u4!lj*=snoQ$;S(g#IGnq-t_g+aeXg(;3P=6(JW$!nYc^o*ime*%~>)JjrC*Ls77Nt7Cp(!Js+pn%*(NBy}Z)CsN&bjh^gC{rL~LauR(COgtSd>bE4IHnvS$>ovdGkG|VU^PL1*cw*dz6l9aH($Kat5LTU9BKbaVBD}e6ZT~A9kcNB{KYbj~K(7<a;8LX;x(jRm@9cLv$#Ubz)U+r%6B=(k#J4~F{f2Dp|S=!P9+VIP!E0)0ACz+VZ1ocmMTx{#U%TEl$b)$F#cXLOkdjKf96euOn^vW>{m$+D85|@#74?ms4(<invY(H$jEQ@mBDlK!7g0v_6PbZsmKeG&CZ_=OxUAWu5noVNzVGPSdTV|)SfD>7n$~>n>pTX`Y%sMm%<C%kmjvbs2e9LX<Xwf`1468A!!DT?({~n(tbR2T+BP&;2T-gLIDE6WyR!4c^kVJkqiP=y%%%!oFop}TE2PE`;yCH?lBC;}cOBDBEgoY8|c0PvpKy4m$AY+7VB#&H!!?B!AN@NJ|@m6sk4c&+a)?7~B)okfH0O<%izMeJF%U32P2``~k=g*GgtsAigqU>q37$sm}KmutW;E;=^VLusQ?lO6n`0TFjQAc`g)`IHG4G<%c8sRkb*u>;O8etvo0@=>SAhL77BuaNdi|LI0L>I=<SB0FAKD`FJgI`1dUT(!pnk|Fqh#3|&RGc&2Zn4PvdB#)D8VV=k>?nF^ZO%Qae<~ZG5pz#9ZAFRpFG%-Y8{Rmd*f!oYYX*iSsjQjl`TqEOaP?mMm@Y?2^|vWS<d{Wgc+ei9L|6u@Mq+Ca2Ye|jk<aZp!HU7svd6bVPRW5f2-cA#!#+?e5;zB^Yv-jciE^4X@vk&3PUvMV`XONl0g075#_BW}IKzoR+MK{H*tr?MSo$t78He^ujn2A-{c_4kuR}oR=DWs1M&H%)+tT7#;p6YG>Qqhp#Ro~xw3f(fI6x=i)ocaQIs|Dvg?AX3|G_enP}P7N_?{nab4X|xO;Bvcny;Mgm&n;}#^N?ht)QPa=pK=OJT&Nc@`)s2y%=xX{IUe}??&l&?LPPJ^bTBK*!;mW_~-<`zW8)>h0fy7dX3AT&!LmnKb*<tO`uM31<E}QIi4(}F}*{;`DAc_54LkLj<F~)gS_T9>*OFB-IsN$aD^LPcO{na32FZCS;P!p)sbnR{<1H8&Io*XH>^%{X5H?vtC_<5Yl)4H{;T?eR=xo4zMgGxrMG9p@1UtXLg|+1$C`Eo$g|L<Yt^E6lO6<?C7)VU#sV|G#;?62fC+<Stf5u}&+HgfUyeK(+kt_|hB~wI!OX|rIDi8kN5ZTptl?S!(d)!^kVogoZ;Jy6A0lGcjW*8E7^RvXr9`%t#!wlS_{uYo3bIrq*+sg!XgdRxFP?|RU?>x#e~g(<!|jcAl*qWW5zFc-Cp!f#!4`-P!JKI$%ARE-?%J#N76u(2k~%CFlA;w~_Ya!UPM-^Y-*@X9d&bT=b@Bwf{NF;xPk+}}5b@n^AL<#=X$kmPGY}~)i!?Id#94?7+&Q}rbtqs<e$ZmK#mehUtZ4_kmP^*D*5g48xD`p-tL`#h;Ejz$C~bzq0RK6<dTPL14$y`OE%LvEP-YHm0IeHmaf&pqN@c~lk&p>V3q>l<cvC>QZ}FvGh-tAjMoOTg=^RKYDoUIaU;*WhzRh@}-9nE11k#_w`r+2d7A@2gw`AU7O5Nt!32Lo0+$xOMdW67%8<KSxW5_hKx+mzyiB~Xy_TH`h4@;WRx{mgu5ISw;cds3N5;RceKJ2smo_&0j=uTKzWkG%Pu*a%TjraU^)b@IqT^Cear{D9!^dpbhC#I+yMXT4-ZH3gx6?#;j-QayOMtWK2>`w@1^w*jNQ!&uSKfge%M28%OO{Ws}_mw5k2)UX#8EE`$J&ery(PFRTPRe+8ME$%+0(8%omCTo5iz3vJ+obP2NWfe{?nUg>q@;gbs0zwWscj2jCr*C32c$lxQ+=4Exp3VPq2xzPUNKpQcy~h@N$a;FQxng%f-{r<UClnTh9ydm{A5_q{y0Eu!Gm=NpL<$<kbhpOSka0Fptz<~z7f9}|C(xH4#M#c*jMr(w<S_)isH-o4PWu3RNb$D*#lbp1>N>P_yc?!P-}$P_?H9E>1g+ea9y4H{m9vJ169o>9(N|lI$0M}Uv<HhktAiB(G5f;!YMp;EL|)g@Xd!c`ZQ!%qXO<i+qr%DB8lNVf50y0>$@25BS_d%2FJ&gv3Sf0%>(OD;tg#mF(VF6GK7(DK*r9%wu?|AusPFcGjp-H&mfb5eGek@LU1s(Jk*`7!ur*UU_J@K4Ie>Su?<+apZL;q7d8Z?MJJ{Ew(x%93*MI1EI#&X%iGGdJ9!(|UhI+i*`+>jZn?h;K-w}>M~lFsBSVmjSI*Py=BlvSgU<FZ^kK7TE7492B40FV>|RO*TT1Fa$2+@ie+S506rPh`84?h7$4MDe6a2Od4|YI$7k1`A|K_FixJ(d#P~6R>uB8!?^*`G~OIz3q_gyhleNle+a{7n>fPT}9i)}$yGwM~j_|YsLYVAJhKBb?=7uZ*07(_qNd_N5&8E8#c2Wq82=IEJY5s<tvxtANYUK>;WXJU|dRpVRJ1*7P<K2BqFho5sZb9;f#Fa}mkJyugV{pzo~(v;S*x4Ud@#36SMN4NU0e%Wuby<lQ~v!enb5G3wB+uzj^T5?dm0Q|lG{%y1t)C^@)jw**HtXvk`DHWfkux=43HqlH`UDhI<W9HoH!z&b20*n8<{YKY8YUCu+cW-jj;p$f4l7ZV)KPx8?pzgX4*5~JA^Vxi9xiVdLAJh}?MjU;xUVu1C-b>~Kwj{V<?j3e4K`8fl0+$0=Vv{vSC!7tpAn!|enyUN7FO2A&_W)R%XD@N=#HDZ}&4S(V7`PjSE#ElpYR7qEvP<b!_Zz<$)8b$6bIENcS`0ATm^j}wB_RSVl;Gr-gH^sJp+4a62hKv_@J#f;QF0~_g9TU2Gr(Mhcq{jaI`x7LV*`QpT-T8>%l9Wc;(#+4XM)!#giyS6FL_7O`DvOWUo6zO(FggIxM-;oSqeP>I^_M`6)E1WsCDM2O~XMf-t1*O+P)yvRgmiUb)kFO@;xD+2G{@qPq#);P$7Wt00F=#yJi3YrO+j%vBYQl0ssI200dcD')).decode('ascii').split('\n')

entropy: int = secrets.randbits(128)

checksum: int = hashlib.sha256(entropy.to_bytes(16, 'big')).digest()[0] >> 4

combined: int = (entropy << 4) | checksum

mnemonic: list[str] = [bip39_words[(combined >> (index * 11)) & 2047] for index in reversed(range(12))]

print(f'Entropy (128 bits, hexadecimal): {hex(entropy)[2:].zfill(32)}')

print(f'Checksum (4 bits, binary): {bin(checksum)[2:].zfill(4)}')

print(f'Mnemonic (12 words, english): {" ".join(mnemonic)}')

And here's the same script but generalized to produce either 12, 15, 18, 21, or 24-word mnemonics:

Code:
#!/usr/bin/env python3

# Don't use this for anything serious; it *probably* works as intended, but I haven't tested it much (I wrote it quickly for apogio).

import base64

import lzma

import secrets

import hashlib

bip39_words: list[str] = lzma.decompress(base64.b85decode('{Wp48S^xk9=GL@E0stWa761SMbT8$j;4?ZDBwYY7n21WR2~SMNj7l(<JR*YqdhorTGI^h5s6rBe;k9*`P;vADxW!uq6ud9G`Ryq|uIakUrKX0S{>^H;DHJAH%e&gKef~1EXSD0Us}VywB$hQSCL24wlCsKYCV<&UARZHOh)&>5DZ-~ie;w#}??6<JOl|mq9eKdcew;FDEcSIuPSsz9ifo`zRLj%vg=z0~cu*vAMA6cb5GSaXO7n>$%xTl&8@gxbgANqLq@*=qXFu|h=a2+%Xss$^84V29ubWU|Jis}ZeS^SfW}jww7nw9K&Cx%HKy;0Y37#)`+p3zY1bZ`7k+YIMR3u^uY^9ccN{kp=S?u6N4zisDC8gkIJo$^^m6wM^a$8H3bAYEsAIc966#xe{9j&hY0zxEiT${N!QqS^qX$el?jg>&rnPf$K-yrI;)DRZN%5N67_SO#n=yj@!>$4Hz)evAV5=sYEQS$z7tp@GUj@>>S;S=L=!OK{Jtif0|-p%w0w#bxt71|pkbpS}&H*pv#^=Et7p$ITGaVb29^yoJQ!zsLIcy9`T(hCW;CliZjzHlUHk5C~^7<s${pyjkGSHqDb$3%6Ql)O^B*BWTyC_6sP9t*>_nJ1EUY6*S-;1uIhueo7A2kS$(TLIuv1k&86r%i)z0*-`orY@!pD9im@rths?CuQ90QmSY+!iP@8%nQ%d2Mnv#BVLo#w-6V9c5aG@e2d9O-C!?y>GSCUs5I^54+iV}u#dj~6%nU^oJ!C{P_)~vNh$*wcdG_&J;l!^sRRdSF->(8X?IogT__SWD7&M;TnqE9)DN*23c>sJsQxXi3;5J6DDh(_H0P%C?nxktxwmY48AW19?`wuF+F(0QfgOO}Ojr7j3KfbBaY+=fiqt?}oNK#yaFde;{ARhlk@2*Yh;H++vcQgmvVuv4wKzHFO&Ru(cfJW=QuOvQu>M0i6U6^04<N3c${Mzk9WOh3^h|Bx=-7U{ac`Tojgk$wjm&2*;dbo8XCFVx7vftB*T#;^eJ6Rv>JXbcxiR-dL7D_vpPfb6ZAR`2uHBG)agXV6VC2h%>;B+vg*v^Xsw3(RIEe8ls@DQbyP-deH3-Hb)O_0nXteO2F_5u@cpMV^*D4qiuN<at4zRaHb_%+w4o!3z1x|G(S0Q4-8w6cmtHv6}zRL00x0v3*+4}~6x$RUNbD{rKGJe~n>SK-`U!)6zJN$A6{Hhkj+D@VTMcYtaNfsu>Wn{j~^6xu22NN$^PmEmEl*lr<Iq~?ayQ?Mq+_SAf1u3uKb)!FG*pd}Y`;RydQ_jhBV3IJyYbiO@nL6xCOD-B1(}2VUEWj<scNhas{F%K!5FcMIvQCKN3TK-vuB#u@5a)O*CA;1@r33JxK6ZcOff;l0Rb)DDIUIdWU2Lrg_nT~!OmX{$$FBD%4V7TQ-RCP1rhG&giyB}eTE*eNPEK0{F<j^TrG8NOn8ylmgdaL)Ull(-8%}RdS!ufXK%-KAb8qY!&DKNMg|}L7tSo2p<DN>~k&2zu1nq>@!y1*ypM67Y`iGod_AKq<bEWq&l@ZliOe+DODTaDj3TR|GzSq{ygZN5;^38}PCZxI0%CH=5UB@k%2Mgh6zQ_-s+Kb_kVRfhG^$Y0oOW2zmlc2Ay=$M;wjEA_a!!f;^Si^ZbTV#OV)if)Fr5(zM@iXYVO_6G(ooKRa&RFfYbR~k(4Pj|mmG17{dcNunx0U|P=4}B;hEo8nj=OBMER5&p=;yBKPt~g@_oib!r>_r-*jlOyBOA{KNrg}5Ac0RMtO%k2jizS0XF!`YtPkPQ`ImjU%rS#KF}#sq+r|(L72zb1TC2;dOS~ikeihcHtjY!p{N`Z*Q+Cx&oG&bsXVozbAQj&R&`HmZr4)YnH?nY^m}If@mU2OBIw{C4^z1meuyEu;2#(@;2Osppn@|UV6U2xJvDC)cQ<bcDUd=$-N=fQT+iEI(H+Q?DeL|cvnMVG}N$??c0$9l~YqMpU!4~#FrCo0^q9I#GD;e^^M&&}sesOl$cqh^&2$>`(jFILY>=0`+;VLBTS|!3}0QE&E(EzgOrO8NIJOzT>^p}ISTqQSGa0npbKH^kf2A+%8xf8FWGBc;!h)Vd2IuWu!v6lNZ{yVZpjQ$0$y<=)J7sK?*>Vv>n?iROPvbL3X*R&VFHz8cX8#e-z!_RyxYIU<(6gQ_4b(OE?b)!x=RJf;~4bi0p=4VlSVImRd!l7a7cE+)`2rKn4pAw_LqwZx&RWLHTaB*I{-F6zLlIF;yxKK4;IvNZ6t|?^jhonkM3>Vwmf(Vk0@EB2?UeVdB;Yb|Kd;W%R3JWCWlnF(sPu^{(m8)`sb8503#A0k-zZPD`M9T*&C+y`J9JD_0->(14<!m6W^O9yW6f0a!h*#%-1<bd5h^ziFcpp3$isdCU5BaIyH%tA&lv4a|IxD^z(ppfd%c?gp?Gm_dVP{9B9W#N5rKm47h>W>=Y!~_Y8&AfDjoh)LpK6g5a&}4OZ^ryKhc3JF+hme1Be32X32Sb{U6qNKLDpmXx~u;TgGnn6m@#M;b$CnfIq7~tRFqGO>Nx0>tP_m`QW>a`i!TRAZ%h<ymlLNjB`3I{j`y3}_zXntLR;@~&3)~<SBdxVe0Vg1MkQ0{lkTd<V%5*B=I_`q1$F~Qo;N&nXC7gDm!Z10oRnT>#-uM7BMo<Ke_<Kq)X1`x)B&Tdx7}z^L;s$YvfhGzZb!JuDEVsZ{LZI)c>C{dn$iVRKwHz-B)^APT2#W+FMad$_X#-BM+bg%Rf2oYfSf2eeAFo8OyWD>GfI>IduIKFJlGhOb<V;Yf~s`G!GBuy(f*5CW8~~c@!93tes7Fv+xF^laoI;vh^GK8{~-#$l}0k8xt46LDlynQhn%mpy?WuiuL+BT|KVa4iu(b)bcYP332V(60%B)Cf6xDm6x1cy=}#}NP4<RI&@N3E1HwLQ8&=yzW5DJ>tF)718Oq4s#zK*RIUGa7k|k$4HOG>9RiJM;@2yK=NBbEC6*Kd&2VV<iJZVy`q}J4-fIAR*IEm-W-NnbBMc#b?aqo*UzFd_rO0R?FJ!b=1U)c-%YZf(a552_x+NG~95C6Wn-z7rXYz#GCH#5xo1SKQEpVCZu?gKLp>qPUxacYwN@0mswW469o32{DJf=y*CU9V7)?7loOwYQ9_8JLIotvhv~&Wz%i0Z!05V1|QY@4L4jp;%<jo0f%IrpPHnzrf*|6Y7jJ9)F6*Of5>JOM*dix({v*!!8Z=C&nDTk&RqqACXz9fO2kwe61+}5DG1WkN7Hp0~$f1@=n~e=))pi@!)Tac?masVzC?^p0gZWN%vmU+jb}&3M!$|S+EHr+mGIU0i;)%3RPlu5L-Y@1H-swrrU`hjMq%4nK}+=J_f-N8;rWk>@YoZbR~hDP?=07HhnK7Yha4mRW0EOgl>Q5h&N?zt#<Q0@0*u}Wxt8X07JQtoelXwG`h;N8T#%3L&tG0GNEUaabE7}x+<Lgx`Z&u4!lj*=snoQ$;S(g#IGnq-t_g+aeXg(;3P=6(JW$!nYc^o*ime*%~>)JjrC*Ls77Nt7Cp(!Js+pn%*(NBy}Z)CsN&bjh^gC{rL~LauR(COgtSd>bE4IHnvS$>ovdGkG|VU^PL1*cw*dz6l9aH($Kat5LTU9BKbaVBD}e6ZT~A9kcNB{KYbj~K(7<a;8LX;x(jRm@9cLv$#Ubz)U+r%6B=(k#J4~F{f2Dp|S=!P9+VIP!E0)0ACz+VZ1ocmMTx{#U%TEl$b)$F#cXLOkdjKf96euOn^vW>{m$+D85|@#74?ms4(<invY(H$jEQ@mBDlK!7g0v_6PbZsmKeG&CZ_=OxUAWu5noVNzVGPSdTV|)SfD>7n$~>n>pTX`Y%sMm%<C%kmjvbs2e9LX<Xwf`1468A!!DT?({~n(tbR2T+BP&;2T-gLIDE6WyR!4c^kVJkqiP=y%%%!oFop}TE2PE`;yCH?lBC;}cOBDBEgoY8|c0PvpKy4m$AY+7VB#&H!!?B!AN@NJ|@m6sk4c&+a)?7~B)okfH0O<%izMeJF%U32P2``~k=g*GgtsAigqU>q37$sm}KmutW;E;=^VLusQ?lO6n`0TFjQAc`g)`IHG4G<%c8sRkb*u>;O8etvo0@=>SAhL77BuaNdi|LI0L>I=<SB0FAKD`FJgI`1dUT(!pnk|Fqh#3|&RGc&2Zn4PvdB#)D8VV=k>?nF^ZO%Qae<~ZG5pz#9ZAFRpFG%-Y8{Rmd*f!oYYX*iSsjQjl`TqEOaP?mMm@Y?2^|vWS<d{Wgc+ei9L|6u@Mq+Ca2Ye|jk<aZp!HU7svd6bVPRW5f2-cA#!#+?e5;zB^Yv-jciE^4X@vk&3PUvMV`XONl0g075#_BW}IKzoR+MK{H*tr?MSo$t78He^ujn2A-{c_4kuR}oR=DWs1M&H%)+tT7#;p6YG>Qqhp#Ro~xw3f(fI6x=i)ocaQIs|Dvg?AX3|G_enP}P7N_?{nab4X|xO;Bvcny;Mgm&n;}#^N?ht)QPa=pK=OJT&Nc@`)s2y%=xX{IUe}??&l&?LPPJ^bTBK*!;mW_~-<`zW8)>h0fy7dX3AT&!LmnKb*<tO`uM31<E}QIi4(}F}*{;`DAc_54LkLj<F~)gS_T9>*OFB-IsN$aD^LPcO{na32FZCS;P!p)sbnR{<1H8&Io*XH>^%{X5H?vtC_<5Yl)4H{;T?eR=xo4zMgGxrMG9p@1UtXLg|+1$C`Eo$g|L<Yt^E6lO6<?C7)VU#sV|G#;?62fC+<Stf5u}&+HgfUyeK(+kt_|hB~wI!OX|rIDi8kN5ZTptl?S!(d)!^kVogoZ;Jy6A0lGcjW*8E7^RvXr9`%t#!wlS_{uYo3bIrq*+sg!XgdRxFP?|RU?>x#e~g(<!|jcAl*qWW5zFc-Cp!f#!4`-P!JKI$%ARE-?%J#N76u(2k~%CFlA;w~_Ya!UPM-^Y-*@X9d&bT=b@Bwf{NF;xPk+}}5b@n^AL<#=X$kmPGY}~)i!?Id#94?7+&Q}rbtqs<e$ZmK#mehUtZ4_kmP^*D*5g48xD`p-tL`#h;Ejz$C~bzq0RK6<dTPL14$y`OE%LvEP-YHm0IeHmaf&pqN@c~lk&p>V3q>l<cvC>QZ}FvGh-tAjMoOTg=^RKYDoUIaU;*WhzRh@}-9nE11k#_w`r+2d7A@2gw`AU7O5Nt!32Lo0+$xOMdW67%8<KSxW5_hKx+mzyiB~Xy_TH`h4@;WRx{mgu5ISw;cds3N5;RceKJ2smo_&0j=uTKzWkG%Pu*a%TjraU^)b@IqT^Cear{D9!^dpbhC#I+yMXT4-ZH3gx6?#;j-QayOMtWK2>`w@1^w*jNQ!&uSKfge%M28%OO{Ws}_mw5k2)UX#8EE`$J&ery(PFRTPRe+8ME$%+0(8%omCTo5iz3vJ+obP2NWfe{?nUg>q@;gbs0zwWscj2jCr*C32c$lxQ+=4Exp3VPq2xzPUNKpQcy~h@N$a;FQxng%f-{r<UClnTh9ydm{A5_q{y0Eu!Gm=NpL<$<kbhpOSka0Fptz<~z7f9}|C(xH4#M#c*jMr(w<S_)isH-o4PWu3RNb$D*#lbp1>N>P_yc?!P-}$P_?H9E>1g+ea9y4H{m9vJ169o>9(N|lI$0M}Uv<HhktAiB(G5f;!YMp;EL|)g@Xd!c`ZQ!%qXO<i+qr%DB8lNVf50y0>$@25BS_d%2FJ&gv3Sf0%>(OD;tg#mF(VF6GK7(DK*r9%wu?|AusPFcGjp-H&mfb5eGek@LU1s(Jk*`7!ur*UU_J@K4Ie>Su?<+apZL;q7d8Z?MJJ{Ew(x%93*MI1EI#&X%iGGdJ9!(|UhI+i*`+>jZn?h;K-w}>M~lFsBSVmjSI*Py=BlvSgU<FZ^kK7TE7492B40FV>|RO*TT1Fa$2+@ie+S506rPh`84?h7$4MDe6a2Od4|YI$7k1`A|K_FixJ(d#P~6R>uB8!?^*`G~OIz3q_gyhleNle+a{7n>fPT}9i)}$yGwM~j_|YsLYVAJhKBb?=7uZ*07(_qNd_N5&8E8#c2Wq82=IEJY5s<tvxtANYUK>;WXJU|dRpVRJ1*7P<K2BqFho5sZb9;f#Fa}mkJyugV{pzo~(v;S*x4Ud@#36SMN4NU0e%Wuby<lQ~v!enb5G3wB+uzj^T5?dm0Q|lG{%y1t)C^@)jw**HtXvk`DHWfkux=43HqlH`UDhI<W9HoH!z&b20*n8<{YKY8YUCu+cW-jj;p$f4l7ZV)KPx8?pzgX4*5~JA^Vxi9xiVdLAJh}?MjU;xUVu1C-b>~Kwj{V<?j3e4K`8fl0+$0=Vv{vSC!7tpAn!|enyUN7FO2A&_W)R%XD@N=#HDZ}&4S(V7`PjSE#ElpYR7qEvP<b!_Zz<$)8b$6bIENcS`0ATm^j}wB_RSVl;Gr-gH^sJp+4a62hKv_@J#f;QF0~_g9TU2Gr(Mhcq{jaI`x7LV*`QpT-T8>%l9Wc;(#+4XM)!#giyS6FL_7O`DvOWUo6zO(FggIxM-;oSqeP>I^_M`6)E1WsCDM2O~XMf-t1*O+P)yvRgmiUb)kFO@;xD+2G{@qPq#);P$7Wt00F=#yJi3YrO+j%vBYQl0ssI200dcD')).decode('ascii').split('\n')

mnemonic_length: int = 12

assert mnemonic_length in {12, 15, 18, 21, 24}

mnemonic_factor: int = mnemonic_length // 3

entropy: int = secrets.randbits(mnemonic_factor * 32)

checksum: int = hashlib.sha256(entropy.to_bytes(mnemonic_factor * 4, 'big')).digest()[0] >> (8 - mnemonic_factor)

combined: int = (entropy << mnemonic_factor) | checksum

mnemonic: list[str] = [bip39_words[(combined >> (index * 11)) & 2047] for index in reversed(range(mnemonic_length))]

print(f'Entropy ({mnemonic_factor * 32} bits, hexadecimal): {hex(entropy)[2:].zfill(mnemonic_factor * 8)}')

print(f'Checksum ({mnemonic_factor} bits, binary): {bin(checksum)[2:].zfill(mnemonic_factor)}')

print(f'Mnemonic ({mnemonic_length} words, english): {" ".join(mnemonic)}')
15  Other / Meta / Re: [Results 2023] Bitcointalk Community Awards 🏆 on: March 01, 2024, 11:59:37 PM
Thank you again for asking this question. And, as icopress already said, maybe next year you can give a hand of help too?  Wink
Sure. If it turns out I'm right, then I'll help next year. If it turns out I'm not, then you don't need my help. Cheesy

(...)
Thanks for that really nice post, man; it made me smile! Yeah, my merit-to-post ratio probably screws me out of merit sometimes. I remember once sending a PM to TSC (TP back then) asking for his advice about a post of mine that didn't get merited. I think I even asked him (paraphrasing): "Do you reckon some people think: Fuck that guy, he has enough already!". Grin (I do appreciate getting merit, and I like having sMerit to spend, so don't be too stingy with me, yeah? Same goes for the rest of you tight-fisted bastards.) Tongue

Let me know if I can make you a special Bitcoin NFT to commemorate your achievements; you might not be able to sell it for anything, but its the best I can do.
Hmmm... a minted-by-nutildah PowerGlove NFT? Are you trying to set me up for an early retirement? I mean, that'll be worth a fleet of Lambos in a few years' time!! (In all seriousness, thanks for the kind offer, I appreciate it, but your post was more than enough for me.)
16  Other / Meta / Re: [Results 2023] Bitcointalk Community Awards 🏆 on: March 01, 2024, 03:43:26 PM
Big ol' speeches should be for the people with 1st-place finishes, so I'll just say: Thanks to everyone who voted for me (really, it makes me smile), and congratulations to all the winners!!

@o_e_l_e_o: We really miss you. I hope you're happy/comfortable wherever you are. You'll be remembered fondly around here for a very long time. Cry

@icopress: Thanks for organizing this yet again, you're awesome, man! Smiley (And thanks for sending my prize to derBowler, another awesome dude.)

@GazetaBitcoin: Were you responsible for counting the votes? If so, thanks for helping icopress (seriously), but I have to ask: Were you maybe drinking on the job, friend? Too much plastic-bottled wine? Tongue (The reason I ask is that if I count the votes myself I get slightly different results than yours. Maybe I'm drinking too much, I don't know; see below.) Wink

I count 26 "Bitcointalk Ninja" votes for me (not 27): NotATether, Woodie, criptoevangelista, dkbit98, jeraldskie11, nakamura12, Charles-Tim, SatoPrincess, Husna QA, Nheer, joker_josue, Lafu, AHOYBRAUSE, julerz12, Jawhead999, m2017, Amphenomenon, TryNinja, sabotag3x, Ambatman, Foxpup, famososMuertos, LoyceV, FatFork, Potato Chips, darxiaomi.

I count 15 "Discovery of the Year" votes for me (not 14): Lillominato89, Crypto Library, 2Pizza410000BTC, Bitcoin_people, Peanutswar, wmaurik, nakamura12, hosseinimr93, nutildah, BlackHatCoiner, $crypto$, Compromise me, Coin_trader, lovesmayfamilis, GazetaBitcoin.

Hopefully, I'm just missing some detail/rule, because if the first two things I check are wrong, that usually means there'll be more mistakes if I keep looking. These two mistakes are small, and they wouldn't have affected my outcomes, but maybe a more thorough check will reveal outcome-changing mistakes for other users. (I don't have the time to do that myself, and I hate to create more work for you or anyone else, but I had to mention it.) Undecided
17  Other / Meta / Re: A simpler version of demerits: "dmerits" for every X merits earned on: February 26, 2024, 08:46:35 PM
I voted no.

I basically have 2 or 3 ideas a month about things that might make sense for Bitcointalk, but I keep most of them to myself, because after the initial excitement wears off, I ponder them more deeply and almost always come to realize that they are flawed in some subtle (and sometimes not so subtle) way and/or that they would throw off the balance that theymos has (presumably) worked so hard to achieve. It's really hard to find things that would be strict improvements (that is, ideas that would have nothing or almost nothing but upside if they were implemented). It's easier (though still hard) to find things that might/will create new problems but that you're almost certain will solve an even bigger problem (or set of problems) in exchange. So, if I were you, I'd start by asking: "What is the problem (or set of problems) that I'm aiming to solve?". If you can't come up with a really clear problem-statement, then, in my experience, it's usually not worth unpacking/debating the details of the solution (at least, not yet). Another way to think about it (just abstractly, I mean; there are no general-purpose units that I know of that would let you reason this out concretely), is that if you can't estimate the magnitude of the problem(s) being solved, then you have nothing to weigh against the magnitude of the problem(s) being caused.

(I mean, I know that sometimes the answer to something can present itself before you actually know the question, but, in general, that's a really inefficient way to work. A semi-related example that comes to mind is that I think the constant factor of 0.5 in the sMerit calculation could be swapped out for a rank-dependent value: that is, instead of the per-transaction sMerit calculation being something like sMeritBalance += meritsReceived * 0.5, it could be something like sMeritBalance += meritsReceived * LUT[receiversRank], or even something like sMeritBalance += meritsReceived * LUT[receiversRank][sendersRank]. In either the 8-entry 1D LUT case, or the 64-entry 2D LUT case, the values could all be set to 0.5, which would keep things working like they currently do, but, I have a hunch that experimenting with those values could have multiple benefits: it's easy to come up with LUTs that would make it much harder for unestablished accounts to rank each other up, or LUTs that would make the merit system less source-dependent by generating sMerit a little more generously for the higher ranks, etc. but because I came up with this idea before I had a specific problem in mind, I've just been sitting on it, struggling to arrive at a really convincing argument for why it should be implemented. But, I also can't just push if off my plate, so to speak, because I think it's likely the solution to something, I just don't know what.) Cheesy
18  Bitcoin / Development & Technical Discussion / Re: Understanding Nonce on: February 26, 2024, 10:37:09 AM
32-bit has a maximum value of 2^32 or 4,294,967,296, so the range is from 0~4,294,967,296.
You mean 2^32-1, right? Tongue (As in, the range for uint32_t goes from 0 to 4294967295.)



(That's a riff by Leon Bambrick on the famous Phil Karlton quote, I think.)

Seriously off-topic: Leon Bambrick's blog is really worth spending time on. There's some excellent stuff there. You Feel The Blood Drain From Your Face gave me flashbacks (I think almost every programmer that has done time as the resident "problem solver" at a small/medium company has an anecdote or two similar to that one from their early days). Grin
19  Other / Meta / A copy button for [code] blocks (SMF patch) on: February 19, 2024, 07:01:55 PM
This is something @libert19 suggested last year. I think it's a good idea: manually copy-pasting BBCode to update your signature is a bit error-prone (not everyone is as careful as they should be, and, although I don't really mess with mobile, I'm guessing that it's even more finicky on a phone/tablet). Besides that, it's just a nice, unobtrusive little time-saver (I bump into [code] blocks quite often on Bitcointalk, so I think this will be pretty handy beyond the use-case that inspired it).

Thanks to @TryNinja for posting a userscript that I took a peek at as a starting point.

I've put together two variations of this patch, here's what style A (default styling with just a hair of margin-bottom) looks like:



And here's what style B (the same border as [quote] blocks, which ends up working pretty nicely, IMO) looks like:



(I think style B works/fits a bit better, personally. Especially when there are small and/or multiple code blocks, like at the bottom of this post, I think style A will draw too much attention to itself.)

Here's the diff for @theymos (style A):

Code:
--- baseline/Sources/Subs.php	2011-09-17 21:59:55.000000000 +0000
+++ modified/Sources/Subs.php 2024-02-19 11:28:27.000000000 +0000
@@ -1123,7 +1123,7 @@
  array(
  'tag' => 'code',
  'type' => 'unparsed_content',
- 'content' => '<div class="codeheader">' . $txt['smf238'] . ':</div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
+ 'content' => '<div class="codeheader">' . $txt['smf238'] . ': <button type="button" style="margin-bottom: 1px;" onclick="navigator.clipboard.writeText(this.parentElement.nextElementSibling.innerText);">Copy</button></div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
  // !!! Maybe this can be simplified?
  'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
  global $context;
@@ -1161,7 +1161,7 @@
  array(
  'tag' => 'code',
  'type' => 'unparsed_equals_content',
- 'content' => '<div class="codeheader">' . $txt['smf238'] . ': ($2)</div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
+ 'content' => '<div class="codeheader">' . $txt['smf238'] . ': ($2) <button type="button" style="margin-bottom: 1px;" onclick="navigator.clipboard.writeText(this.parentElement.nextElementSibling.innerText);">Copy</button></div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
  // !!! Maybe this can be simplified?
  'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
  global $context;

And here's the diff for style B:

Code:
--- baseline/Sources/Subs.php	2011-09-17 21:59:55.000000000 +0000
+++ modified/Sources/Subs.php 2024-02-19 11:28:40.000000000 +0000
@@ -1123,7 +1123,7 @@
  array(
  'tag' => 'code',
  'type' => 'unparsed_content',
- 'content' => '<div class="codeheader">' . $txt['smf238'] . ':</div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
+ 'content' => '<div class="codeheader">' . $txt['smf238'] . ': <button type="button" style="border: 1px solid #d0d0e0;" onclick="navigator.clipboard.writeText(this.parentElement.nextElementSibling.innerText);">Copy</button></div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
  // !!! Maybe this can be simplified?
  'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
  global $context;
@@ -1161,7 +1161,7 @@
  array(
  'tag' => 'code',
  'type' => 'unparsed_equals_content',
- 'content' => '<div class="codeheader">' . $txt['smf238'] . ': ($2)</div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
+ 'content' => '<div class="codeheader">' . $txt['smf238'] . ': ($2) <button type="button" style="border: 1px solid #d0d0e0;" onclick="navigator.clipboard.writeText(this.parentElement.nextElementSibling.innerText);">Copy</button></div><div class="code">' . ($context['browser']['is_gecko'] ? '<pre style="margin-top: 0; display: inline;">$1</pre>' : '$1') . '</div>',
  // !!! Maybe this can be simplified?
  'validate' => isset($disabled['code']) ? null : create_function('&$tag, &$data, $disabled', '
  global $context;



@hd49728: Thanks for adding my patches to your topic, I appreciate it. I noticed that one of the titles is rendering incorrectly: Adding   (non-breaking space) to the BBCode parser instead of Adding [nbsp] (non-breaking space) to the BBCode parser. That title probably rendered correctly at the time you added it, but, since that patch was accepted, [nbsp] has become valid BBCode, so now it needs to be escaped if you want it to display properly. You'll probably run into a similar problem with this title, too. Here's a tip: whenever you want a BBCode tag (or something that might become a BBCode tag) to render without being processed, remember to wrap it in [nobbc] tags (you can quote this post and examine this paragraph to see what I mean).
20  Economy / Games and rounds / Re: 🥧 Bitcointalk Pie Baking Contest - 2nd edition 🥧 on: February 16, 2024, 10:54:29 AM
I had a lot of fun participating in this last year!

I'll contribute 3 mBTC to the prize pool.

(I'm not sure I'll be able to participate again this year, but if I do find the time, it'll be on the same basis as last year: a submission with a ton of help from my wife; like I said last time, I'm much better at eating pies than I am at making them, especially without my buxom sous-chef to basically tell me exactly what to do and then let me take all the glory.) Cheesy

You would still be edible. (...)
Are we about to eat some pies, or each other? Tongue
Pages: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!