<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Stephen Gilmore's Posts</title><link>https://sglmr.com/blog/</link><description>Stephen Gilmore's blog post feed.&lt;img src="https://sglmr.goatcounter.com/count?p=%2Ffeed%2F&amp;title=RSS+Feed" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><atom:link href="https://sglmr.com/feed/" rel="self"/><language>en-us</language><lastBuildDate>Fri, 03 Apr 2026 15:38:57 +0000</lastBuildDate><item><title>Blogosphere</title><link>https://sglmr.com/blog/e468b8/</link><description>&lt;p&gt;What's old is new again. A nice spot to find content by (hopefully) real people.&lt;/p&gt;
&lt;p&gt;I wish Facebook, Instagram, and all the others were more interested in building connections with friends, family, and my community than squeeze every possible moment of my attention out of me.&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fe468b8%2F&amp;title=Blogosphere" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Fri, 03 Apr 2026 15:38:57 +0000</pubDate><guid isPermaLink="false">e468b8</guid><category>Blogs</category></item><item><title>Django status notifications with ntfy.sh</title><link>https://sglmr.com/blog/icf532/</link><description>&lt;p&gt;There are a gazillion ways to get status notifications for a web application, but here's another one using ntfy.sh&lt;/p&gt;
&lt;p&gt;This little helper function would need to be scheduled to run in a task queue like &lt;a href="https://django-q2.readthedocs.io"&gt;django-q2&lt;/a&gt;. It could also be modified slightly into a cron job.&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;ntfy_status&lt;/span&gt;() &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;str&lt;/span&gt;:
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Checks the health check endpoint and sends a notification to ntfy.sh.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;requests&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;django.contrib.sites.models&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Site
    &lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;django.urls&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; reverse

    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #A2F; font-weight: bold"&gt;not&lt;/span&gt; settings&lt;span style="color: #666"&gt;.&lt;/span&gt;NTFY_TOPIC:
        &lt;span style="color: #008000; font-weight: bold"&gt;raise&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;ValueError&lt;/span&gt;(&lt;span style="color: #BA2121"&gt;&amp;quot;NTFY_TOPIC environment variable is not configured.&amp;quot;&lt;/span&gt;)

    &lt;span style="color: #3D7B7B; font-style: italic"&gt;# Create the full url to a health check&lt;/span&gt;
    protocol &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;https&amp;quot;&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; settings&lt;span style="color: #666"&gt;.&lt;/span&gt;SECURE_SSL_REDIRECT &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;http&amp;quot;&lt;/span&gt;
    domain &lt;span style="color: #666"&gt;=&lt;/span&gt; Site&lt;span style="color: #666"&gt;.&lt;/span&gt;objects&lt;span style="color: #666"&gt;.&lt;/span&gt;get_current()&lt;span style="color: #666"&gt;.&lt;/span&gt;domain
    path &lt;span style="color: #666"&gt;=&lt;/span&gt; reverse(&lt;span style="color: #BA2121"&gt;&amp;quot;health_check&amp;quot;&lt;/span&gt;)
    url &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;f&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;protocol&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;://&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;domain&lt;span style="color: #A45A77; font-weight: bold"&gt;}{&lt;/span&gt;path&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;

    health_response &lt;span style="color: #666"&gt;=&lt;/span&gt; requests&lt;span style="color: #666"&gt;.&lt;/span&gt;get(url)

    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; health_response&lt;span style="color: #666"&gt;.&lt;/span&gt;status_code &lt;span style="color: #666"&gt;==&lt;/span&gt; &lt;span style="color: #666"&gt;200&lt;/span&gt;:
        emoji &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;green_circle&amp;quot;&lt;/span&gt;
        suffix &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;is up!&amp;quot;&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;:
        emoji &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;red_circle,skull&amp;quot;&lt;/span&gt;
        suffix &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;is down!&amp;quot;&lt;/span&gt;

    &lt;span style="color: #3D7B7B; font-style: italic"&gt;# Send ntfy message&lt;/span&gt;
    ntfy_response &lt;span style="color: #666"&gt;=&lt;/span&gt; requests&lt;span style="color: #666"&gt;.&lt;/span&gt;post(
        &lt;span style="color: #BA2121"&gt;f&amp;quot;https://ntfy.sh/&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;settings&lt;span style="color: #666"&gt;.&lt;/span&gt;NTFY_TOPIC&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;,
        data&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;f&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;domain&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt; &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;suffix&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;,
        headers&lt;span style="color: #666"&gt;=&lt;/span&gt;{
            &lt;span style="color: #BA2121"&gt;&amp;quot;Tags&amp;quot;&lt;/span&gt;: &lt;span style="color: #BA2121"&gt;f&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;emoji&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;,&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;health_response&lt;span style="color: #666"&gt;.&lt;/span&gt;status_code&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;,
            &lt;span style="color: #BA2121"&gt;&amp;quot;Actions&amp;quot;&lt;/span&gt;: &lt;span style="color: #BA2121"&gt;&amp;quot;view, Open URL, &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{url}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;, clear=true&amp;quot;&lt;/span&gt;,
        },
    )

    ntfy_response&lt;span style="color: #666"&gt;.&lt;/span&gt;raise_for_status()
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;Sent notification to ntfy.sh with status code: &amp;quot;&lt;/span&gt; &lt;span style="color: #666"&gt;+&lt;/span&gt; &lt;span style="color: #008000"&gt;str&lt;/span&gt;(ntfy_response&lt;span style="color: #666"&gt;.&lt;/span&gt;status_code)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt="Notification screenshot" src="https://sglmr.com/media/file/2026/ntfy-django-status-screenshot.jpeg"&gt;&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Ficf532%2F&amp;title=Django+status+notifications+with+ntfy.sh" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Thu, 02 Apr 2026 04:25:35 +0000</pubDate><guid isPermaLink="false">icf532</guid><category>Python</category><category>Django</category><category>ntfy.sh</category></item><item><title>I ran a half marathon! 🏃</title><link>https://sglmr.com/blog/un9z34/</link><description>&lt;p&gt;I don't think anyone else will ever read or see this, but it was a lot of work; and 6 months ago, I didn't think I could do it. &lt;/p&gt;
&lt;p&gt;&lt;img alt="Finish line on the warning track" src="https://sglmr.com/media/file/2026/shamrockn-half-marathon-2026-finish-line.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;My goal was just to finish. Based on my training runs, it looked like I might run a 2:45:00 time, but I beat it by about 30 minutes. I was trying to run by heart rate, but it felt boringly slow. A few miles in, I switched to a 90s/30s run walk and it carried me through the end of the race.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://sglmr.com/media/file/2026/shamrockn-half-marathon-2026-finisher.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;Lesson's learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A half marathon is very do-able.&lt;/li&gt;
&lt;li&gt;Nature's Bakery fig bars are decent real food option for runs.&lt;/li&gt;
&lt;li&gt;I drink a lot of water and it was VERY helpful to keep a 500 mL bottle of Skratch with me in a belt during the run.&lt;/li&gt;
&lt;li&gt;The Galloway run walk method was amazing! I think the run would have been a lot harder and slower without it.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fun9z34%2F&amp;title=I+ran+a+half+marathon%21+%F0%9F%8F%83" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Sat, 21 Mar 2026 03:54:10 +0000</pubDate><guid isPermaLink="false">un9z34</guid><category>Running</category></item><item><title>The difference between worry, anxiety, and stress</title><link>https://sglmr.com/blog/7vvkq2/</link><description>&lt;p&gt;&lt;a href="https://nesslabs.com/worrying-well"&gt;Worrying well: how to bring wisdom to your worries&lt;/a&gt; by Anne-Laure Le Cunff&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Worrying well is about tapping into the wisdom of real or imagined people, you can turn your negative worry into a positive one—whether a worry you accept, if the circumstances are out of your control, or one you can take action upon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Worry.&lt;/strong&gt; A repetitive/ruminative form of thinking about the future or the past.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anxiety.&lt;/strong&gt; An uncomfortable feeling of fear, apprehension, or dread, often in the gut or chest, accompanied by physical symptoms such as rapid heartbeat and sweating.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stress.&lt;/strong&gt; A physical response (fight or flight) to a threat, real or imagined.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2F7vvkq2%2F&amp;title=The+difference+between+worry%2C+anxiety%2C+and+stress" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Thu, 19 Mar 2026 19:58:02 +0000</pubDate><guid isPermaLink="false">7vvkq2</guid><category>"Anne-Laure Le Cunff"</category></item><item><title>Workday Compensation Plan Assignments Security gotcha</title><link>https://sglmr.com/blog/u9355g/</link><description>&lt;p&gt;I hit another Workday security "gotcha" today.&lt;/p&gt;
&lt;p&gt;I needed a field that was based on a related business object "Compensation Plan Assignments".&lt;/p&gt;
&lt;p&gt;No problem, &lt;em&gt;Related Actions &amp;gt;&amp;gt; View Security for Calculated Field&lt;/em&gt;. Okay, &lt;code&gt;View&lt;/code&gt; access on &lt;code&gt;Worker Data: Compensation by Organization&lt;/code&gt;, great.&lt;/p&gt;
&lt;p&gt;And it didn't work! I was stuck for the better part of an hour.&lt;/p&gt;
&lt;p&gt;Eventually I came up with the correct search encantation to find something helpful on Workday Community:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://workday.my.site.com/customercenter/article?no=000006862&amp;amp;redirect=false"&gt;Report User Or ISU Not Seeing Merit, Bonus Or Stock Plan Assignment Data&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Issue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A report user or ISU account is not seeing merit, bonus or stock plan assignment data.&lt;/p&gt;
&lt;p&gt;For example &lt;em&gt;Compensation Plan Assignment&lt;/em&gt; related fields, secured by the &lt;em&gt;Worker Data: Compensation by Organization&lt;/em&gt; domain, are not returning the expected merit, bonus or stock plan assignment data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In line with your Organizations compensation security model please verify if access is also required on the &lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt; domain:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Domain description: &lt;em&gt;This domain works in conjunction with segment security to provide the ability to secure funded plan (merit, bonus or stock) assignments.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Grant the user access to the applicable &lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt; domain.  Activate changes and retest.&lt;/p&gt;
&lt;p&gt;Example impacted fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compensation Plan Assignment&lt;/li&gt;
&lt;li&gt;Merit Plans - Plan Details&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fu9355g%2F&amp;title=Workday+Compensation+Plan+Assignments+Security+gotcha" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Fri, 06 Mar 2026 21:35:29 +0000</pubDate><guid isPermaLink="false">u9355g</guid><category>Workday Security</category><category>TIL</category><category>Workday</category></item><item><title>Workday Studio "exit()"</title><link>https://sglmr.com/blog/nb5y7f/</link><description>&lt;p&gt;Today I learned there is an MVEL expression do do a "System.exit" or "sys.exit()" in Workday Studio.&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;context.&lt;span style="color: #687822"&gt;setAbort&lt;/span&gt;(&lt;span style="color: #008000; font-weight: bold"&gt;true&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: The default behavior of all local-out steps is &lt;code&gt;Propogate Abort = true&lt;/code&gt;.  Generally you'll want this. If the abort isn't working as expected, check that setting first.&lt;/p&gt;
&lt;h1 id="example"&gt;Example&lt;a class="headerlink" href="#example" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="1-set-an-integration-time-limit"&gt;1. Set an integration time limit&lt;a class="headerlink" href="#1-set-an-integration-time-limit" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Somewhere near the beginning of the integration, set a time limit on the integration.&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;// You could simply set a global value&lt;/span&gt;
props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;3.9&lt;/span&gt;

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// OR you could retrieve it from a launch parameter or integration attribute&lt;/span&gt;
props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;Double.&lt;span style="color: #687822"&gt;valueOf&lt;/span&gt;(lp.&lt;span style="color: #687822"&gt;getSimpleData&lt;/span&gt;(&lt;span style="color: #BA2121"&gt;&amp;quot;Runtime Limit (hours)&amp;quot;&lt;/span&gt;));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;If you use a launch parameter or integration attribute, consider adding an &lt;strong&gt;ValidateExp&lt;/strong&gt; that the value is between 0 and 4 hours&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="2-evaluate-the-run-duration"&gt;2: Evaluate the run duration&lt;a class="headerlink" href="#2-evaluate-the-run-duration" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So for example, say you're in a loop processing a few thousand records. After the splitter, you might have an &lt;strong&gt;eval&lt;/strong&gt; component with something like this:&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;// 1. Get the current time and the &amp;#39;sent&amp;#39; time in milliseconds&lt;/span&gt;
&lt;span style="color: #B00040"&gt;long&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;nowMs&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;System.&lt;span style="color: #687822"&gt;currentTimeMillis&lt;/span&gt;();
&lt;span style="color: #B00040"&gt;long&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;sentMs&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;lp.&lt;span style="color: #687822"&gt;sentOnAsDate&lt;/span&gt;.&lt;span style="color: #687822"&gt;getTime&lt;/span&gt;();

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// 2. Calculate the difference in milliseconds&lt;/span&gt;
&lt;span style="color: #B00040"&gt;long&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;diffMs&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;nowMs&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;-&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;sentMs;

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// 3. Convert to hours as a double (to support decimals like 3.75)&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;// There are 3,600,000 milliseconds in one hour&lt;/span&gt;
&lt;span style="color: #B00040"&gt;double&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;diffHours&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;diffMs&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;/&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;3600000.0&lt;/span&gt;;

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// 4. Logic check&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;(diffHours&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;)&lt;span style="color: #BBB"&gt; &lt;/span&gt;{
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;// Logic for when the time limit is exceeded&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;true&lt;/span&gt;;
}&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;{
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;false&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="3-route-by-duration"&gt;3. Route by duration&lt;a class="headerlink" href="#3-route-by-duration" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Then you could have a &lt;strong&gt;route&lt;/strong&gt; step that checks &lt;code&gt;props["abortIntegration"]&lt;/code&gt; for each record.  The &lt;em&gt;choose-route&lt;/em&gt; expression would be something like:&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;// abort&lt;/span&gt;
(&lt;span style="color: #B00040"&gt;boolean&lt;/span&gt;)props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;==&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;true&lt;/span&gt;

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// continue&lt;/span&gt;
(&lt;span style="color: #B00040"&gt;boolean&lt;/span&gt;)props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;==&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="4-handle-the-abort"&gt;4. Handle the abort&lt;a class="headerlink" href="#4-handle-the-abort" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The last thing in the logic path will be an &lt;strong&gt;eval&lt;/strong&gt; step with &lt;code&gt;context.setAbort(true)&lt;/code&gt;. Do any steps to close out the integration before the &lt;code&gt;context.setAbort&lt;/code&gt;. So for example, there might be steps like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log a &lt;code&gt;CRTICICAL&lt;/code&gt; message in a &lt;strong&gt;PutIntegrationMessage&lt;/strong&gt; step&lt;/li&gt;
&lt;li&gt;Close/save any log files with a &lt;strong&gt;local-out&lt;/strong&gt; step&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;eval&lt;/strong&gt; step to trigger the abort with &lt;code&gt;context.setAbort(true)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fnb5y7f%2F&amp;title=Workday+Studio+%22exit%28%29%22" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Mon, 16 Feb 2026 22:07:14 +0000</pubDate><guid isPermaLink="false">nb5y7f</guid><category>Workday</category><category>Workday Studio</category><category>TIL</category></item><item><title>Workday API Security Gotcha's</title><link>https://sglmr.com/blog/8p833n/</link><description>&lt;blockquote&gt;
&lt;p&gt;&lt;span style="color:red;"&gt;Validation error occurred. The entered information does not meet the restrictions defined for this field. (Replacement_for_Worker_Reference).&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was working with the Edit_Job_Requisition API and kept hitting this error; even though I wasn't touching the &lt;code&gt;Replacement_for_Worker_Reference&lt;/code&gt; at all in my API request. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution: give the ISU &lt;code&gt;View&lt;/code&gt; access to &lt;em&gt;Worker Data: Public Worker Reports&lt;/em&gt;.&lt;/strong&gt; I wasn't missing any job requisition related security, I was missing the security to see the worker in the &lt;code&gt;Replacement_for_Worker_Reference&lt;/code&gt;. Imagine completing the task through Workday's UI, I couldn't see the drop down list of workers without that domain.&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2F8p833n%2F&amp;title=Workday+API+Security+Gotcha%27s" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Thu, 12 Feb 2026 19:45:56 +0000</pubDate><guid isPermaLink="false">8p833n</guid><category>Workday Security</category></item><item><title>Ctrl + L + C</title><link>https://sglmr.com/blog/i457sd/</link><description>&lt;p&gt;Today I learned how to quickly copy the URL of the current page.&lt;/p&gt;
&lt;h2&gt;
&lt;center&gt;
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;L&lt;/kbd&gt; + &lt;kbd&gt;C&lt;/kbd&gt;
&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Ctrl + L&lt;/code&gt; selects the address bar and &lt;code&gt;Ctrl + C&lt;/code&gt; copies the selected address bar URL.&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fi457sd%2F&amp;title=Ctrl+%2B+L+%2B+C" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Mon, 02 Feb 2026 16:54:25 +0000</pubDate><guid isPermaLink="false">i457sd</guid><category>TIL</category></item><item><title>My Workday Studio Preferences</title><link>https://sglmr.com/blog/7e8ezp/</link><description>&lt;p&gt;These are some of my preferred Workday Studio preference changes I've made over the years.&lt;/p&gt;
&lt;p&gt;Navigation: &lt;strong&gt;Window&lt;/strong&gt; &amp;gt; &lt;strong&gt;Preferences&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="xml-xml-files-editor"&gt;XML &amp;gt; XML Files &amp;gt; Editor&lt;a class="headerlink" href="#xml-xml-files-editor" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Uncheck "Format Comments" &lt;ul&gt;
&lt;li&gt;&lt;em&gt;It is incredibly frustrating when formatting an XSLT comment destroyes the format and readability of a long comment block&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="fonts"&gt;Fonts&lt;a class="headerlink" href="#fonts" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Search "font" at the top of &lt;strong&gt;Preferences&lt;/strong&gt; and replace everything with your font of choice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="general-workday-deployment"&gt;General &amp;gt; Workday &amp;gt; Deployment&lt;a class="headerlink" href="#general-workday-deployment" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Check "Include source code in deployed CLAR"&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="general-editors-text-editors"&gt;General &amp;gt; Editors &amp;gt; Text Editors&lt;a class="headerlink" href="#general-editors-text-editors" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Line spacing (extra % of font height): 25&lt;/li&gt;
&lt;li&gt;Check "Enable word wrap when opening an editor"&lt;/li&gt;
&lt;li&gt;Check "Show line numbers"&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="xml-xml-files-editor-syntax-coloring"&gt;XML &amp;gt; XML Files &amp;gt; Editor &amp;gt; Syntax Coloring&lt;a class="headerlink" href="#xml-xml-files-editor-syntax-coloring" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;"Comment Content" and "Comment Delimiters": Custom dark orange color to stand out from other text&lt;/li&gt;
&lt;li&gt;"Tag Delimiters" and "Tag Names": Change to a pink or purple to differentiate them from XSLT tags&lt;/li&gt;
&lt;/ul&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2F7e8ezp%2F&amp;title=My+Workday+Studio+Preferences" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Fri, 30 Jan 2026 19:36:50 +0000</pubDate><guid isPermaLink="false">7e8ezp</guid><category>Workday Studio</category><category>Workday</category></item><item><title>Spatchcock Chicken</title><link>https://sglmr.com/blog/6r69w5/</link><description>&lt;p&gt;Spatchcocking (is that a word?) is the only way I cook whole chicken. Until this morning, I hadn't seen how much easier it is to remove the ribs and some of the other bones before cooking the chicken.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ChefSteps Spatchcock Chicken Butchery&lt;/strong&gt;&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/h97lR321hIg?si=JgobtlKxFV0I4W4O" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;strong&gt;Spatchcock a Chicken with Chef Eric Crowley, Chef Eric's Culinary Classroom, West LA/CA&lt;/strong&gt;&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/sRax6mBXazE?si=_MQqxhZY7GQXS7wL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2F6r69w5%2F&amp;title=Spatchcock+Chicken" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Sun, 25 Jan 2026 16:02:50 +0000</pubDate><guid isPermaLink="false">6r69w5</guid><category>Cooking</category></item><item><title>Comparing Tribute.js and Tom Select for tagging with suggestions</title><link>https://sglmr.com/blog/q5787r/</link><description>&lt;p&gt;I've been wishing for tagging autocomplete for some of my projects to go along with django-taggit.&lt;/p&gt;
&lt;p&gt;This is a quick demo that I was playing with to help make a choice.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tribute.js&lt;/strong&gt; is nice if you want to do tagging or mentions in the text as you are typing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tom Select&lt;/strong&gt; seems to play a little bit nicer with the way django-taggit works out of the box.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Sorry it isn't a super mobile friendly experience.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tributejs@5.1.3/dist/tribute.css"&gt;
&lt;link href="https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/css/tom-select.css" rel="stylesheet"&gt;&lt;/p&gt;
&lt;style&gt;
body {
font-family: 'Segoe UI', system-ui, sans-serif;
padding: 20px;
background: #f8f9fa;
display: flex;
flex-direction: column;
align-items: center;
}

.container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
max-width: 1000px;
width: 100%;
}

.card {
background: white;
padding: 20px;
border-radius: 10px;
border: 1px solid #ddd;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}

h3 {
margin-top: 0;
color: #333;
border-bottom: 2px solid #007bff;
display: inline-block;
padding-bottom: 5px;
}

label {
display: block;
margin-top: 15px;
font-weight: 600;
}

textarea,
input[type="text"] {
width: 100%;
box-sizing: border-box;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 15px;
}

textarea {
height: 120px;
}

button {
background: #28a745;
color: white;
border: none;
padding: 12px 24px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
margin-top: 20px;
width: 100%;
font-weight: bold;
}

/* Submission Modal Styling */
#submission-view {
display: none;
margin-top: 30px;
width: 100%;
max-width: 1000px;
background: #222;
color: #0f0 !important;
padding: 20px;
border-radius: 8px;
font-family: 'Courier New', monospace;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
position: relative;
}

pre {
color: #0f0 !important;
}

#submission-view h4 {
color: white;
margin-top: 0;
}

.close-btn {
position: absolute;
top: 10px;
right: 15px;
cursor: pointer;
color: white;
font-size: 20px;
}
&lt;/style&gt;

&lt;h2&gt;Tagging System Comparison&lt;/h2&gt;

&lt;form id="comparison-form" class="container"&gt;
&lt;div class="card"&gt;
&lt;h3&gt;Tribute.js&lt;/h3&gt;
&lt;p&gt;&lt;i&gt;Best for long text posts.&lt;/i&gt;&lt;/p&gt;
&lt;label for="post_content"&gt;Content Field:&lt;/label&gt;
&lt;textarea name="post_content" id="post_content" placeholder="Type @ or #..."&gt;&lt;/textarea&gt;
&lt;small&gt;Try: @guido, #django, #database&lt;/small&gt;
&lt;/div&gt;

&lt;div class="card"&gt;
&lt;h3&gt;Tom Select&lt;/h3&gt;
&lt;p&gt;&lt;i&gt;Best for specific category fields.&lt;/i&gt;&lt;/p&gt;
&lt;label for="category_tags"&gt;Category Tags:&lt;/label&gt;
&lt;input name="category_tags" id="category_tags" placeholder="Search tags..."&gt;
&lt;small&gt;Allows "X" to delete, multiple picks.&lt;/small&gt;
&lt;/div&gt;

&lt;div style="grid-column: span 2;"&gt;
&lt;button type="submit"&gt;Submit Data to "Django"&lt;/button&gt;
&lt;/div&gt;
&lt;/form&gt;

&lt;div id="submission-view"&gt;
&lt;span class="close-btn" onclick="document.getElementById('submission-view').style.display='none'"&gt;×&lt;/span&gt;
&lt;h4&gt;Django Backend View (request.POST)&lt;/h4&gt;
&lt;pre id="post-data-output"&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;script src="https://cdn.jsdelivr.net/npm/tributejs@5.1.3/dist/tribute.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/js/tom-select.complete.min.js"&gt;&lt;/script&gt;

&lt;script&gt;
// --- DATASET ---
const tags = [
{ key: 'Django', value: 'django' }, { key: 'Python', value: 'python' },
{ key: 'JavaScript', value: 'javascript' }, { key: 'Postgres', value: 'postgres' },
{ key: 'Tailwind', value: 'tailwind' }, { key: 'React', value: 'react' },
{ key: 'API', value: 'api' }, { key: 'Database', value: 'database' },
{ key: 'Frontend', value: 'frontend' }, { key: 'Backend', value: 'backend' }
];

const users = [
{ key: 'Guido van Rossum', value: 'guido' }, { key: 'Linus Torvalds', value: 'linus' },
{ key: 'Ada Lovelace', value: 'ada' }, { key: 'Django Reinhardt', value: 'django_r' },
{ key: 'Admin User', value: 'admin' }, { key: 'Gemini AI', value: 'gemini' }
];

// --- TRIBUTE.JS ---
const tribute = new Tribute({
collection: [
{ trigger: '@', values: users },
{ trigger: '#', values: tags }
]
});
tribute.attach(document.getElementById('post_content'));

// --- TOM SELECT ---
const ts = new TomSelect("#category_tags", {
plugins: ['remove_button'],
options: tags.map(t =&gt; ({ value: t.value, text: t.key })),
maxItems: null,
create: true,

onItemAdd: function () {
this.setTextboxValue(''); // Clears the typed text from the box
this.refreshOptions();     // Resets the dropdown to show all options again
}
});

// --- FORM SUBMISSION PREVIEW ---
document.getElementById('comparison-form').addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(this);
const output = {};

formData.forEach((value, key) =&gt; {
output[key] = value;
});

document.getElementById('submission-view').style.display = 'block';
document.getElementById('post-data-output').textContent = JSON.stringify(output, null, 4);
});
&lt;/script&gt;

&lt;hr&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fq5787r%2F&amp;title=Comparing+Tribute.js+and+Tom+Select+for+tagging+with+suggestions" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Fri, 23 Jan 2026 20:25:30 +0000</pubDate><guid isPermaLink="false">q5787r</guid><category>Webdev</category><category>Python</category><category>javascript</category><category>Django</category></item><item><title>Helpful Markdown utilities</title><link>https://sglmr.com/blog/ccxx6t/</link><description>&lt;p&gt;A few tools that have been useful for writing in Markdown.&lt;/p&gt;
&lt;p&gt;One's I've actually used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://euangoddard.github.io/clipboard2markdown/"&gt;Pase to Markdown&lt;/a&gt;&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tabletomarkdown.com/convert-spreadsheet-to-markdown/"&gt;Table to Markdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tablesgenerator.com/markdown_tables"&gt;Markdown Tables Generator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I haven't used, but could be useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://word2md.com/"&gt;Word to Markdown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Uses &lt;a href="https://github.com/mixmark-io/turndown"&gt;https://github.com/mixmark-io/turndown&lt;/a&gt;&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fccxx6t%2F&amp;title=Helpful+Markdown+utilities" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Fri, 23 Jan 2026 02:08:49 +0000</pubDate><guid isPermaLink="false">ccxx6t</guid><category>Webdev</category><category>Writing</category><category>Markdown</category></item><item><title>Your project is always at risk of being delayed by the longest task in the project.</title><link>https://sglmr.com/blog/nbzz48/</link><description>&lt;blockquote&gt;
&lt;p&gt;Your project is always at risk of being delayed by the longest task in the project.&lt;/p&gt;
&lt;p&gt;—Mark Horstman, Career Tools Podcast&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think I replayed this 3 times in the driveway while I took out the trash.  It's been a minute since I've thought about project management this way.&lt;/p&gt;
&lt;p&gt;We often think, "UAT will take a month", so we block a month on the calendar and move on. What happens if we realize something didn't get done at the end of the month? The project could be 4 weeks behind.  Smaller 2-3 day tasks put a cap on the risk.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Task Size&lt;/strong&gt;: 1 month → &lt;strong&gt;Potential Delay&lt;/strong&gt;: 4 weeks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Task Size&lt;/strong&gt;: 3 days → &lt;strong&gt;Potential Delay&lt;/strong&gt;: 3 days&lt;/li&gt;
&lt;/ul&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fnbzz48%2F&amp;title=Your+project+is+always+at+risk+of+being+delayed+by+the+longest+task+in+the+project." width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Wed, 21 Jan 2026 03:52:19 +0000</pubDate><guid isPermaLink="false">nbzz48</guid><category>Project Management</category><category>Quote</category></item><item><title>Presidio - Data Protection and De-identification</title><link>https://sglmr.com/blog/saisc4/</link><description>&lt;blockquote&gt;
&lt;p&gt;An open-source framework for detecting, redacting, masking, and anonymizing sensitive data (PII) across text, images, and structured data. Supports NLP, pattern matching, and customizable pipelines. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/microsoft/presidio"&gt;Microsoft Presideo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I don't have an immediate use for this now, but there's been times I sure wish I knew about or had this.&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fsaisc4%2F&amp;title=Presidio+-+Data+Protection+and+De-identification" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Thu, 15 Jan 2026 14:59:42 +0000</pubDate><guid isPermaLink="false">saisc4</guid><category>Data Tools</category><category>Python</category></item><item><title>Essentialism</title><link>https://sglmr.com/blog/fdjryb/</link><description>&lt;p&gt;Spark notes on the 1-2-3 planning method author Greg McKeown published.&lt;/p&gt;
&lt;h2 id="quarterly-planning"&gt;Quarterly Planning&lt;a class="headerlink" href="#quarterly-planning" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;What's essential that I'm underinvesting in?&lt;/li&gt;
&lt;li&gt;What's non-essential that I'm over-investing in?&lt;/li&gt;
&lt;li&gt;How can I make it effortless to get the most important things done?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="the-1-2-3-method"&gt;The 1-2-3 Method:&lt;a class="headerlink" href="#the-1-2-3-method" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Essential Project&lt;/strong&gt;: The day's priority. 1 essential project to work on for 3 hours. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Urgent &amp;amp; Essential Tasks&lt;/strong&gt;: 2 urgent and essential tasks to keep you from falling behind.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintenance Tasks&lt;/strong&gt;: 3 maintenance items to complete to stay organized and prevent problems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Other tasks or notes&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="references"&gt;References&lt;a class="headerlink" href="#references" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://gregmckeown.com/books/the-essentialism-planner/"&gt;The Essentialism Planner on Amazon&lt;/a&gt; by Greg McKeown&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gregmckeown.com/books/essentialism/"&gt;Essentialism: The Disciplined Pursuit of Less&lt;/a&gt; by Greg McKeown&lt;/li&gt;
&lt;li&gt;Greg's podcast Episode 233 for more about the "Power Half an Hour"&lt;/li&gt;
&lt;li&gt;Greg's podcast Episode 235 for more about the "1-2-3 Method"&lt;/li&gt;
&lt;/ol&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Ffdjryb%2F&amp;title=Essentialism" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Tue, 13 Jan 2026 13:00:02 +0000</pubDate><guid isPermaLink="false">fdjryb</guid><category>Book Notes</category></item><item><title>Time Workday RaaS Requests</title><link>https://sglmr.com/blog/fj9hev/</link><description>&lt;p&gt;I've had a few scenarios recently where I've needed to time RaaS API requests from Workday for testing and optimizing reports.&lt;/p&gt;
&lt;p&gt;This is a somewhat unpolished python script with inline dependencies I can quickly run with &lt;code&gt;uv&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="using-the-script"&gt;Using the script&lt;a class="headerlink" href="#using-the-script" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;uv&lt;/code&gt; installed, it's as easy as &lt;code&gt;uv run raas_timer.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Run the help command:&lt;/strong&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;uv&lt;span style="color: #BBB"&gt; &lt;/span&gt;run&lt;span style="color: #BBB"&gt; &lt;/span&gt;raas_timer.py&lt;span style="color: #BBB"&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #008000; font-weight: bold"&gt;usage&lt;/span&gt;:&lt;span style="color: #BBB"&gt; &lt;/span&gt;raas_timer.py [-h] [--user USER] [--count COUNT] [--timeout TIMEOUT] [--download] url

Time a Workday RaaS request.

&lt;span style="color: #008000; font-weight: bold"&gt;positional arguments&lt;/span&gt;:
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;url                The RaaS URL to request.

&lt;span style="color: #008000; font-weight: bold"&gt;options&lt;/span&gt;:
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;-h, --help         show this help message and exit
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;--user USER        Workday ISU Username
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;--count COUNT      Number of times to run the request (default=1)
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;--timeout TIMEOUT  Request timeout in minutes (default=1)
&lt;span style="color: #BBB"&gt;  &lt;/span&gt;--download         Save the output as a timestamped CSV file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h2 id="the-script"&gt;The script&lt;a class="headerlink" href="#the-script" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Save this in a file named &lt;code&gt;raas_timer.py&lt;/code&gt; on your computer to use.&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;# /// script&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;# requires-python = &amp;quot;&amp;gt;=3.11&amp;quot;&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;# dependencies = [&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;#     &amp;quot;requests&amp;quot;,&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;#     &amp;quot;rich&amp;quot;,&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;#     &amp;quot;rich-argparse&amp;quot;,&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;# ]&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;# ///&lt;/span&gt;
&lt;span style="color: #3D7B7B; font-style: italic"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;__future__&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; annotations

&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;argparse&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;datetime&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;getpass&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;logging&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;os&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;threading&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;time&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;collections.abc&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Sequence
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;pathlib&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Path

&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;requests&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;requests.auth&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; HTTPBasicAuth
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.console&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Console
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.live&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Live
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.logging&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; RichHandler
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.progress&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; (
    BarColumn,
    DownloadColumn,
    Progress,
    SpinnerColumn,
    TextColumn,
    TransferSpeedColumn,
)
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.spinner&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Spinner
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.table&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Table
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich.text&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; Text
&lt;span style="color: #008000; font-weight: bold"&gt;from&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F; font-weight: bold"&gt;rich_argparse&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; RichHelpFormatter

&lt;span style="color: #3D7B7B; font-style: italic"&gt;# Setup Rich Console and Logging&lt;/span&gt;
console &lt;span style="color: #666"&gt;=&lt;/span&gt; Console()
logging&lt;span style="color: #666"&gt;.&lt;/span&gt;basicConfig(
    level&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;INFO&amp;quot;&lt;/span&gt;,
    &lt;span style="color: #008000"&gt;format&lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;%(message)s&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;,
    datefmt&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;[&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;%X&lt;/span&gt;&lt;span style="color: #BA2121"&gt;]&amp;quot;&lt;/span&gt;,
    handlers&lt;span style="color: #666"&gt;=&lt;/span&gt;[RichHandler(rich_tracebacks&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;True&lt;/span&gt;, console&lt;span style="color: #666"&gt;=&lt;/span&gt;console, show_path&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;False&lt;/span&gt;)],
)
log &lt;span style="color: #666"&gt;=&lt;/span&gt; logging&lt;span style="color: #666"&gt;.&lt;/span&gt;getLogger(&lt;span style="color: #BA2121"&gt;&amp;quot;raas_timer&amp;quot;&lt;/span&gt;)

&lt;span style="color: #3D7B7B; font-style: italic"&gt;# --- Utility Functions ---&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;format_size&lt;/span&gt;(bytes_size: &lt;span style="color: #008000"&gt;int&lt;/span&gt;) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;str&lt;/span&gt;:
    mb_size &lt;span style="color: #666"&gt;=&lt;/span&gt; bytes_size &lt;span style="color: #666"&gt;/&lt;/span&gt; (&lt;span style="color: #666"&gt;1024&lt;/span&gt; &lt;span style="color: #666"&gt;*&lt;/span&gt; &lt;span style="color: #666"&gt;1024&lt;/span&gt;)
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #BA2121"&gt;f&amp;quot;[bold cyan]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;bytes_size&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;,&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[/] bytes ([bold magenta]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;mb_size&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;,.2f&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt; MB[/])&amp;quot;&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;get_timer_content&lt;/span&gt;(start_time: datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime, start_ts: &lt;span style="color: #008000"&gt;str&lt;/span&gt;) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; Text:
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Generates the formatted content for the live waiting timer.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    elapsed &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now() &lt;span style="color: #666"&gt;-&lt;/span&gt; start_time
    mins, secs &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;divmod&lt;/span&gt;(&lt;span style="color: #008000"&gt;int&lt;/span&gt;(elapsed&lt;span style="color: #666"&gt;.&lt;/span&gt;total_seconds()), &lt;span style="color: #666"&gt;60&lt;/span&gt;)

    content &lt;span style="color: #666"&gt;=&lt;/span&gt; Text()
    content&lt;span style="color: #666"&gt;.&lt;/span&gt;append(start_ts, style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;bold cyan&amp;quot;&lt;/span&gt;)
    content&lt;span style="color: #666"&gt;.&lt;/span&gt;append(&lt;span style="color: #BA2121"&gt;&amp;quot; | &amp;quot;&lt;/span&gt;, style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;white&amp;quot;&lt;/span&gt;)
    content&lt;span style="color: #666"&gt;.&lt;/span&gt;append(&lt;span style="color: #BA2121"&gt;&amp;quot;Waiting for Workday...&amp;quot;&lt;/span&gt;, style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;yellow&amp;quot;&lt;/span&gt;)
    content&lt;span style="color: #666"&gt;.&lt;/span&gt;append(&lt;span style="color: #BA2121"&gt;f&amp;quot; &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;mins&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;m &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;secs&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;02d&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;s&amp;quot;&lt;/span&gt;, style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;bold white&amp;quot;&lt;/span&gt;)
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; content


&lt;span style="color: #3D7B7B; font-style: italic"&gt;# --- Core Logic Splits ---&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;wait_for_response&lt;/span&gt;(
    url: &lt;span style="color: #008000"&gt;str&lt;/span&gt;, auth: HTTPBasicAuth, timeout_min: &lt;span style="color: #008000"&gt;int&lt;/span&gt;
) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; requests&lt;span style="color: #666"&gt;.&lt;/span&gt;Response:
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Handles the live timer UI while waiting for the server to respond.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    start_time &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now()
    start_ts &lt;span style="color: #666"&gt;=&lt;/span&gt; start_time&lt;span style="color: #666"&gt;.&lt;/span&gt;strftime(&lt;span style="color: #BA2121"&gt;&amp;quot;%I:%M:%S %p&amp;quot;&lt;/span&gt;)

    response: requests&lt;span style="color: #666"&gt;.&lt;/span&gt;Response &lt;span style="color: #666"&gt;|&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt; &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;
    error: &lt;span style="color: #CB3F38; font-weight: bold"&gt;Exception&lt;/span&gt; &lt;span style="color: #666"&gt;|&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt; &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;

    &lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;make_request&lt;/span&gt;():
        &lt;span style="color: #008000; font-weight: bold"&gt;nonlocal&lt;/span&gt; response, error
        &lt;span style="color: #008000; font-weight: bold"&gt;try&lt;/span&gt;:
            res &lt;span style="color: #666"&gt;=&lt;/span&gt; requests&lt;span style="color: #666"&gt;.&lt;/span&gt;get(url, auth&lt;span style="color: #666"&gt;=&lt;/span&gt;auth, timeout&lt;span style="color: #666"&gt;=&lt;/span&gt;timeout_min &lt;span style="color: #666"&gt;*&lt;/span&gt; &lt;span style="color: #666"&gt;60&lt;/span&gt;, stream&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;True&lt;/span&gt;)
            res&lt;span style="color: #666"&gt;.&lt;/span&gt;raise_for_status()
            response &lt;span style="color: #666"&gt;=&lt;/span&gt; res
        &lt;span style="color: #008000; font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;Exception&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; e:
            error &lt;span style="color: #666"&gt;=&lt;/span&gt; e

    req_thread &lt;span style="color: #666"&gt;=&lt;/span&gt; threading&lt;span style="color: #666"&gt;.&lt;/span&gt;Thread(target&lt;span style="color: #666"&gt;=&lt;/span&gt;make_request, daemon&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;True&lt;/span&gt;)
    req_thread&lt;span style="color: #666"&gt;.&lt;/span&gt;start()

    spinner &lt;span style="color: #666"&gt;=&lt;/span&gt; Spinner(&lt;span style="color: #BA2121"&gt;&amp;quot;dots&amp;quot;&lt;/span&gt;, style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;cyan&amp;quot;&lt;/span&gt;)

    &lt;span style="color: #008000; font-weight: bold"&gt;with&lt;/span&gt; Live(console&lt;span style="color: #666"&gt;=&lt;/span&gt;console, refresh_per_second&lt;span style="color: #666"&gt;=10&lt;/span&gt;, transient&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;True&lt;/span&gt;) &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; live:
        &lt;span style="color: #008000; font-weight: bold"&gt;while&lt;/span&gt; req_thread&lt;span style="color: #666"&gt;.&lt;/span&gt;is_alive():
            timer_text &lt;span style="color: #666"&gt;=&lt;/span&gt; get_timer_content(start_time, start_ts)
            renderable &lt;span style="color: #666"&gt;=&lt;/span&gt; Text&lt;span style="color: #666"&gt;.&lt;/span&gt;assemble(spinner&lt;span style="color: #666"&gt;.&lt;/span&gt;render(time&lt;span style="color: #666"&gt;.&lt;/span&gt;time()), &lt;span style="color: #BA2121"&gt;&amp;quot; &amp;quot;&lt;/span&gt;, timer_text)
            live&lt;span style="color: #666"&gt;.&lt;/span&gt;update(renderable)
            req_thread&lt;span style="color: #666"&gt;.&lt;/span&gt;join(timeout&lt;span style="color: #666"&gt;=0.1&lt;/span&gt;)

    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; error:
        &lt;span style="color: #008000; font-weight: bold"&gt;raise&lt;/span&gt; error
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #A2F; font-weight: bold"&gt;not&lt;/span&gt; response:
        &lt;span style="color: #008000; font-weight: bold"&gt;raise&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;RuntimeError&lt;/span&gt;(&lt;span style="color: #BA2121"&gt;&amp;quot;Request thread died without response or error.&amp;quot;&lt;/span&gt;)

    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; response


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;consume_response&lt;/span&gt;(response: requests&lt;span style="color: #666"&gt;.&lt;/span&gt;Response, download: &lt;span style="color: #008000"&gt;bool&lt;/span&gt;) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;tuple&lt;/span&gt;[&lt;span style="color: #008000"&gt;int&lt;/span&gt;, &lt;span style="color: #008000"&gt;int&lt;/span&gt;]:
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Handles the progress bar and processes the incoming data stream.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    total_size &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;int&lt;/span&gt;(response&lt;span style="color: #666"&gt;.&lt;/span&gt;headers&lt;span style="color: #666"&gt;.&lt;/span&gt;get(&lt;span style="color: #BA2121"&gt;&amp;quot;content-length&amp;quot;&lt;/span&gt;, &lt;span style="color: #666"&gt;0&lt;/span&gt;))
    line_count &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #666"&gt;0&lt;/span&gt;
    total_bytes &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #666"&gt;0&lt;/span&gt;

    &lt;span style="color: #008000; font-weight: bold"&gt;with&lt;/span&gt; Progress(
        SpinnerColumn(),
        TextColumn(&lt;span style="color: #BA2121"&gt;&amp;quot;[progress.description]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{task.description}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;),
        BarColumn(),
        DownloadColumn(),
        TransferSpeedColumn(),
        console&lt;span style="color: #666"&gt;=&lt;/span&gt;console,
        transient&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;True&lt;/span&gt;,
    ) &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; progress:
        desc &lt;span style="color: #666"&gt;=&lt;/span&gt; (
            &lt;span style="color: #BA2121"&gt;&amp;quot;[cyan]Downloading content...&amp;quot;&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; download &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;[cyan]Streaming content...&amp;quot;&lt;/span&gt;
        )
        task_id &lt;span style="color: #666"&gt;=&lt;/span&gt; progress&lt;span style="color: #666"&gt;.&lt;/span&gt;add_task(desc, total&lt;span style="color: #666"&gt;=&lt;/span&gt;total_size &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; total_size &lt;span style="color: #666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #666"&gt;0&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;)

        &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; download:
            timestamp &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now()&lt;span style="color: #666"&gt;.&lt;/span&gt;strftime(&lt;span style="color: #BA2121"&gt;&amp;quot;%Y%m&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;%d&lt;/span&gt;&lt;span style="color: #BA2121"&gt;_%H%M%S&amp;quot;&lt;/span&gt;)
            filepath &lt;span style="color: #666"&gt;=&lt;/span&gt; Path(&lt;span style="color: #19177C"&gt;__file__&lt;/span&gt;)&lt;span style="color: #666"&gt;.&lt;/span&gt;parent &lt;span style="color: #666"&gt;/&lt;/span&gt; &lt;span style="color: #BA2121"&gt;f&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;timestamp&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;.csv&amp;quot;&lt;/span&gt;

            &lt;span style="color: #008000; font-weight: bold"&gt;with&lt;/span&gt; &lt;span style="color: #008000"&gt;open&lt;/span&gt;(filepath, &lt;span style="color: #BA2121"&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;) &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; f:
                &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; chunk &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; response&lt;span style="color: #666"&gt;.&lt;/span&gt;iter_content(chunk_size&lt;span style="color: #666"&gt;=8192&lt;/span&gt;):
                    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; chunk:
                        f&lt;span style="color: #666"&gt;.&lt;/span&gt;write(chunk)
                        progress&lt;span style="color: #666"&gt;.&lt;/span&gt;update(task_id, advance&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000"&gt;len&lt;/span&gt;(chunk))

            total_bytes &lt;span style="color: #666"&gt;=&lt;/span&gt; filepath&lt;span style="color: #666"&gt;.&lt;/span&gt;stat()&lt;span style="color: #666"&gt;.&lt;/span&gt;st_size
            &lt;span style="color: #008000; font-weight: bold"&gt;with&lt;/span&gt; &lt;span style="color: #008000"&gt;open&lt;/span&gt;(filepath, &lt;span style="color: #BA2121"&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;) &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; f:
                &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; _ &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; f:
                    line_count &lt;span style="color: #666"&gt;+=&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt;
        &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;:
            &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; line &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; response&lt;span style="color: #666"&gt;.&lt;/span&gt;iter_lines():
                &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; line:
                    line_count &lt;span style="color: #666"&gt;+=&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt;
                    total_bytes &lt;span style="color: #666"&gt;+=&lt;/span&gt; &lt;span style="color: #008000"&gt;len&lt;/span&gt;(line) &lt;span style="color: #666"&gt;+&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt;
                    progress&lt;span style="color: #666"&gt;.&lt;/span&gt;update(task_id, advance&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000"&gt;len&lt;/span&gt;(line) &lt;span style="color: #666"&gt;+&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt;)

    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; line_count, total_bytes


&lt;span style="color: #3D7B7B; font-style: italic"&gt;# --- Orchestrator ---&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;run_timing_attempt&lt;/span&gt;(
    url: &lt;span style="color: #008000"&gt;str&lt;/span&gt;, auth: HTTPBasicAuth, timeout_min: &lt;span style="color: #008000"&gt;int&lt;/span&gt;, download: &lt;span style="color: #008000"&gt;bool&lt;/span&gt;
) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;timedelta &lt;span style="color: #666"&gt;|&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;:
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #BA2121; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Orchestrates a single request and returns the duration.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    start_time &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now()

    &lt;span style="color: #008000; font-weight: bold"&gt;try&lt;/span&gt;:
        response &lt;span style="color: #666"&gt;=&lt;/span&gt; wait_for_response(url, auth, timeout_min)
        lines, bytes_count &lt;span style="color: #666"&gt;=&lt;/span&gt; consume_response(response, download)

        duration &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now() &lt;span style="color: #666"&gt;-&lt;/span&gt; start_time

        log&lt;span style="color: #666"&gt;.&lt;/span&gt;info(&lt;span style="color: #BA2121"&gt;f&amp;quot;Lines:    [bold white]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;lines&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;,&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[/]&amp;quot;&lt;/span&gt;)
        log&lt;span style="color: #666"&gt;.&lt;/span&gt;info(&lt;span style="color: #BA2121"&gt;f&amp;quot;Size:     &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;format_size(bytes_count)&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;)
        log&lt;span style="color: #666"&gt;.&lt;/span&gt;info(&lt;span style="color: #BA2121"&gt;f&amp;quot;Status:   [bold green]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;response&lt;span style="color: #666"&gt;.&lt;/span&gt;status_code&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[/]&amp;quot;&lt;/span&gt;)
        log&lt;span style="color: #666"&gt;.&lt;/span&gt;info(&lt;span style="color: #BA2121"&gt;f&amp;quot;Duration: [bold yellow]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;duration&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[/]&amp;quot;&lt;/span&gt;)
        &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; duration

    &lt;span style="color: #008000; font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;Exception&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;as&lt;/span&gt; e:
        duration &lt;span style="color: #666"&gt;=&lt;/span&gt; datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;now() &lt;span style="color: #666"&gt;-&lt;/span&gt; start_time
        log&lt;span style="color: #666"&gt;.&lt;/span&gt;error(
            &lt;span style="color: #BA2121"&gt;f&amp;quot;Request [bold red]FAILED[/] after &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;duration&lt;span style="color: #666"&gt;.&lt;/span&gt;total_seconds()&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;.1f&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;s. Error: &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;e&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;
        )
        log&lt;span style="color: #666"&gt;.&lt;/span&gt;warning(&lt;span style="color: #BA2121"&gt;f&amp;quot;Cooldown: Sleeping for &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;timeout_min&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;/&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;2&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt; minutes...&amp;quot;&lt;/span&gt;)
        time&lt;span style="color: #666"&gt;.&lt;/span&gt;sleep((timeout_min &lt;span style="color: #666"&gt;/&lt;/span&gt; &lt;span style="color: #666"&gt;2&lt;/span&gt;) &lt;span style="color: #666"&gt;*&lt;/span&gt; &lt;span style="color: #666"&gt;60&lt;/span&gt;)
        &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;


&lt;span style="color: #3D7B7B; font-style: italic"&gt;# --- Entry Point ---&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #00F"&gt;main&lt;/span&gt;(argv: Sequence[&lt;span style="color: #008000"&gt;str&lt;/span&gt;] &lt;span style="color: #666"&gt;|&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt; &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;) &lt;span style="color: #666"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #008000"&gt;int&lt;/span&gt;:
    parser &lt;span style="color: #666"&gt;=&lt;/span&gt; argparse&lt;span style="color: #666"&gt;.&lt;/span&gt;ArgumentParser(
        description&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Time a Workday RaaS request.&amp;quot;&lt;/span&gt;, formatter_class&lt;span style="color: #666"&gt;=&lt;/span&gt;RichHelpFormatter
    )
    parser&lt;span style="color: #666"&gt;.&lt;/span&gt;add_argument(&lt;span style="color: #BA2121"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;, help&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;The RaaS URL to request.&amp;quot;&lt;/span&gt;)
    parser&lt;span style="color: #666"&gt;.&lt;/span&gt;add_argument(&lt;span style="color: #BA2121"&gt;&amp;quot;--user&amp;quot;&lt;/span&gt;, help&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Workday ISU Username&amp;quot;&lt;/span&gt;)
    parser&lt;span style="color: #666"&gt;.&lt;/span&gt;add_argument(
        &lt;span style="color: #BA2121"&gt;&amp;quot;--count&amp;quot;&lt;/span&gt;, &lt;span style="color: #008000"&gt;type&lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000"&gt;int&lt;/span&gt;, default&lt;span style="color: #666"&gt;=1&lt;/span&gt;, help&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Number of times to run (default: 1)&amp;quot;&lt;/span&gt;
    )
    parser&lt;span style="color: #666"&gt;.&lt;/span&gt;add_argument(
        &lt;span style="color: #BA2121"&gt;&amp;quot;--timeout&amp;quot;&lt;/span&gt;, &lt;span style="color: #008000"&gt;type&lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #008000"&gt;int&lt;/span&gt;, default&lt;span style="color: #666"&gt;=1&lt;/span&gt;, help&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Timeout in minutes (default: 1)&amp;quot;&lt;/span&gt;
    )
    parser&lt;span style="color: #666"&gt;.&lt;/span&gt;add_argument(
        &lt;span style="color: #BA2121"&gt;&amp;quot;--download&amp;quot;&lt;/span&gt;, action&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;store_true&amp;quot;&lt;/span&gt;, help&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Save the first run as CSV&amp;quot;&lt;/span&gt;
    )

    args &lt;span style="color: #666"&gt;=&lt;/span&gt; parser&lt;span style="color: #666"&gt;.&lt;/span&gt;parse_args(argv)

    username &lt;span style="color: #666"&gt;=&lt;/span&gt; args&lt;span style="color: #666"&gt;.&lt;/span&gt;user &lt;span style="color: #A2F; font-weight: bold"&gt;or&lt;/span&gt; console&lt;span style="color: #666"&gt;.&lt;/span&gt;input(&lt;span style="color: #BA2121"&gt;&amp;quot;[bold green]Enter Username:[/] &amp;quot;&lt;/span&gt;)
    password &lt;span style="color: #666"&gt;=&lt;/span&gt; getpass&lt;span style="color: #666"&gt;.&lt;/span&gt;getpass(&lt;span style="color: #BA2121"&gt;&amp;quot;Enter Password: &amp;quot;&lt;/span&gt;)
    auth &lt;span style="color: #666"&gt;=&lt;/span&gt; HTTPBasicAuth(username, password)

    results: &lt;span style="color: #008000"&gt;list&lt;/span&gt;[datetime&lt;span style="color: #666"&gt;.&lt;/span&gt;timedelta &lt;span style="color: #666"&gt;|&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;] &lt;span style="color: #666"&gt;=&lt;/span&gt; []

    &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #008000"&gt;range&lt;/span&gt;(&lt;span style="color: #666"&gt;1&lt;/span&gt;, args&lt;span style="color: #666"&gt;.&lt;/span&gt;count &lt;span style="color: #666"&gt;+&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt;):
        console&lt;span style="color: #666"&gt;.&lt;/span&gt;rule(&lt;span style="color: #BA2121"&gt;f&amp;quot;[bold blue]Request &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;i&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;02d&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;/&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;args&lt;span style="color: #666"&gt;.&lt;/span&gt;count&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;02d&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[/]&amp;quot;&lt;/span&gt;)

        duration &lt;span style="color: #666"&gt;=&lt;/span&gt; run_timing_attempt(
            url&lt;span style="color: #666"&gt;=&lt;/span&gt;args&lt;span style="color: #666"&gt;.&lt;/span&gt;url,
            auth&lt;span style="color: #666"&gt;=&lt;/span&gt;auth,
            timeout_min&lt;span style="color: #666"&gt;=&lt;/span&gt;args&lt;span style="color: #666"&gt;.&lt;/span&gt;timeout,
            download&lt;span style="color: #666"&gt;=&lt;/span&gt;args&lt;span style="color: #666"&gt;.&lt;/span&gt;download &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; i &lt;span style="color: #666"&gt;==&lt;/span&gt; &lt;span style="color: #666"&gt;1&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;False&lt;/span&gt;,
        )
        results&lt;span style="color: #666"&gt;.&lt;/span&gt;append(duration)
        &lt;span style="color: #008000"&gt;print&lt;/span&gt;()

    &lt;span style="color: #3D7B7B; font-style: italic"&gt;# Summary Table&lt;/span&gt;
    table &lt;span style="color: #666"&gt;=&lt;/span&gt; Table(title&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #AA5D1F; font-weight: bold"&gt;\n&lt;/span&gt;&lt;span style="color: #BA2121"&gt;📊 Execution Summary&amp;quot;&lt;/span&gt;, title_style&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;bold underline&amp;quot;&lt;/span&gt;)
    table&lt;span style="color: #666"&gt;.&lt;/span&gt;add_column(&lt;span style="color: #BA2121"&gt;&amp;quot;Run #&amp;quot;&lt;/span&gt;, justify&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;center&amp;quot;&lt;/span&gt;)
    table&lt;span style="color: #666"&gt;.&lt;/span&gt;add_column(&lt;span style="color: #BA2121"&gt;&amp;quot;Duration (Min:Sec)&amp;quot;&lt;/span&gt;, justify&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;right&amp;quot;&lt;/span&gt;)
    table&lt;span style="color: #666"&gt;.&lt;/span&gt;add_column(&lt;span style="color: #BA2121"&gt;&amp;quot;Status&amp;quot;&lt;/span&gt;, justify&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;)

    successes &lt;span style="color: #666"&gt;=&lt;/span&gt; [d &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; d &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; results &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; d &lt;span style="color: #A2F; font-weight: bold"&gt;is&lt;/span&gt; &lt;span style="color: #A2F; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;None&lt;/span&gt;]
    &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; i, delta &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #008000"&gt;enumerate&lt;/span&gt;(results, &lt;span style="color: #666"&gt;1&lt;/span&gt;):
        &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; delta:
            m, s &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;divmod&lt;/span&gt;(&lt;span style="color: #008000"&gt;int&lt;/span&gt;(delta&lt;span style="color: #666"&gt;.&lt;/span&gt;total_seconds()), &lt;span style="color: #666"&gt;60&lt;/span&gt;)
            table&lt;span style="color: #666"&gt;.&lt;/span&gt;add_row(&lt;span style="color: #008000"&gt;str&lt;/span&gt;(i), &lt;span style="color: #BA2121"&gt;f&amp;quot;&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;m&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;m &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;s&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;02d&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;s&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;[green]SUCCESS[/]&amp;quot;&lt;/span&gt;)
        &lt;span style="color: #008000; font-weight: bold"&gt;else&lt;/span&gt;:
            table&lt;span style="color: #666"&gt;.&lt;/span&gt;add_row(&lt;span style="color: #008000"&gt;str&lt;/span&gt;(i), &lt;span style="color: #BA2121"&gt;&amp;quot;N/A&amp;quot;&lt;/span&gt;, &lt;span style="color: #BA2121"&gt;&amp;quot;[red]FAILED[/]&amp;quot;&lt;/span&gt;)

    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; successes:
        avg_s &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;sum&lt;/span&gt;(d&lt;span style="color: #666"&gt;.&lt;/span&gt;total_seconds() &lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt; d &lt;span style="color: #A2F; font-weight: bold"&gt;in&lt;/span&gt; successes) &lt;span style="color: #666"&gt;/&lt;/span&gt; &lt;span style="color: #008000"&gt;len&lt;/span&gt;(successes)
        m, s &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;divmod&lt;/span&gt;(&lt;span style="color: #008000"&gt;int&lt;/span&gt;(avg_s), &lt;span style="color: #666"&gt;60&lt;/span&gt;)
        table&lt;span style="color: #666"&gt;.&lt;/span&gt;caption &lt;span style="color: #666"&gt;=&lt;/span&gt; &lt;span style="color: #BA2121"&gt;f&amp;quot;Average Duration (Successes): [bold yellow]&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;m&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;m &lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;{&lt;/span&gt;s&lt;span style="color: #A45A77; font-weight: bold"&gt;:&lt;/span&gt;&lt;span style="color: #BA2121"&gt;02d&lt;/span&gt;&lt;span style="color: #A45A77; font-weight: bold"&gt;}&lt;/span&gt;&lt;span style="color: #BA2121"&gt;s[/]&amp;quot;&lt;/span&gt;

    console&lt;span style="color: #666"&gt;.&lt;/span&gt;print(table)
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #666"&gt;0&lt;/span&gt;


&lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #19177C"&gt;__name__&lt;/span&gt; &lt;span style="color: #666"&gt;==&lt;/span&gt; &lt;span style="color: #BA2121"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;:
    &lt;span style="color: #008000; font-weight: bold"&gt;try&lt;/span&gt;:
        &lt;span style="color: #008000; font-weight: bold"&gt;raise&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;SystemExit&lt;/span&gt;(main())
    &lt;span style="color: #008000; font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #CB3F38; font-weight: bold"&gt;KeyboardInterrupt&lt;/span&gt;:
        console&lt;span style="color: #666"&gt;.&lt;/span&gt;print(&lt;span style="color: #BA2121"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #AA5D1F; font-weight: bold"&gt;\n&lt;/span&gt;&lt;span style="color: #BA2121"&gt;[bold red]Process interrupted by user.[/]&amp;quot;&lt;/span&gt;)
        os&lt;span style="color: #666"&gt;.&lt;/span&gt;_exit(&lt;span style="color: #666"&gt;1&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Ffj9hev%2F&amp;title=Time+Workday+RaaS+Requests" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Mon, 12 Jan 2026 21:14:52 +0000</pubDate><guid isPermaLink="false">fj9hev</guid><category>Workday Integrations</category><category>Workday</category><category>Python</category><category>uv</category></item><item><title>TIL: Workday Studio Decimal Formatting</title><link>https://sglmr.com/blog/wr3vcf/</link><description>&lt;p&gt;Today I was trying to clean up the log message for a number and wanted to add some formatting to the decimal to add 0 padding so &lt;code&gt;2&lt;/code&gt; becomes &lt;code&gt;0002&lt;/code&gt; or &lt;code&gt;2345&lt;/code&gt; becomes &lt;code&gt;2,345&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="add-zero-padding"&gt;Add zero padding&lt;a class="headerlink" href="#add-zero-padding" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;count&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;23&lt;/span&gt;;

props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;fmt&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;java.&lt;span style="color: #687822"&gt;text&lt;/span&gt;.&lt;span style="color: #687822"&gt;DecimalFormat&lt;/span&gt;(&lt;span style="color: #BA2121"&gt;&amp;quot;00000&amp;quot;&lt;/span&gt;);
props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;fmt&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;.&lt;span style="color: #687822"&gt;format&lt;/span&gt;(props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;count&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;);&lt;span style="color: #BBB"&gt; &lt;/span&gt;

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// result: &amp;#39;00023&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="add-thousands-separator"&gt;Add thousands separator&lt;a class="headerlink" href="#add-thousands-separator" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;This seems like a really roundabout way... but it worked...&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;count&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;2345&lt;/span&gt;

props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;formattedCount&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #666"&gt;=&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;java.&lt;span style="color: #687822"&gt;text&lt;/span&gt;.&lt;span style="color: #687822"&gt;DecimalFormat&lt;/span&gt;(&lt;span style="color: #BA2121"&gt;&amp;quot;#,###&amp;quot;&lt;/span&gt;).&lt;span style="color: #687822"&gt;format&lt;/span&gt;(Long.&lt;span style="color: #687822"&gt;parseLong&lt;/span&gt;(props&lt;span style="color: #666"&gt;[&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;count&amp;quot;&lt;/span&gt;&lt;span style="color: #666"&gt;]&lt;/span&gt;.&lt;span style="color: #687822"&gt;toString&lt;/span&gt;()))

&lt;span style="color: #3D7B7B; font-style: italic"&gt;// result: &amp;#39;2,345&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fwr3vcf%2F&amp;title=TIL%3A+Workday+Studio+Decimal+Formatting" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Wed, 17 Dec 2025 22:21:47 +0000</pubDate><guid isPermaLink="false">wr3vcf</guid><category>Workday Studio</category><category>TIL</category></item><item><title>TIL: Force ASCII output with XSLT</title><link>https://sglmr.com/blog/nm9p49/</link><description>&lt;p&gt;Today I learned how to get ASCII output from an XSLT transformation using "unicode decomposition". In the past I've seen and used long character maps or translate, but they don't seem to cover every use case. This one seems to be a little more elegant of a solution.&lt;/p&gt;
&lt;h2 id="source"&gt;Source&lt;a class="headerlink" href="#source" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This was a Workday Community &lt;a href="https://collaborate.workday.com/t5/Platform-and-Product-Extensions/How-to-remove-special-characters-or-non-ascii-characters-using/m-p/18646/highlight/true#M2158"&gt;question response by Parry&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Something didn't look like it copy+pasted well with Parry's solution. I asked AI to help me clean it up and this is what it came up with:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Con's&lt;/strong&gt;: This is an "all or nothing" transformation. It can sometimes strip out a character unintentionally when the string contains a mix of Latin-1 and non-Latin-1 characters. It can be acceptable when not crashing is a higher priority than preserving accents.&lt;/p&gt;
&lt;h2 id="code"&gt;Code&lt;a class="headerlink" href="#code" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:stylesheet&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;version=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;2.0&amp;quot;&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #687822"&gt;xmlns:xsl=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;http://www.w3.org/1999/XSL/Transform&amp;quot;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #687822"&gt;xmlns:xs=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #687822"&gt;xmlns:my=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;http://www.example.com/functions&amp;quot;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #687822"&gt;exclude-result-prefixes=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;xs my&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;

&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;&amp;lt;!-- The function --&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:function&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;my:stripAccents&amp;quot;&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;as=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;xs:string&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:param&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;as=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;xs:string?&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;

&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:choose&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:when&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;test=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;not($input)&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;                &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:value-of&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;select=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;&amp;#39;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:when&amp;gt;&lt;/span&gt;

&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:when&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;test=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;matches($input, &amp;#39;^[\x00-\xFF]+$&amp;#39;)&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;                &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:value-of&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;select=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;$input&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:when&amp;gt;&lt;/span&gt;

&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:otherwise&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;                &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:value-of&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;select=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;replace(normalize-unicode($input, &amp;#39;NFKD&amp;#39;), &amp;#39;[\p{M}]&amp;#39;, &amp;#39;&amp;#39;)&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;            &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:otherwise&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:choose&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:function&amp;gt;&lt;/span&gt;

&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;&amp;lt;!-- How to call it --&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:template&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;match=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;Row&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:value-of&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;select=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;my:stripAccents(CustomerName)&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:template&amp;gt;&lt;/span&gt;

&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:stylesheet&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Generally speaking, using translate is not a robust method for doing character encoding.  You'll ultimately miss characters you didn't even know existed. For example, you do not handle Hungarian names that have letters like Ő.&lt;/p&gt;
&lt;p&gt;I would suggest trying a method called Unicode decomposition.  All Unicode characters (the default encoding for Workday) have predefined method of splitting a character into atomic parts.  In your example above, Â would become the combining character ^ (circonflex) + A.  When you've decomposed the character as such, you can remove all non-ascii bytes (in this case the circonflex).&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;&amp;lt;!-- if it&amp;#39;s entirely ISO-8859-1, then let it go through normal --&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt;    &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:function&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;this:stripAccents&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:param&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;name=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;as=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;xs:string&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #3D7B7B; font-style: italic"&gt;&amp;lt;!-- this is the regex string for all ISO-8859-1 encoded characters --&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt;        &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;xsl:value-of&lt;/span&gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&lt;span style="color: #687822"&gt;select=&lt;/span&gt;&lt;span style="color: #BA2121"&gt;&amp;quot;if(matches($input,&amp;#39;^[&amp;amp;#x20;-&amp;amp;#xFF;]+$&amp;#39;))            then($input)            else(            &amp;lt;!-- This line replaces all non-ISO-8859-1 characters with the empty                 string. i.e. where the accent removal takes place --&amp;gt;            replace(normalize-unicode($input, &amp;#39;NFKD&amp;#39;),&amp;#39;[\p{M}]&amp;#39;,&amp;#39;&amp;#39;)            )&amp;quot;&lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #BBB"&gt;          &lt;/span&gt;&lt;span style="color: #008000; font-weight: bold"&gt;&amp;lt;/xsl:function&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Usage would look like this:&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;this:stripAccents(&amp;quot;Þórr&amp;quot;)Þórr&lt;span style="color: #BBB"&gt; &lt;/span&gt;==&amp;gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;Þorrsince&lt;span style="color: #BBB"&gt; &lt;/span&gt;Þ&lt;span style="color: #BBB"&gt; &lt;/span&gt;is&lt;span style="color: #BBB"&gt; &lt;/span&gt;part&lt;span style="color: #BBB"&gt; &lt;/span&gt;of&lt;span style="color: #BBB"&gt; &lt;/span&gt;the&lt;span style="color: #BBB"&gt; &lt;/span&gt;ISO-8859-1&lt;span style="color: #BBB"&gt; &lt;/span&gt;char&lt;span style="color: #BBB"&gt; &lt;/span&gt;set
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If this does not meet all of your requirements, you can also use the XSLT function replace in conjunction with codepoints-to-string.  codepoints-to-string takes the HTML entity number and converts it to a string. This is useful for representing hard to type or difficult to encode characters.  In the example below, I'm using this to replace EN-DASHes ( – ) since it cannot be casted to ASCII using decomposition.&lt;/p&gt;
&lt;div class="highlight" style="background: #f8f8f8"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;replace(wd:Name,codepoints-to-string(8211),&amp;#39;-&amp;#39;)&amp;quot;Hello&lt;span style="color: #BBB"&gt; &lt;/span&gt;–&lt;span style="color: #BBB"&gt; &lt;/span&gt;World&amp;quot;&lt;span style="color: #BBB"&gt; &lt;/span&gt;==&amp;gt;&lt;span style="color: #BBB"&gt; &lt;/span&gt;&amp;quot;Hello&lt;span style="color: #BBB"&gt; &lt;/span&gt;-&lt;span style="color: #BBB"&gt; &lt;/span&gt;World&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hope that helps!  If you require only ASCII, I would suggest first using decomposition and then replacing characters such as Þ with a predefined transliteration that the vendor expects.  Removing characters such as this or ð could potentially cause issues with legal names.&lt;/p&gt;
&lt;p&gt;Parry&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fnm9p49%2F&amp;title=TIL%3A+Force+ASCII+output+with+XSLT" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Tue, 16 Dec 2025 18:05:33 +0000</pubDate><guid isPermaLink="false">nm9p49</guid><category>XML</category><category>Workday</category><category>XSLT</category></item><item><title>TIL: Workday data privacy notice options</title><link>https://sglmr.com/blog/gvevn5/</link><description>&lt;p&gt;TIL about a list of places Workday lets you display something that resembles a data privacy notice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://community-content.workday.com/content/workday-community/en-us/reference/learn/resources/workday-privacy-features-guide-for-human-capital-management.html?lang=en-us"&gt;Workday Privacy Features Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 id="notice-and-information"&gt;Notice and Information&lt;a class="headerlink" href="#notice-and-information" title="Permanent link"&gt;&amp;para;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Providing Notice&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Workday, when acting as a data processor, doesn’t under privacy laws provide “notice of processing activities” for its data processor activities. It’s you, the Workday customer, who determines which features and functionality are carried out on the Workday platform and the legal basis for this processing (such as consent, performance of a contract or in fulfillment of legal obligations). The Workday HCM platform provides mechanisms to enable customers to provide notice to the end-user which can include information on personal data processing, including any cookies used, as provided in the following mechanisms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Media Marking Text in Edit Tenant - Setup allows you to present a brief message on the tenant Home Page. This can include full URLs or other content.&lt;/li&gt;
&lt;li&gt;You can host you privacy notices entirely in the Workday platform or link to them from various mechanisms to share how the employee data is processed for the purposes of employment and associated activities. The following features that can be leveraged to provide transparency, including:&lt;ul&gt;
&lt;li&gt;Dashboards with non-expiring announcements&lt;/li&gt;
&lt;li&gt;Worklets with external links&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;On career sites, when you want to use certain features of the External Career Site, such as Google Analytics or Tracking Pixels, you may determine that the end-user needs to be able to decline these cookies or trackers. To facilitate this requirement, configure the EU Cookie Policy Message and when it should be displayed. This cookie banner can provide the necessary transparency directly in the message or can include a clickable link to a more detailed privacy or cookie statement.&lt;/li&gt;
&lt;li&gt;If the career site is not using any of these optional cookies, sidebars can be configured to contain links, images, videos, and so on that are presented on every page that includes the sidebar. Sidebars may help support you in delivering transparency to the end-users of your career site. These sidebars can be configured to contain a component that provides information or links to a cookie or privacy notice.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2Fgvevn5%2F&amp;title=TIL%3A+Workday+data+privacy+notice+options" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Thu, 11 Dec 2025 17:12:59 +0000</pubDate><guid isPermaLink="false">gvevn5</guid><category>Workday</category></item><item><title>Printable 3-Rectangle Template for Drawabox.com Homework Exercises</title><link>https://sglmr.com/blog/4zhqqv/</link><description>&lt;p&gt;I created a printable to avoid spending the first 10 minutes of drawing on setting up a template.&lt;/p&gt;
&lt;p&gt;I'm doing more &lt;a href="https://drawabox.com"&gt;drawabox.com&lt;/a&gt; and less &lt;a href="https://proko.com"&gt;Proko&lt;/a&gt; lately. &lt;/p&gt;
&lt;p&gt;There are a few homework exercises where the first task is to draw 3 rectangular frames before drawing in them. I got tired of drawing them and debating what the gaps should be after the first one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://sglmr.com/media/file/2025/sglmr-drawabox-printable-3-frame-rectangle-template.html"&gt;Printable 3-Rectangle Template for Drawabox Homework Exercises&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I've only been able to test it on 8.5"x11" paper, but it should also scale okay to work on other paper sizes.&lt;/li&gt;
&lt;li&gt;The text on the page won't print.&lt;/li&gt;
&lt;li&gt;There are tick marks in the middle to draw optional lines across each box. &lt;/li&gt;
&lt;li&gt;Depending on your computer, browser, and printer, you might need to specify custom margins when printing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="drawabox.com 3 rectangles for homework" src="https://sglmr.com/media/file/2025/drawabox-3-rectangle-template-photo.jpeg"&gt;&lt;/p&gt;&lt;img src="https://sglmr.goatcounter.com/count?p=%2Fblog%2F4zhqqv%2F&amp;title=Printable+3-Rectangle+Template+for+Drawabox.com+Homework+Exercises" width="1" height="1" alt="" style="position:absolute;visibility:hidden"&gt;</description><pubDate>Mon, 08 Dec 2025 14:50:01 +0000</pubDate><guid isPermaLink="false">4zhqqv</guid><category>Scribbles</category><category>Drawing</category><category>drawabox</category></item></channel></rss>