diff --git a/README.md b/README.md index 603023c..11c251c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,20 @@ +

+ Row-Template +

+ # Row-Template Docs -The documentation site for [Row-Template](https://github.com/iitzSeriZdev/Row-Template), the self-contained, white-label subscription page for 3X-UI panels. +The documentation site for [Row-Template](https://github.com/iitzSeriZdev/Row-Template), the self-contained, white-label subscription page for 3X-UI, PasarGuard and Rebecca panels. **→ [iitzseridev.github.io/Web-Row-Template](https://iitzseridev.github.io/Web-Row-Template/)** · [فارسی](https://iitzseridev.github.io/Web-Row-Template/fa/) -- **Installation** with the one-command installer, and a step-by-step manual install that also works on servers without GitHub access. +- **Installation** on 3X-UI, PasarGuard and Rebecca with the one-command installer, and a step-by-step manual install that also works on servers without GitHub access. - **Every template** with a live, interactive preview: phone and desktop sizes, all five languages, light and dark. -- **An error reference** covering every error and warning the installer can print, with what it means and how to fix it, translated into Persian. +- **An error reference** covering every error and warning the installer can print — including the panel adapters and the activation transaction engine — with what it means and how to fix it, translated into Persian. - **Management**: the `row-template` command, the interactive manager, updating, backups and rollback, verify, uninstall. - **English and Persian**, right-to-left, with full-text search in both. -Everything is written against the Row-Template 1.2.0 source: commands, paths and messages are exactly what the installer prints. +Everything is written against the Row-Template 1.3.0 source: commands, paths and messages are exactly what the installer prints. ## Development @@ -33,7 +37,9 @@ Search needs the Pagefind index, so it works after `npm run build` (in `preview` | `src/content/docs/en/`, `src/content/docs/fa/` | The pages, as MDX — one file per page and language, at the same path | | `src/data/errors.ts` | The error reference: every installer message, its translation, meaning and fix | | `src/data/templates.json`, `public/previews/`, `public/live/` | Synced from Row-Template — never edited here | -| `src/data/installer-messages.json` | Every error and warning in the installer source, extracted by the sync script | +| `public/branding/` | The official Row-Template logo: the symbol (navigation bar), the square logo (landing page, social image) and the app icon (favicon). Copies and downscaled derivatives of the canonical logo files — never redrawn or recoloured | +| `public/flags/` | The language switch: the United States flag for English, the Lion and Sun flag for Persian | +| `src/data/installer-messages.json` | Every error and warning in the installer source — the bootstrap, the library, the command and every companion the library declares — extracted by the sync script | | `src/components/`, `src/layouts/` | The UI, modelled on the shadcn/ui documentation | | `src/lib/nav.ts` | The sidebar, in reading order | | `src/styles/globals.css` | The design system: shadcn/ui's neutral palette, Geist and Vazirmatn, logical properties for RTL | diff --git a/public/branding/row-template-app-icon-180.png b/public/branding/row-template-app-icon-180.png new file mode 100644 index 0000000..538f32b Binary files /dev/null and b/public/branding/row-template-app-icon-180.png differ diff --git a/public/branding/row-template-app-icon-32.png b/public/branding/row-template-app-icon-32.png new file mode 100644 index 0000000..88e36e8 Binary files /dev/null and b/public/branding/row-template-app-icon-32.png differ diff --git a/public/branding/row-template-logo.png b/public/branding/row-template-logo.png new file mode 100644 index 0000000..36d2947 Binary files /dev/null and b/public/branding/row-template-logo.png differ diff --git a/public/branding/row-template-logo.webp b/public/branding/row-template-logo.webp new file mode 100644 index 0000000..6852860 Binary files /dev/null and b/public/branding/row-template-logo.webp differ diff --git a/public/branding/row-template-mark.png b/public/branding/row-template-mark.png new file mode 100644 index 0000000..2ef4fd5 Binary files /dev/null and b/public/branding/row-template-mark.png differ diff --git a/public/branding/row-template-social.png b/public/branding/row-template-social.png new file mode 100644 index 0000000..cabc433 Binary files /dev/null and b/public/branding/row-template-social.png differ diff --git a/public/favicon.svg b/public/favicon.svg deleted file mode 100644 index 22070e3..0000000 --- a/public/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/public/flags/flag-en-us.svg b/public/flags/flag-en-us.svg new file mode 100644 index 0000000..238ff5d --- /dev/null +++ b/public/flags/flag-en-us.svg @@ -0,0 +1 @@ + diff --git a/public/flags/flag-fa-lion-and-sun.png b/public/flags/flag-fa-lion-and-sun.png new file mode 100644 index 0000000..13961ce Binary files /dev/null and b/public/flags/flag-fa-lion-and-sun.png differ diff --git a/public/live/arcade/index.html b/public/live/arcade/index.html index 05f7ae9..3620ebe 100644 --- a/public/live/arcade/index.html +++ b/public/live/arcade/index.html @@ -1378,8 +1378,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172384" - data-last-online="1790284294514" + data-expire="1794346416" + data-last-online="1790458326502" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/arcadenova/index.html b/public/live/arcadenova/index.html index bf5576c..f3c27f8 100644 --- a/public/live/arcadenova/index.html +++ b/public/live/arcadenova/index.html @@ -1399,8 +1399,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172387" - data-last-online="1790284297540" + data-expire="1794346418" + data-last-online="1790458328183" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/brutal/index.html b/public/live/brutal/index.html index 015dc0e..81fdf7c 100644 --- a/public/live/brutal/index.html +++ b/public/live/brutal/index.html @@ -1369,8 +1369,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172384" - data-last-online="1790284294054" + data-expire="1794346416" + data-last-online="1790458326263" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/canvas/index.html b/public/live/canvas/index.html index d51fcda..c2443b4 100644 --- a/public/live/canvas/index.html +++ b/public/live/canvas/index.html @@ -1425,8 +1425,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172382" - data-last-online="1790284292295" + data-expire="1794346415" + data-last-online="1790458325297" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/editorial/index.html b/public/live/editorial/index.html index 69edc95..9669821 100644 --- a/public/live/editorial/index.html +++ b/public/live/editorial/index.html @@ -1451,8 +1451,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172381" - data-last-online="1790284291926" + data-expire="1794346415" + data-last-online="1790458325048" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/meter/index.html b/public/live/meter/index.html new file mode 100644 index 0000000..0ce91eb --- /dev/null +++ b/public/live/meter/index.html @@ -0,0 +1,4837 @@ + + + + + + + + + +Aurora + + + + + + + + + + + + + +
+ +
+
+
+ +

+
+
+ + Enabled + + +
+
+
+ + +
+
+ +
+ +
+
+

Subscription status

+ Aurora +
+

61.60GB remaining

+
+

+ + 38.40GB + used of 100.00GB +

+
+
+
+

—

+

+
+ +
+ +
+ +
+
+ + +
+
+ + +
+
+ +
+

Connect

+
+
+

+
+ +
+ +
+
+

Configurations

+ +
+

+ +
+ + +
+ + +
Contact support
+ +
+
+ +
+ + +
+

QR code

+ +
+
+
+

Scan with your client application

+
+ + +
+
+
+ + + + +
+

+ +
+
+
+

+
+ + +
+ + +
+
+ + + + + diff --git a/public/live/notebook/index.html b/public/live/notebook/index.html new file mode 100644 index 0000000..8266d83 --- /dev/null +++ b/public/live/notebook/index.html @@ -0,0 +1,4825 @@ + + + + + + + + + +Aurora + + + + + + + + + + + + + + + +
+ +
+
+ +

+
+
+ + +
+
+ +
+ +
+

Enabled

+

+ + Aurora +

+
+ +
+ + +
+ +
+ +

Subscription status

+
+

38.40GB

+

used of 100.00GB

+
+
+

61.60GB remaining

+
+ +
+ +
+ +
+

—

+

+
+
+ +
+ +
+ +

Connect

+
+
+

+
+ +
+ +
+

Configurations

+ +
+

+ +
+ + +
+ + +
Contact support
+ +
+
+ +
+ + +
+

QR code

+ +
+
+
+

Scan with your client application

+
+ + +
+
+
+ + + + +
+

+ +
+
+
+

+
+ + +
+ + +
+
+ + + + + diff --git a/public/live/prism/index.html b/public/live/prism/index.html index 9d1ea48..2ca9d30 100644 --- a/public/live/prism/index.html +++ b/public/live/prism/index.html @@ -1335,8 +1335,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172382" - data-last-online="1790284292712" + data-expire="1794346415" + data-last-online="1790458325540" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/prismnova/index.html b/public/live/prismnova/index.html index 2324c08..1a57426 100644 --- a/public/live/prismnova/index.html +++ b/public/live/prismnova/index.html @@ -1378,8 +1378,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172386" - data-last-online="1790284296664" + data-expire="1794346417" + data-last-online="1790458327701" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/pulse/index.html b/public/live/pulse/index.html index 2b9fa1a..e694f3a 100644 --- a/public/live/pulse/index.html +++ b/public/live/pulse/index.html @@ -1328,8 +1328,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172383" - data-last-online="1790284293595" + data-expire="1794346416" + data-last-online="1790458326018" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/pulsenova/index.html b/public/live/pulsenova/index.html index 2a750dd..f01904a 100644 --- a/public/live/pulsenova/index.html +++ b/public/live/pulsenova/index.html @@ -1467,8 +1467,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172386" - data-last-online="1790284296196" + data-expire="1794346417" + data-last-online="1790458327464" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/row/index.html b/public/live/row/index.html index 6019e49..a76ff7d 100644 --- a/public/live/row/index.html +++ b/public/live/row/index.html @@ -1290,8 +1290,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172381" - data-last-online="1790284291552" + data-expire="1794346414" + data-last-online="1790458324800" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/saffron/index.html b/public/live/saffron/index.html index e084beb..857b25f 100644 --- a/public/live/saffron/index.html +++ b/public/live/saffron/index.html @@ -1441,8 +1441,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172385" - data-last-online="1790284295780" + data-expire="1794346417" + data-last-online="1790458327224" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/signature/index.html b/public/live/signature/index.html index 1902fbe..dbae3fa 100644 --- a/public/live/signature/index.html +++ b/public/live/signature/index.html @@ -1488,8 +1488,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172385" - data-last-online="1790284295358" + data-expire="1794346416" + data-last-online="1790458326983" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/sketch/index.html b/public/live/sketch/index.html index c5c9eff..4d40d53 100644 --- a/public/live/sketch/index.html +++ b/public/live/sketch/index.html @@ -1317,8 +1317,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172384" - data-last-online="1790284294917" + data-expire="1794346416" + data-last-online="1790458326738" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/terminal/index.html b/public/live/terminal/index.html index 5bd7897..48ff8b7 100644 --- a/public/live/terminal/index.html +++ b/public/live/terminal/index.html @@ -1230,8 +1230,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172383" - data-last-online="1790284293164" + data-expire="1794346415" + data-last-online="1790458325780" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/live/terminalnova/index.html b/public/live/terminalnova/index.html index 6305d27..b74da3a 100644 --- a/public/live/terminalnova/index.html +++ b/public/live/terminalnova/index.html @@ -1388,8 +1388,8 @@ data-download-byte="34359738368" data-upload-byte="6871947674" data-total-byte="107374182400" - data-expire="1794172387" - data-last-online="1790284297111" + data-expire="1794346417" + data-last-online="1790458327938" data-sub-url="https://sub.example.com/sub/e3b0c44298fc1c14" data-sub-json-url="https://sub.example.com/json/e3b0c44298fc1c14" data-sub-clash-url="https://sub.example.com/clash/e3b0c44298fc1c14" diff --git a/public/previews/meter-desktop.webp b/public/previews/meter-desktop.webp new file mode 100644 index 0000000..da064ea Binary files /dev/null and b/public/previews/meter-desktop.webp differ diff --git a/public/previews/meter-mobile.webp b/public/previews/meter-mobile.webp new file mode 100644 index 0000000..5e96b9c Binary files /dev/null and b/public/previews/meter-mobile.webp differ diff --git a/public/previews/notebook-desktop.webp b/public/previews/notebook-desktop.webp new file mode 100644 index 0000000..beb783d Binary files /dev/null and b/public/previews/notebook-desktop.webp differ diff --git a/public/previews/notebook-mobile.webp b/public/previews/notebook-mobile.webp new file mode 100644 index 0000000..5af599c Binary files /dev/null and b/public/previews/notebook-mobile.webp differ diff --git a/scripts/check-site.mjs b/scripts/check-site.mjs index f3a7c60..e75673e 100644 --- a/scripts/check-site.mjs +++ b/scripts/check-site.mjs @@ -11,14 +11,15 @@ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs"; import { dirname, join, relative, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; +import { fileURLToPath, pathToFileURL } from "node:url"; const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const BASE = "/Web-Row-Template"; const problems = []; const fail = (msg) => problems.push(msg); -const { ENTRIES } = await import(join(ROOT, "src/data/errors.ts")); +// A file URL, not a bare path: on Windows import() reads "D:" as a URL scheme. +const { ENTRIES } = await import(pathToFileURL(join(ROOT, "src/data/errors.ts")).href); const messages = JSON.parse(readFileSync(join(ROOT, "src/data/installer-messages.json"), "utf8")).messages; const catalogue = JSON.parse(readFileSync(join(ROOT, "src/data/templates.json"), "utf8")); diff --git a/scripts/sync-from-row-template.mjs b/scripts/sync-from-row-template.mjs index 73b4f23..cb9298d 100644 --- a/scripts/sync-from-row-template.mjs +++ b/scripts/sync-from-row-template.mjs @@ -16,8 +16,17 @@ // it comes from, in src/data/installer-messages.json. scripts/check-site.mjs // compares the error reference against that list, so a message added to or // removed from the installer shows up as a failing check here. +// +// The messages come from the bootstrap, the management library, the command +// launcher, and every companion the library declares (RT_INSTALLER_COMPANIONS: +// the transaction engine and the panel adapters). Each message is read as the +// bash double-quoted string it is, so a command substitution with quotes of its +// own -- $(rt_panel_label "$panel") -- is read whole. Command substitutions are +// then recorded as named placeholders (SUBST below), because what they print +// changes from run to run just like a variable does; one this script does not +// know stops the sync, so a new one is named deliberately. -import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs"; +import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; @@ -32,7 +41,7 @@ function need(path) { return path; } -need(join(SRC, "installer", "lib", "row-template.sh")); +const LIB = need(join(SRC, "installer", "lib", "row-template.sh")); // 1. the catalogue const catalogue = need(join(SRC, "docs", "src", "data", "templates.json")); @@ -57,26 +66,110 @@ for (const id of ids) { } // 4. installer messages -const FILES = ["installer/install.sh", "installer/lib/row-template.sh", "installer/bin/row-template"]; -const CALL = /\b(b_die|b_err|rt_die|rt_err|rt_warn|rt_ui_warn|rt_ui_error)\s+"((?:[^"\\]|\\.)*)"/g; +const declared = readFileSync(LIB, "utf8").match(/^RT_INSTALLER_COMPANIONS="(.*)"$/m); +if (!declared) { + console.error("sync: the management library declares no RT_INSTALLER_COMPANIONS"); + process.exit(1); +} +const FILES = [ + "installer/install.sh", + "installer/lib/row-template.sh", + "installer/bin/row-template", + ...declared[1].trim().split(/\s+/).map((rel) => `installer/${rel}`), +]; +const CALL = /\b(b_die|b_err|rt_die|rt_err|rt_warn|rt_ui_warn|rt_ui_error)\s+(?=")/g; // The CLI launcher prints two lines of its own before the library is loaded. const RAW = /printf '(row-template: [^'\\]*)(?:\\n)?'/g; -// Groundwork no 1.2.0 command reaches (format-2 backups), and the printing -// helpers themselves. -const SKIP = new Set([ - "rt_backup_create_v2", "rt_backup_panel_write", "rt_backup_manifest_write", "rt_backup_format", - "rt_ui_success", "rt_section", -]); +// The printing helpers themselves. +const SKIP = new Set(["rt_ui_success", "rt_section"]); +// Command substitutions inside messages, and the placeholder each becomes. +const SUBST = [ + [/^\$\(rt_panel_label\b/, "${PANEL}"], + [/^\$\(basename "\$dir"\)$/, "${BACKUP}"], + [/^\$\(printf '%s' "\$found" \| tr '\\n' ' '\)$/, "${PANELS}"], + [/^\$\(rt_panel_rebecca_image\)$/, "${IMAGE}"], + [/^\$\(\(n_avail - n_missing\)\)$/, "${N_PRESENT}"], +]; + +// Read the bash double-quoted string that starts at s[i]; return its source +// text and where it ends, or null when the line does not close it. +function readDq(s, i) { + if (s[i] !== '"') return null; + const paren = (k) => { // k: just after "$(" -- the index after its ")" + let depth = 1; + while (k < s.length && depth > 0) { + const c = s[k]; + if (c === "\\") { k += 2; continue; } + if (c === "'") { const e = s.indexOf("'", k + 1); if (e < 0) return -1; k = e + 1; continue; } + if (c === '"') { const r = readDq(s, k); if (!r) return -1; k = r.end; continue; } + if (c === "(") depth++; + else if (c === ")") depth--; + k++; + } + return depth === 0 ? k : -1; + }; + let j = i + 1; + while (j < s.length) { + const c = s[j]; + if (c === "\\") { j += 2; continue; } + if (c === '"') return { text: s.slice(i + 1, j), end: j + 1 }; + if (c === "$" && s[j + 1] === "(") { const k = paren(j + 2); if (k < 0) return null; j = k; continue; } + if (c === "$" && s[j + 1] === "{") { const k = s.indexOf("}", j + 2); if (k < 0) return null; j = k + 1; continue; } + j++; + } + return null; +} + +// Replace each top-level $( … ) in a message with its placeholder. +function placeholders(text, where) { + let out = ""; + let j = 0; + while (j < text.length) { + if (text[j] === "\\") { out += text.slice(j, j + 2); j += 2; continue; } + if (text[j] === "$" && text[j + 1] === "(") { + let depth = 0, k = j + 1; + for (; k < text.length; k++) { + const c = text[k]; + if (c === "\\") { k++; continue; } + if (c === "'") { k = text.indexOf("'", k + 1); continue; } + if (c === '"') { const q = readDq(text, k); k = q.end - 1; continue; } + if (c === "(") depth++; + else if (c === ")" && --depth === 0) break; + } + const sub = text.slice(j, k + 1); + const hit = SUBST.find(([re]) => re.test(sub)); + if (!hit) { + console.error(`sync: ${where}: no placeholder for ${sub}; add one to SUBST`); + process.exit(1); + } + out += hit[1]; + j = k + 1; + continue; + } + out += text[j++]; + } + return out; +} + const messages = []; for (const file of FILES) { let fn = "(top)"; - readFileSync(join(SRC, file), "utf8").split("\n").forEach((line, i) => { + readFileSync(need(join(SRC, file)), "utf8").split("\n").forEach((line, i) => { const def = line.match(/^([a-z_0-9]+)\(\) \{/); if (def) fn = def[1]; if (/^\s*#/.test(line) || SKIP.has(fn)) return; for (const m of line.matchAll(CALL)) { - if (/^\$\d$/.test(m[2])) continue; // the helpers passing their argument on - messages.push({ file, line: i + 1, fn, level: /die|err|error/.test(m[1]) ? "FAIL" : "warn", text: m[2] }); + const r = readDq(line, m.index + m[0].length); + if (!r) { + console.error(`sync: ${file}:${i + 1}: cannot read the message string`); + process.exit(1); + } + if (/^\$\d$/.test(r.text)) continue; // the helpers passing their argument on + messages.push({ + file, line: i + 1, fn, + level: /die|err|error/.test(m[1]) ? "FAIL" : "warn", + text: placeholders(r.text, `${file}:${i + 1}`), + }); } for (const m of line.matchAll(RAW)) { messages.push({ file, line: i + 1, fn, level: "FAIL", text: m[1].replace(/^row-template: /, "") }); @@ -86,4 +179,4 @@ for (const file of FILES) { writeFileSync(join(ROOT, "src", "data", "installer-messages.json"), JSON.stringify({ source: "Row-Template installer", count: messages.length, messages }, null, 2) + "\n"); -console.log(`sync: ${ids.length} templates, ${ids.length * 2} screenshots, ${ids.length} live pages, ${messages.length} installer messages`); +console.log(`sync: ${ids.length} templates, ${ids.length * 2} screenshots, ${ids.length} live pages, ${messages.length} installer messages from ${FILES.length} files`); diff --git a/src/components/Header.astro b/src/components/Header.astro index 0987389..78ca1ae 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -1,7 +1,7 @@ --- import Icon from "./Icon.astro"; import Sidebar from "./Sidebar.astro"; -import { t, docHref, homeHref, switchLocale, LOCALE_META, type Locale } from "../lib/i18n"; +import { t, docHref, homeHref, switchLocale, withBase, LOCALE_META, type Locale } from "../lib/i18n"; interface Props { locale: Locale; @@ -28,7 +28,7 @@ const repo = "https://github.com/iitzSeriZdev/Row-Template"; {s.toggleMenu} - + Row-Template