summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.txt5
-rw-r--r--_log/e-reader.md36
-rw-r--r--_log/neo4j-a-star-search.md19
-rw-r--r--_site/feed.xml2
-rw-r--r--_site/log/e-reader/index.html36
-rw-r--r--_site/log/neo4j-a-star-search/index.html17
-rw-r--r--_site/posts.xml2
7 files changed, 63 insertions, 54 deletions
diff --git a/README.txt b/README.txt
index b744290..32de791 100644
--- a/README.txt
+++ b/README.txt
@@ -8,9 +8,8 @@ $ cd /var/www/htdocs
# chown -R www:www www.asciimx.com
# chmod -R 444 www.asciimx.com/
# chmod u+x,g+x www.asciimx.com/
-# cd www.asciimx.com/
-# find . -type d -exec chmod 554 {} +
-# chmod 554 cgi-bin/find.cgi
+# find www.asciimx.com/ -type d -exec chmod 554 {} +
+# chmod 554 www.asciimx.com/cgi-bin/find.cgi
Search lock setup in chroot
diff --git a/_log/e-reader.md b/_log/e-reader.md
index 2edd5dd..fbc7b94 100644
--- a/_log/e-reader.md
+++ b/_log/e-reader.md
@@ -12,25 +12,26 @@ First project with e-paper displays and ESP32.
<source src="ereader.mp4" type="video/mp4">
</video>
-ESP-WROOM-32, 7.5" Waveshare e-paper display, three buttons (prev/next/sleep).
+System: ESP-WROOM-32, 7.5" Waveshare e-paper display, three buttons
+(prev/next/sleep).
-No local storage—streams books over HTTP. RTC memory tracks reading progress
-between sessions.
+2023-09-23: 512KB SRAM, 4MB flash (shared with FreeRTOS and ESP-IDF). Not
+enough storage for books. Using ESP32's built-in WiFi to stream them over HTTP.
+Recording the reading progress in RTC memory.
-ESP32: 512KB SRAM, 4MB flash (shared with FreeRTOS, ESP-IDF). Not enough to
-store books. Stream from webserver instead.
+Rasterized pages encoded as tightly packed bitmaps (1 byte => 8 pixels), no
+headers, arranged along 48 KB (480x800) boundaries; Reader can stream pages
+using HTTP Range requests with zero server-side logic. Keeps both ends lean.
-Custom EBM file format. Rasterized monochrome bitmaps, one per page (480x800).
-One byte = 8 pixels. Pages on 48KB boundaries—HTTP Range requests work without
-server logic. pdftoebm.py converts PDFs.
+Page table stores 3 pages (prev/current/next) in a circular buffer. When the
+user requests a page, program cycles through the table, updates the screen, and
+downloads the next page.
-Circular buffer holds 3 pages (prev/current/next)--page table. Single-threaded
-approach too slow—user input, SPI, and HTTP on one core causes lag.
+Responsiveness is inadequate. Scheduling GPIO (user input), SPI, and HTTP on
+one core causes input lag. Pinned the GPIO and SPI tasks to one core, the HTTP
+task to the other core.
-Optimizations: pin the GPIO task (responding to user input and updating
-display) to one core, pin the HTTP task to the other core.
-
-Better, but system unresponsive during screen updates. Made SPI transfer async:
+Better, but screen updates are blocking user input; Made SPI transfer async:
```
void epd_draw_async(const uint8_t *buf, size_t n)
@@ -59,11 +60,14 @@ void epd_draw_async(const uint8_t *buf, size_t n)
}
```
-Much better. Squeeze a few more cycles by moving SPI buffer to DMA.
+Much better.
+
+2023-10-06: Moved the page table to DMA-capable memory; Reclaimed a few more
+CPU cycles from the SPI transfers.
Can't think of anything else.
-Outcome: Works but limited. Led to [Etlas](../etlas/).
+Verdict: Works but limited. Led to [Etlas](../etlas/).
Commit:
[7f691c4](https://git.asciimx.com/esp32-e-reader/commit/?id=7f691c46093933b67aab466c0ca582ace8ab73d4)
diff --git a/_log/neo4j-a-star-search.md b/_log/neo4j-a-star-search.md
index 3233428..fe6f33f 100644
--- a/_log/neo4j-a-star-search.md
+++ b/_log/neo4j-a-star-search.md
@@ -4,13 +4,11 @@ date: 2018-03-06
layout: post
---
-Replaced Dijkstra's search for vessel route tracking in Neo4J.
+Work project. Marine vessel tracking with Neo4J hit a limit. Need to store
+13,000 route points; Dijkstra's shortest path search slows after 4,000.
-Tracking 13,000 marine vessel route points. Needed shortest paths between ports
-for arrival prediction. Neo4j's Dijkstra's algorithm slows after 4,000 route
-points.
-
-Implemented A* search using haversine function as heuristic:
+Replaced Dijkstra's algorithm with A* search using haversine function as
+heuristic:
```
private double computeHeuristic(
@@ -50,7 +48,10 @@ private void updateCosts(
}
```
-Outcome: 300x speedup. Scaled to 13,000 route points. Upstreamed changes. <a
+Outcome: 300x speedup. Scaled to 13,000 route points.
+
+Upstreamed changes: <a
href="https://github.com/neo4j-contrib/neo4j-graph-algorithms/releases/tag/3.4.0.0"
-class="external" target="_blank" rel="noopener noreferrer">Neo4J v3.4.0</a>.
-[Full source](https://github.com/neo4j-contrib/neo4j-graph-algorithms/blob/bd9732d9a690319552e134708692acb5a0d6b37c/algo/src/main/java/org/neo4j/graphalgo/impl/ShortestPathAStar.java)
+class="external" target="_blank" rel="noopener noreferrer">Neo4J v3.4.0</a> |
+[Full
+source](https://github.com/neo4j-contrib/neo4j-graph-algorithms/blob/bd9732d9a690319552e134708692acb5a0d6b37c/algo/src/main/java/org/neo4j/graphalgo/impl/ShortestPathAStar.java)
diff --git a/_site/feed.xml b/_site/feed.xml
index cb9e91e..989f4b2 100644
--- a/_site/feed.xml
+++ b/_site/feed.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T17:31:30+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">Search engine (Perl + FastCGI + SA)</title><link href="/log/site-search/" rel="alternate" type="text/html" title="Search engine (Perl + FastCGI + SA)" /><published>2026-01-03T00:00:00+08:00</published><updated>2026-01-03T00:00:00+08:00</updated><id>/log/site-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Article count on the website is growing. Need a way to search.]]></summary></entry><entry><title type="html">Matrix Rain: 2025 refactor</title><link href="/log/matrix-digital-rain/" rel="alternate" type="text/html" title="Matrix Rain: 2025 refactor" /><published>2025-12-21T00:00:00+08:00</published><updated>2025-12-21T00:00:00+08:00</updated><id>/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[The 2022 version worked but had some loose ends. Unicode support was inflexible–couldn’t mix ASCII with Katakana; Phosphor decay was stored in a separate array when it should’ve been packed with RGB; Code was harder to read than it needed to be.]]></summary></entry><entry><title type="html">Fingerprint door lock (LP)</title><link href="/log/fpm-door-lock-lp/" rel="alternate" type="text/html" title="Fingerprint door lock (LP)" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>/log/fpm-door-lock-lp</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Second iteration of the RF door lock. Old version worked but drew too much quiescent current. Sensor and servo pulled 13.8mA and 4.6mA idle. Linear regulators were a disaster. Battery didn’t last 24 hours.]]></summary></entry><entry><title type="html">High-side MOSFET switching</title><link href="/log/mosfet-switches/" rel="alternate" type="text/html" title="High-side MOSFET switching" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Needed low-power switching for the fingerprint door lock. Servo and FPM draw high quiescent current–had to cut power electronically during sleep. MOSFETs can do this.]]></summary></entry><entry><title type="html">ATmega328P at 3.3V and 5V</title><link href="/log/arduino-uno/" rel="alternate" type="text/html" title="ATmega328P at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Quick reference for wiring ATmega328P ICs at 5V and 3.3V. 5V uses 16MHz crystal, 3.3V uses 8MHz.]]></summary></entry><entry><title type="html">Fingerprint door lock (RF)</title><link href="/log/fpm-door-lock-rf/" rel="alternate" type="text/html" title="Fingerprint door lock (RF)" /><published>2025-06-05T00:00:00+08:00</published><updated>2025-06-05T00:00:00+08:00</updated><id>/log/fpm-door-lock-rf</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Wanted to unlock door with fingerprint, wirelessly to avoid drilling.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Built with Andy Zhang for an employer. Tool to automate web scraping script generation.]]></summary></entry><entry><title type="html">Bare-metal ATSAM3X8E</title><link href="/log/arduino-due/" rel="alternate" type="text/html" title="Bare-metal ATSAM3X8E" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Notes on programming bare-metal ATSAM3X8E chips (Arduino Due) using Serial Wire Debug (SwD) protocol.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Repurposed e-reader prototype into something for regular use. News, stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5” Waveshare e-paper + DHT22 sensor.]]></summary></entry><entry><title type="html">ESP32 e-reader prototype</title><link href="/log/e-reader/" rel="alternate" type="text/html" title="ESP32 e-reader prototype" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[First project with e-paper displays and ESP32.]]></summary></entry></feed> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T22:36:11+08:00</updated><id>/feed.xml</id><title type="html">ASCIIMX | Log</title><author><name>W. D. Sadeep Madurange</name></author><entry><title type="html">Search engine (Perl + FastCGI + SA)</title><link href="/log/site-search/" rel="alternate" type="text/html" title="Search engine (Perl + FastCGI + SA)" /><published>2026-01-03T00:00:00+08:00</published><updated>2026-01-03T00:00:00+08:00</updated><id>/log/site-search</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Article count on the website is growing. Need a way to search.]]></summary></entry><entry><title type="html">Matrix Rain: 2025 refactor</title><link href="/log/matrix-digital-rain/" rel="alternate" type="text/html" title="Matrix Rain: 2025 refactor" /><published>2025-12-21T00:00:00+08:00</published><updated>2025-12-21T00:00:00+08:00</updated><id>/log/matrix-digital-rain</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[The 2022 version worked but had some loose ends. Unicode support was inflexible–couldn’t mix ASCII with Katakana; Phosphor decay was stored in a separate array when it should’ve been packed with RGB; Code was harder to read than it needed to be.]]></summary></entry><entry><title type="html">Fingerprint door lock (LP)</title><link href="/log/fpm-door-lock-lp/" rel="alternate" type="text/html" title="Fingerprint door lock (LP)" /><published>2025-08-18T00:00:00+08:00</published><updated>2025-08-18T00:00:00+08:00</updated><id>/log/fpm-door-lock-lp</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Second iteration of the RF door lock. Old version worked but drew too much quiescent current. Sensor and servo pulled 13.8mA and 4.6mA idle. Linear regulators were a disaster. Battery didn’t last 24 hours.]]></summary></entry><entry><title type="html">High-side MOSFET switching</title><link href="/log/mosfet-switches/" rel="alternate" type="text/html" title="High-side MOSFET switching" /><published>2025-06-22T00:00:00+08:00</published><updated>2025-06-22T00:00:00+08:00</updated><id>/log/mosfet-switches</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Needed low-power switching for the fingerprint door lock. Servo and FPM draw high quiescent current–had to cut power electronically during sleep. MOSFETs can do this.]]></summary></entry><entry><title type="html">ATmega328P at 3.3V and 5V</title><link href="/log/arduino-uno/" rel="alternate" type="text/html" title="ATmega328P at 3.3V and 5V" /><published>2025-06-10T00:00:00+08:00</published><updated>2025-06-10T00:00:00+08:00</updated><id>/log/arduino-uno</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Quick reference for wiring ATmega328P ICs at 5V and 3.3V. 5V uses 16MHz crystal, 3.3V uses 8MHz.]]></summary></entry><entry><title type="html">Fingerprint door lock (RF)</title><link href="/log/fpm-door-lock-rf/" rel="alternate" type="text/html" title="Fingerprint door lock (RF)" /><published>2025-06-05T00:00:00+08:00</published><updated>2025-06-05T00:00:00+08:00</updated><id>/log/fpm-door-lock-rf</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Wanted to unlock door with fingerprint, wirelessly to avoid drilling.]]></summary></entry><entry><title type="html">Bumblebee: browser automation</title><link href="/log/bumblebee/" rel="alternate" type="text/html" title="Bumblebee: browser automation" /><published>2025-04-02T00:00:00+08:00</published><updated>2025-04-02T00:00:00+08:00</updated><id>/log/bumblebee</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Built with Andy Zhang for an employer. Tool to automate web scraping script generation.]]></summary></entry><entry><title type="html">Bare-metal ATSAM3X8E</title><link href="/log/arduino-due/" rel="alternate" type="text/html" title="Bare-metal ATSAM3X8E" /><published>2024-09-16T00:00:00+08:00</published><updated>2024-09-16T00:00:00+08:00</updated><id>/log/arduino-due</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Notes on programming bare-metal ATSAM3X8E chips (Arduino Due) using Serial Wire Debug (SwD) protocol.]]></summary></entry><entry><title type="html">Etlas: e-paper dashboard</title><link href="/log/etlas/" rel="alternate" type="text/html" title="Etlas: e-paper dashboard" /><published>2024-09-05T00:00:00+08:00</published><updated>2024-09-05T00:00:00+08:00</updated><id>/log/etlas</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[Repurposed e-reader prototype into something for regular use. News, stocks, weather dashboard. ESP32 NodeMCU D1 + 7.5” Waveshare e-paper + DHT22 sensor.]]></summary></entry><entry><title type="html">ESP32 e-reader prototype</title><link href="/log/e-reader/" rel="alternate" type="text/html" title="ESP32 e-reader prototype" /><published>2023-10-24T00:00:00+08:00</published><updated>2023-10-24T00:00:00+08:00</updated><id>/log/e-reader</id><author><name>W. D. Sadeep Madurange</name></author><summary type="html"><![CDATA[First project with e-paper displays and ESP32.]]></summary></entry></feed> \ No newline at end of file
diff --git a/_site/log/e-reader/index.html b/_site/log/e-reader/index.html
index 23d409b..a5dbc01 100644
--- a/_site/log/e-reader/index.html
+++ b/_site/log/e-reader/index.html
@@ -46,25 +46,26 @@
<source src="ereader.mp4" type="video/mp4" />
</video>
-<p>ESP-WROOM-32, 7.5” Waveshare e-paper display, three buttons (prev/next/sleep).</p>
+<p>System: ESP-WROOM-32, 7.5” Waveshare e-paper display, three buttons
+(prev/next/sleep).</p>
-<p>No local storage—streams books over HTTP. RTC memory tracks reading progress
-between sessions.</p>
+<p>2023-09-23: 512KB SRAM, 4MB flash (shared with FreeRTOS and ESP-IDF). Not
+enough storage for books. Using ESP32’s built-in WiFi to stream them over HTTP.
+Recording the reading progress in RTC memory.</p>
-<p>ESP32: 512KB SRAM, 4MB flash (shared with FreeRTOS, ESP-IDF). Not enough to
-store books. Stream from webserver instead.</p>
+<p>Rasterized pages encoded as tightly packed bitmaps (1 byte =&gt; 8 pixels), no
+headers, arranged along 48 KB (480x800) boundaries; Reader can stream pages
+using HTTP Range requests with zero server-side logic. Keeps both ends lean.</p>
-<p>Custom EBM file format. Rasterized monochrome bitmaps, one per page (480x800).
-One byte = 8 pixels. Pages on 48KB boundaries—HTTP Range requests work without
-server logic. pdftoebm.py converts PDFs.</p>
+<p>Page table stores 3 pages (prev/current/next) in a circular buffer. When the
+user requests a page, program cycles through the table, updates the screen, and
+downloads the next page.</p>
-<p>Circular buffer holds 3 pages (prev/current/next)–page table. Single-threaded
-approach too slow—user input, SPI, and HTTP on one core causes lag.</p>
+<p>Responsiveness is inadequate. Scheduling GPIO (user input), SPI, and HTTP on
+one core causes input lag. Pinned the GPIO and SPI tasks to one core, the HTTP
+task to the other core.</p>
-<p>Optimizations: pin the GPIO task (responding to user input and updating
-display) to one core, pin the HTTP task to the other core.</p>
-
-<p>Better, but system unresponsive during screen updates. Made SPI transfer async:</p>
+<p>Better, but screen updates are blocking user input; Made SPI transfer async:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void epd_draw_async(const uint8_t *buf, size_t n)
{
@@ -92,11 +93,14 @@ display) to one core, pin the HTTP task to the other core.</p>
}
</code></pre></div></div>
-<p>Much better. Squeeze a few more cycles by moving SPI buffer to DMA.</p>
+<p>Much better.</p>
+
+<p>2023-10-06: Moved the page table to DMA-capable memory; Reclaimed a few more
+CPU cycles from the SPI transfers.</p>
<p>Can’t think of anything else.</p>
-<p>Outcome: Works but limited. Led to <a href="../etlas/">Etlas</a>.</p>
+<p>Verdict: Works but limited. Led to <a href="../etlas/">Etlas</a>.</p>
<p>Commit:
<a href="https://git.asciimx.com/esp32-e-reader/commit/?id=7f691c46093933b67aab466c0ca582ace8ab73d4">7f691c4</a></p>
diff --git a/_site/log/neo4j-a-star-search/index.html b/_site/log/neo4j-a-star-search/index.html
index 00f7886..c8c4ce6 100644
--- a/_site/log/neo4j-a-star-search/index.html
+++ b/_site/log/neo4j-a-star-search/index.html
@@ -40,13 +40,11 @@
<h2 class="center" id="title">NEO4J SHORTEST PATH OPTIMIZATION</h2>
<h5 class="center">06 MARCH 2018</h5>
<br>
- <div class="twocol justify"><p>Replaced Dijkstra’s search for vessel route tracking in Neo4J.</p>
+ <div class="twocol justify"><p>Work project. Marine vessel tracking with Neo4J hit a limit. Need to store
+13,000 route points; Dijkstra’s shortest path search slows after 4,000.</p>
-<p>Tracking 13,000 marine vessel route points. Needed shortest paths between ports
-for arrival prediction. Neo4j’s Dijkstra’s algorithm slows after 4,000 route
-points.</p>
-
-<p>Implemented A* search using haversine function as heuristic:</p>
+<p>Replaced Dijkstra’s algorithm with A* search using haversine function as
+heuristic:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>private double computeHeuristic(
final double lat1, final double lon1,
@@ -84,8 +82,11 @@ points.</p>
}
</code></pre></div></div>
-<p>Outcome: 300x speedup. Scaled to 13,000 route points. Upstreamed changes. <a href="https://github.com/neo4j-contrib/neo4j-graph-algorithms/releases/tag/3.4.0.0" class="external" target="_blank" rel="noopener noreferrer">Neo4J v3.4.0</a>.
-<a href="https://github.com/neo4j-contrib/neo4j-graph-algorithms/blob/bd9732d9a690319552e134708692acb5a0d6b37c/algo/src/main/java/org/neo4j/graphalgo/impl/ShortestPathAStar.java">Full source</a></p>
+<p>Outcome: 300x speedup. Scaled to 13,000 route points.</p>
+
+<p>Upstreamed changes: <a href="https://github.com/neo4j-contrib/neo4j-graph-algorithms/releases/tag/3.4.0.0" class="external" target="_blank" rel="noopener noreferrer">Neo4J v3.4.0</a> |
+<a href="https://github.com/neo4j-contrib/neo4j-graph-algorithms/blob/bd9732d9a690319552e134708692acb5a0d6b37c/algo/src/main/java/org/neo4j/graphalgo/impl/ShortestPathAStar.java">Full
+source</a></p>
</div>
<p class="post-author right">by W. D. Sadeep Madurange</p>
</div>
diff --git a/_site/posts.xml b/_site/posts.xml
index b7913a1..47d8e4d 100644
--- a/_site/posts.xml
+++ b/_site/posts.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T17:31:30+08:00</updated><id>/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/posts.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-04T22:36:11+08:00</updated><id>/posts.xml</id><title type="html">ASCIIMX</title><author><name>W. D. Sadeep Madurange</name></author></feed> \ No newline at end of file