How this page works
This page deliberately does NOT go through the CDN.
Architecture
Measurement logic is isolated from how it is measured. One planner builds the list of probes from a single config file; two adapters execute it - PHP/curl on the origin, fetch() in your browser. A third adapter measuring from outside Vietnam can be added without touching that logic.
Single source of truth
Targets, payloads and passes are declared once in config/lab.json. Both adapters read the same list, so the two columns can never measure different things.
Self-hosted libraries, pinned
Every library is served from this origin under asset/<name>-<version>/. A library loaded from a public CDN would not pass through Fastly, and this page is the measuring instrument - it must not add its own noise to the number it reports.
Pinned libraries
bootstrap 5.3.3
jquery 3.7.1
datatables 2.1.8
datatables-buttons 3.1.2
datatables-responsive 3.0.3
chartjs 4.5.1
luxon 3.5.0
i18next 23.16.8
bootstrap-icons 1.11.3
Ports & adapters
config/lab.json <-- single source of truth
|
v
measurement_plan() (domain - no I/O)
| produces probe[] + probe_id
v
+---- ProbePort ----+ (the hexagon's edge)
| |
curl on origin fetch in browser
PHP (Vietnam) (wherever you are)
| |
+---> MeasurementRun <---+
|
POST to measure.php
|
v
PHP session store
|
+-----------+-----------+
| | | | |
table chart history headers (all rendered by PHP)