บันทึกการสร้าง · Build notes

มดแดงสร้างและเดินระบบอย่างไร สำหรับวิศวกร ตัวเลขทุกตัวมีวันที่กำกับ · How motdang.net is built and run, for engineers. Each figure carries its date.

ภาพรวม · Overview

motdang.net is a Thai-first directory of Chiang Mai and Chiang Rai. The place pages, shelf pages, front page and the index behind the public API are static files written by one Python program, build.py, and uploaded to an R2 bucket (Cloudflare's object storage). A Cloudflare Worker (a script that runs at Cloudflare's edge) reads the bucket and answers each request. Reader submissions go to a second Worker backed by KV (a key-value store). The search at /find reads a D1 database (Cloudflare's hosted SQLite).

build.py uses the standard library and its own modules, 98 *_layer.py files on 2026-10-11, one per feature area. Pillow is imported inside the functions that draw pictures. The share-card renderers also drive headless Chrome and run before the build.

ตัวเลข · Figureวันที่ที่นับ · Counted
88,988 places, 98,687 pages in the sitemapfrom colophon.json as built, 2026-10-10
89,247 canonical records: Chiang Mai 63,743, Chiang Rai 25,504counted from data/canonical/, 2026-10-11, one build later
docs/ 10.4 GB in 271,090 files2026-10-05, from the note in check_room()
build.py 24,400 lines; 184 importer scripts and 9 shell scripts; 157 test filescounted in the working tree, 2026-10-11

ข้อมูลและที่มา · Data and provenance

A record is one object in data/canonical/cm.json or cr.json: id, province, cat and sub (the shelf), name, nameTh, nameEn, lat, lng, geoPrecision, address, phone, website, hours, attrs, sources, confidence, updatedAt. The importers rewrite these files whole. Hand-kept field truth sits in data/curated/ and wins over a crawled record with the same source reference. Researched facts go in curated/enrich.json, which a crawl does not overwrite.

sources is a list. An entry has a type, a ref, usually a via and a fetch date, and where it applies a licence and a release. confidence takes six values: third-party, crawled, official, curated, field, register. geoPrecision takes four: exact (77,085 records on 2026-10-11), approx (6,938), needs-pin (4,849), block (375). A place page shows its provenance as a border: dashed for a crawl, solid for a mapper's tag, bold for a person who stood there.

ต้นทาง · Sourceรายการ · Entries
Overture Maps Places, release 2026-08-19.0, CDLA-Permissive-2.069,459
COD-AB administrative polygons (OCHA, Royal Thai Survey Department): which tambon and amphoe a pin falls in, derived69,918
Address parsing, derived34,604
OpenStreetMap through a slow Overpass crawl, ODbL16,017
OpenStreetMap river lines, derived4,663
National Office of Buddhism temple register1,376
OBEC school register1,302
data.go.th registers1,256
Field entries: a person stood there (signboards, photographs); 930 records carry one942
weed.th directory615
CITIZENinfo (DGA)514

The table counts source entries across all 89,247 records on 2026-10-11. A record carries several, so the rows do not sum to the record count.

Beside the records: weather, PM2.5, river gauges (Royal Irrigation Department), fire hotspots (NASA FIRMS), showtimes, lottery results, exchange rates, events from iCal and JSON feeds, festival dates, iNaturalist sightings and Wikimedia Commons photographs. Each is an importer in importers/ that writes a snapshot to disk and keeps the previous snapshot when its source does not answer. The build makes no network request. importers/ is where the network is used.

A crawl is not a verification. The freshness signal needs a human touch, an owner's claim or a field source, so one bulk import cannot raise it on every record. A dead official site is named and dated, and the Internet Archive copy is linked in place of the dead link; check_links.py runs each morning.

Two crawl details. An Overpass timeout answers HTTP 200 with an empty elements list and the error in remark; with a snapshot-first crawl, caching that leaves a shelf empty for good, so fetch() raises OverpassRemark. A province is an area: provinces are clipped with area["ISO3166-2"="TH-50"], since a rectangle around Chiang Rai returns places in Laos and Myanmar.

รอบเดิน · The walks

Two scheduled jobs on the Mac (launchd). The morning walk runs at 07:09 and gathers the daily sources: weather, air, river gauges, fire hotspots, showtimes, lottery, finance, events, festival dates and link health. It also pulls reader submissions (claims, toilet reports, suggestions) and runs a watchdog that reports a source that came home empty. It writes to disk. The standing walk runs every 20 minutes and publishes whatever is on disk.

A standing-walk round runs these steps in order and stops at the first that says wait:

  1. cache/walk-rest exists: rest. An empty file rests until removed; an ISO timestamp rests until then.
  2. A shared walk lock, and any cache/build.lock held by a live process: stand down.
  3. Source files touched in the last 10 minutes: stand down. A tree nobody has written to for ten minutes is between edits.
  4. Sync claims, toilet reports and suggestions. Import, unless a crawl is out. Rebuild the streets, the temple rounds and the opening-hours lamps.
  5. The same inputs failed the publish gate last round: stand down. cache/gate-fail.fp holds their hash.
  6. Change gate: walk_fingerprint.py hashes what a build reads, drops the generated stamps the writers put inside their output, and compares with cache/last-published.json. No change and the last publish under 20 hours old: stand down.
  7. Refresh weather, air and river gauges after that decision. Stamp BUILD_DATE.
  8. Hand off to the build server, or build locally when cache/build-on-server is absent.

The change gate exists because the first evening of the standing walk republished a byte-identical site four times in ninety minutes, the weather having been refetched at the top of each round. The quiet window replaced a clean-tree rule that let the morning walk publish on 2 mornings of 14. The walk does not commit; cache/standing-walk.jsonl records each round.

Ledger (cache/standing-walk.jsonl), 2026-08-18 to 2026-10-11, counted at 14:24 Bangkok: 1,638 rounds. From 2026-09-20: 230 stood down, 150 handed to the server, 50 published from the Mac; failures were 64 in build.py, 47 in the import, 21 in the deploy, 17 at the publish gate and 2 in the hand-off.

เซิร์ฟเวอร์สร้าง · Build server

Since 2026-10-05 the standing walk hands each round to motdang-build, a server with two shared cores and 3.8 GB of RAM (importers/server_walk.sh). Removing cache/build-on-server builds on the Mac again.

Laptop side, importers/server_link.sh. rsync sends the source tree to a staging folder under a lock, leaving out docs/, docs.next/, docs.prev/, the build lock, the rest file and one private input folder. Every transfer has a 300-second idle timeout: on 2026-10-10 a stalled copy blocked a round and held a lock the next build needed. Then it writes a hand-off id and the UTC time the copy began. With cache/build-from-commit present it also sends the code of HEAD as a tar, so a half-edited file in the working tree is not built (on since 2026-10-10 19:36).

Server side, importers/server_walk.sh. A systemd timer starts it every five minutes. It takes the lock without waiting, looks for a hand-off id it has not tried, honours the same rest file, copies staging into the build tree under a second lock, overlays the committed code, and runs importers/publish_steps.sh: the same build, gates and deploy the Mac ran. One verdict line per attempt goes to walk.jsonl: published, failed, stood-down.

A hand-off is built once. From 2026-10-05 to 10-11 a failed hand-off was built a second time with the code of the last publish; that second build published 0 times in 14 and was removed. A layer that fails puts back its files from the live tree, and a page or site that fails a gate is held at its live version.

Settings: MD_JOBS=1 (one worker process on 3.8 GB), MD_BUILD_TIMEOUT=360m (a full build was 170 minutes on one Mac core on 2026-09-10; the limit was 180 minutes on the server until 2026-10-10), MD_PROFILE set so build_sampler.py records where time goes every two seconds.

ที่มาในรีโป ณ 2026-10-11 · From the repo, 2026-10-11ผล · Result
One function re-parsing a 140 MB file for each shelf map (docstring of _moat_pins in build.py)about 90% of a build's time on motdang-build
Emoji-to-icon sweep over page text (commit ae3eb7afdb)one range scan, 11 times faster on 400 place pages
Settings file read on every page (comment on ask_enabled, commit 1757f1fb9d)about 30 s on motdang-build, read once per process
Writing about 180,000 place files (commit 0703a1a472)444 of 1,687 s on 2026-10-11

การสร้างและ docs.next · The build and the docs.next swap

build.py writes the site into docs.next/ and renames it over docs/ at the end (_swap_into_place()). Two renames, each atomic on APFS; docs.prev/ is deleted after the swap. A build killed halfway leaves the previous whole docs/ where the publisher looks. This came after 2026-09-08, when a half-written docs/ was published (see Incidents).

The build holds a second copy of the site beside the first until the swap. On 2026-10-05 docs/ was 10.4 GB in 271,090 files, and a build died with Errno 28 after the disk reached 213 MB free. check_room() now measures the last docs/ with du and refuses to start when free space is under that size plus 5 GB. The swap itself needs about 8 GB spare for the minute both trees exist.

cache/build.lock holds the builder's pid. A second build refuses and names the holder; a lock whose process is gone is announced and taken. A build into a different output folder takes no lock, and the tests read MD_DOCS, which is how they run while another build holds docs/.

Same inputs should give the same bytes. PYTHONHASHSEED=0 is set in the publish steps, because an event with no uid took its calendar UID from a salted hash(). On 2026-10-10 a round three hours after the last changed 79,500 files, and 1,000 sampled place pages differed only in the weather and air line. That line is now filled in by md.js from data/nownear.json.

The sitemap dates each page by a fingerprint of its content: 97,113 pages changed in the 2026-10-10 build and 1,572 kept an earlier date.

ด่านตรวจ · Gates

importers/publish_steps.sh is sourced by both walks, so the Mac and the server pass the same gates. A hard gate stops the publish and writes failed to the ledger. An advisory gate prints a line and the publish goes on.

ด่าน · Gateตรวจอะไร · Checks
hard: build.pyexit status, within 180 minutes on the Mac and 360 on the server
hard: test_publish_gate.pyno link to a URL check_links.py found dead; no local paths in the pages; a front page and the furniture it needs; the right domain; every site under docs/ has a card in the register
hard: test_asked.pya published reader question has its records, page, card and a filled reply
hard: test_sites.pythe site register
hard: test_map_sanity.pyno swapped or out-of-country pin, none off its frame or province; a ratchet, so rows known when it was added are listed and a new one fails
hard: test_shelflife.pya perishable figure past its age is not drawn
hard: route and front-page tests (node)test_plan_routes.js, test_front_calendar.js, test_soi_run.js
hard: path leak and floorgrep over docs/ for local filesystem paths; at least 20,000 files
hard, server onlythe live bucket is listed and compared; more than 500 live files missing from the build stops the publish
advisoryshelf cards, tags, pins, copy assurances (test_no_assurances.py), llms.txt counts, the front clock, the calendar bands

157 test files sit in tests/. test_search.py runs the shipped JavaScript matcher under node over the page's own pipeline. test_ground.py reads one column down a rendered map frame and expects it to cross the moat's water exactly twice.

การเผยแพร่ · Publish: R2 and the Worker

The site once deployed through Cloudflare Pages from a git host. Pages caps a project at 20,000 files and docs/ was 27,577 at the move. R2 has no object cap, and the 116 MB basemap archive lives in the same bucket.

publish/deploy.py wraps rclone sync, which makes the bucket match docs/ and deletes what docs/ lacks. It runs as a dry run unless given --yes, and takes the build lock so it cannot sync a tree a build is writing. publish/safety.py carries the checks that came out of the 2026-09-08 outage: a required-path set, per-subtree floors, a deletion preview built by listing both sides, a ceiling of 2,000 live objects deleted in one run, a list of prefixes never pruned (vendor/, glyphs/, api/), and a smoke test that asks the live origin a list of questions after the upload. --only and --files publish part of the tree. A live file uploaded after the hand-off began is kept, since the build could not know it.

publish/worker.js serves the bucket. .html is served directly and the extensionless path resolves to the same object, so the common path has no redirect; some folder indexes still redirect. Range requests pass through to R2, which is all a PMTiles archive needs, and tiles carry max-age=31536000, immutable. Every response carries Access-Control-Allow-Origin: *. /api/v1/* is answered from a baked index.json, checked against the bucket by an etag request every 60 seconds (OpenAPI 3.1.0, 8 paths on 2026-10-10).

The Worker writes an Analytics Engine row for a page request: referrer host, the landing path with the query dropped, and a category derived from the User-Agent. Blob position is the schema, and test_edge_count.mjs fails when the order drifts from the collector it shares a dataset with.

The claims Worker (worker/worker.js, KV) takes claims, toilet reports, thumbs and notes (/feedback), suggestions (/suggest), listing forms and tester reports. Rate limits per address per hour: 12 suggestions, 120 feedback events, 12 notes. A suggestion queue and the notes have no public GET. Importers read them with an authenticated call into _incoming/, which is gitignored.

Backups are git bundle files of every repo, written by importers/offsite_backup.py to a separate bucket, the last three kept per repo. A backup written into the site bucket is deleted by the next deploy, which is how the first one was lost.

แผนที่พื้นฐาน · Map basemap

Maps are MapLibre GL JS v5.24.0 over PMTiles (v3), a single-file tile archive read with HTTP range requests, with both the library and the archive served from the site's own origin. The archives came from a Protomaps planet build dated 2026-08-11 through pmtiles extract.

ไฟล์ · Archiveขนาด · Size
cm-cr.pmtiles, both provinces, z0 to z15121,494,891 bytes (extracted 2026-08-12)
north.pmtiles, the 17 northern provinces, z0 to z15244,404,745 bytes (2026-10-03)
cm-cr-terrain.pmtiles, elevation as terrarium tiles, z12161,156,720 bytes
label glyphs, Noto Sans (SIL OFL), four ranges: Latin, Latin extended, Thai, general punctuation and currency4 .pbf files

map_shell.py is the one module that configures a map. Each map is drawn first as a Python-made SVG, which is what prints, what shows with scripting off and what shows while tiles arrive; MapLibre mounts over it in the same box. data/basemap.json with no url switches the tile layer off and leaves the SVG. The OpenStreetMap credit is configured visible on every map surface, as the ODbL asks.

map_ground.py reads the same archive in stdlib Python (PMTiles v3 and MVT) to paint ground under share cards, plan GIFs and posters that Pillow draws. It returns geometry in longitude and latitude for the caller's own projection, draws roads in metres with a pixel floor, and treats polygon holes as holes, so the moat stays a ring. The credit is drawn into the pixels because a GIF travels without its page.

เหตุขัดข้อง · Incidents

วันที่ · Dateเหตุ · What happened
2026-09-08A deploy mirrored a docs/ holding only cm/ and data/ onto the bucket. rclone sync deleted the front page, 404.html, both vendored libraries, the glyphs, all of cr/ and the API index, and motdang.net answered 404 for its own front page. The 20,000-file floor passed, since cm/ alone is 77,107 files. Result: safety.py, which asks whether a tree is the site and not whether it is large. Two days later, the docs.next swap.
2026-10-05A build died with Errno 28 after the disk reached 213 MB free, and took other processes on the machine down with it. Result: check_room().
2026-09-20 to 2026-10-05Half-edited code in the working tree failed 58 builds and gates. Result: the last-good-code rebuild (removed 2026-10-11, 0 publishes in 14), then builds from a commit.
2026-10-05 to 2026-10-10No server build finished. A sampler injected into a running build found about 90% of the time in one function. Result: one shared read, a 360-minute limit, a live-file check against the bucket instead of the laptop's docs/, and build.py must import before a hand-off is sent.
2026-10-10A stalled copy-back of the server's docs/ to the Mac blocked a round and held a lock. Result: a 300-second idle timeout on every transfer, then removal of the copy-back.

ค้างอยู่ · Open items

  • The /find reload crawls a local docs/. Builds now run on the server.
  • D1 coordinates: 3,705 of an intended 76,847 rows carried a pin on 2026-09-21, after a D1 import returned 502 and locked the database for 25 minutes. Distance works where a row has one.
  • The index shipped to the browser grows with the catalogue. The API is the alternative, and it costs offline-first.
บอกต่อ · Share
LINEWhatsAppTelegram

ร้อยไว้ในตาข่ายเดียวกัน · Strung in the same net

ตาข่ายมดแดง — เว็บทั้งหมดบน motdang.net · The Mot Dang net — the sites of motdang.net ta-khai mot daeng

แต่ละเว็บในมดแดงเป็นอัญมณีเม็ดหนึ่งในตาข่าย เปิดหน้าไหนข้างล่างนี้ ก็เห็นที่อื่นทั้งหมด รวมทั้งไฟล์สำหรับบอทและตาข่ายของสถานที่ · Each site on Mot Dang is one jewel in the net. Open any page below and it shows all the others, with the files written for bots and the nets of places.

บ้าน · Home (12)
  • ประกาศขาย-เช่า · The Listing Sheetอะไรขาย อะไรให้เช่า ราคาเท่าไร วันไหน และทะเบียนตึกทั้งหมด · what is for sale and for rent, at what price, on what date
  • หลังคาเมืองเหนือ · Roofs of the Northบ้าน คอนโด หอพัก ทะเบียนตึก ราคาประเมิน ตัวแทน สำนักงานที่ดิน · houses, condos and dorms: the building register, assessed prices, agents, land offices
  • กระดานงานบ้าน · Home-help boardคนทำงานลงชื่อเอง ติดต่อกับเขาได้โดยตรง · workers list themselves; you contact them directly
  • หลายมือ · Many Handsแม่บ้าน คนสวน ซักรีดรับส่ง ช่างซ่อม ลงชื่อเอง ติดต่อตรง · housekeepers, gardeners, laundries and handymen who list themselves
  • ย้ายบ้านข้ามทะเล · The Whole House, by Seaส่งของใช้จากอเมริกามาไทยแบบรวมตู้ ราคา เครื่องคิดค่าส่ง ขั้นตอน · shipping a household from the US to Thailand: prices, a calculator, the steps
  • ดรอปชิป วาดให้ดู · Dropshipping, Drawnขายของออนไลน์จากไทย ให้ผู้ขายส่งส่งของถึงลูกค้า: eBay โรงงานข้ามทะเล ของไทยส่งออก เงิน การรอ ด่านภาษี งูกับบันไดของมือใหม่ · selling online from Thailand while the supplier ships: eBay, a factory abroad, Thai goods out; the money, the wait, the borders, a snakes-and-ladders of rookie mistakes
  • อยู่ยาว · The Long Stayทุกทางที่อยู่เมืองไทยได้ วาดเป็นภาพ ยกเว้นวีซ่า 30 วัน DTV เกษียณ ประตูสี่บานของ LTR พริวิเลจหกแสนห้าถึงห้าล้าน ถิ่นที่อยู่ถาวร · every way to stay in Thailand, drawn: the 30-day stamp, DTV, retirement, the LTR's four doors, Privilege from ฿650,000 to ฿5 million, permanent residence
  • ปั๊ม กรอง ท่อ · Pump, Filter, Drainปั๊มติดเอง น้ำอ่อน น้ำมีสีเหลือง ท่อตัน กลิ่นจากท่อ อาการ ราคา และประโยคคุยกับช่าง · a pump that starts by itself, weak or yellow water, slow drains, a smell: causes, prices, and Thai for the plumber
  • มูลนิธิวอร์มฮาร์ท และโรตารีสากลเชียงใหม่ · Warm Heart Foundation & Rotary Fiscal Sponsorshipสะพานบุญลดหย่อนภาษี 501(c)(3) เพื่อโรตารีเชียงใหม่ ผ้าพันคอย้อมสีธรรมชาติจากฝีมือชาวดอย และการฝึกอบรมไบโอชาร์หยุดเผาเพื่อสิ่งแวดล้อม · US 501(c)(3) fiscal sponsorship for Rotary CMIRC: vegetable-dyed hill tribe hand-woven shawls, and open biochar smoke-reduction trainings in Phrao
  • เวฟที่บ้าน · Wave It at Homeเลขกดบนซองอาหารเซเว่น แปลงเป็นเวลาไมโครเวฟบ้าน ตามวัตต์ของเครื่องคุณ · the code on a 7-Eleven ready meal, turned into a time for your microwave at home
  • อสังหาฯ-ที่พัก · Real estate & places to liveคำที่ใช้ถาม ตึกที่มี และสิ่งที่ยังไม่มีใครถาม · the words to ask, the buildings, and what nobody has asked them
  • ซ่อมของ · Mendersรองเท้า ซิป จักรเย็บผ้า แอร์ โซฟา และมีดที่ทื่อ · shoes, zips, sewing machines, air-conditioners, sofas, and a blunt knife
ไปเที่ยว · Going out (36)
วัด พระจันทร์ วันพระ · Wats, moons, days (18)
  • วันเพ็ญที่วัด · Full Moon at the Watวันเพ็ญทุกเดือนของปี วัดทำอะไร และวัดไหนจัด · every full moon of the year, what happens, and which wats keep it
  • ออกพรรษา และตักบาตรเทโว · Ok Phansa, then Tak Bat Thewoวันเพ็ญเดือนเกี๋ยง 26 ต.ค. พระออกพรรษา เช้าวันรุ่งขึ้นตักบาตรเทโว และวัดไหนจัด · the Kiang Peng full moon, 26 Oct: the rains retreat ends, Tak Bat Thewo the next morning, and which wats keep it
  • ไหว้พระ ๙ วัด · Nine Watsเส้นทางไหว้พระเก้าวัด เดินได้ ตามลำดับ · the wat rounds, walkable, in order
  • เทศกาล · Festivalsลงวันจากประกาศทางการ พร้อมที่มา · dated from official announcements, each with its source
  • ปฏิทิน · The calendarงาน วันพระ และวันสีของสัปดาห์ข้างหน้า · what is on, wan phra and the day colours, weeks ahead
  • ดวง · Horoscopeสีประจำวัน ดาว ปางพระ และเสาจีน · day colour, planet, posture, the Chinese pillar
  • ผีเหนือ ผีไทย · Ghosts, Drawnผีล้านนาและผีไทย ๒๑ ตน วาดเป็นการ์ตูนเคลื่อนไหว แตะเล่นได้ พร้อมนาฬิกาว่าตอนนี้ผีไหนออกมา · 21 Lanna and Thai ghosts as moving cartoons you can play with, and a clock of who is out tonight
  • โคมลอย วาดด้วยคณิต · Khom Loi, Drawnโคมลอยยี่เป็งวาดด้วยฟิสิกส์ของอากาศร้อน ทำไมลอย หนึ่งเที่ยวบินตั้งแต่จุดไฟจนตก ลมพาโคมสี่สิบดวงไปตกที่ไหนในเชียงใหม่ และบนฟ้ามีกี่ดวงพร้อมกัน · the Yi Peng sky lantern drawn with the physics of hot air: why it rises, one flight from lighting to landing, where the wind brings forty lanterns down over Chiang Mai, how many are up at once
  • กินเจ เทศกาลอาหารเจ · Kin Jay, the Vegetarian Festivalเก้าวันกินเจ 2569 ธงเหลืองตัว 齋 อะไรกินได้ อะไรต้องงด เมนูเจ ศาลเจ้า โรงเจ และร้านเจในเชียงใหม่และเชียงราย กลุ่มคนกินเจและมังสวิรัติในไทย และตำนานเก้าองค์ดาวเหนือ · the nine days of jay in 2026: the yellow 齋 flag, what stays off the plate, the menu, the shrines, halls and jay kitchens of Chiang Mai and Chiang Rai, Thailand's vegetarian groups, and the legends
  • กนก วาดด้วยคณิต · Kranok, Drawnกระหนก เปลวไฟแห่งลายไทย วาดด้วยคณิต ตัวเหงา กนกสามตัว ลายก้านขด ลายหน้ากระดานเจ็ดแบบ ลายรดน้ำ และลายคำล้านนา · kranok, the flame of Thai ornament, drawn with math: the snail-shell curl, the three-figure kranok, the coiled-stem scroll, seven border bands, gold on black lacquer and Lanna lai kham
  • กระทง วาดด้วยคณิต · Krathong, Drawnกระทงวาดด้วยคณิต พับกลีบใบตอง กลีบเรียงเป็นวง ทำไมลอยน้ำได้และไม่คว่ำ แม่น้ำปิงพากระทงไปไหน และเช้าวันรุ่งขึ้นเก็บได้กี่ใบ · the Loy Krathong float drawn with math: folding a banana-leaf petal, rings of petals, why it floats and stays upright, where the Ping carries it, and the count the morning after
  • ช่างล้านนา · Lanna Craftวิหาร นาค ป้านลม เจดีย์ ตุง ลายคำ สัตตภัณฑ์ วาดด้วยคณิต พร้อมตำนาน ประวัติ และคำศัพท์มีภาพ · Lanna temple building, ornament and devotional art drawn with math: viharns, nagas, barge boards, chedis, tung, lai kham, sattaphan, with legends, history and an illustrated word list
  • คู่มือศาลพระภูมิ · The Spirit House Manualวิธีดูแลศาลพระภูมิ แบบศาล ส่วนต่าง ๆ ถาดของไหว้ตอนเช้า ใครกินอะไร น้ำแดง ม้าลาย บน ที่ตั้งตามแดด และถอนศาล · how to keep a spirit house: the models, the parts, the morning tray, who eats what, red drinks, zebras, vows, placement by the sun, and retirement
  • งานในเมือง · What is on
  • วันเทศกาลปี 2569–2570 · Festival dates 2026–2027
  • ดวงจีนสี่เสา · Your Four Pillars
  • ศาล-ศาลเจ้า-หลักเมือง · Shrines & city pillars
  • ชื่อวัดบอกภูมิประเทศ · A wat’s name tells the landscape
ร่างกายและสุขภาพ · Body and health (28)
ทุกวัน · Every day (23)
เว็บของร้าน · A business's own site (2)
บอท · Bots (5)
เบื้องหลัง · Behind the site (22)
สำหรับบอท · For bots sam-rap bot (13)
  • llms.txtเว็บนี้แนะนำตัวกับโมเดลภาษา · the site introduced to language models
  • llms-full.txtฉบับเต็ม · the long version
  • net.jsonตาข่ายนี้เป็น JSON · this net, as JSON
  • audit.jsonตัวเลขที่เว็บพิมพ์ นับใหม่จากไฟล์ต้นทางทุกครั้งที่สร้าง · each published number re-counted from its source file at build
  • colophon.jsonโคโลฟอนเป็น JSON · the colophon, as JSON
  • API v1ถามข้อมูลได้โดยไม่ต้องมีคีย์ · the data, asked without a key
  • graph.jsonldกราฟความรู้ JSON-LD · the knowledge graph, JSON-LD
  • sites.jsonทะเบียนเว็บเป็น JSON · the register of sites, as JSON
  • sitemap.xmlแผนผังเว็บ · the sitemap
  • rss.xmlฟีดของใหม่ · the feed of what is new
  • robots.txtป้ายหน้าประตูสำหรับบอท · the sign on the door for bots
  • security.txtแจ้งช่องโหว่ที่ไหน (RFC 9116) · where to report a security bug (RFC 9116)
  • รังมด skill.md · Anthill skill.mdบอทเข้ารังมดอย่างไร · how a bot joins the Anthill
ตาข่ายของสถานที่ · Nets of places ta-khai khong sa-than-thi (25)
เพื่อนบ้าน — เว็บของคนอื่น · Neighbours — other people's sites phuean-baan (1)

net.json · ทำไมเป็นตาข่าย — Indra's Net, Drawn (ภาษาอังกฤษ) · Why a net — Indra's Net, Drawn