aboutsummaryrefslogtreecommitdiffstats
path: root/names/vendor/translate-split.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-16 16:33:53 -0700
committerAdam Soltys <[email protected]>2026-10-16 16:33:53 -0700
commit13da0eda3b972eafb3962960165f73181497b7e5 (patch)
treee12eb5732ed05dc32794a82ab5ed1309c6ecb0a3 /names/vendor/translate-split.js
parent35c974e4255006ae0a99f6f900a373613af35fd0 (diff)
downloadcoinosv3-server-13da0eda3b972eafb3962960165f73181497b7e5.tar.gz
coinosv3-server-13da0eda3b972eafb3962960165f73181497b7e5.zip
coinosv3 → 73bffd9: the services run the wallet's current Ark code; names/vendor/ goes.
The pin had stayed at 082fc2e (Sep 14) while the app's Ark manager moved on — renewals priced at a 300-sat base fee and re-priced on "insufficient refresh fee", expiry-aware coin selection, standing (scheduled) renewals merged by unlock hash, policy-aware freeing of in-flight coins — so the registrar's forwarder float was a month behind the wallets it forwards to. The manager's constructor, the methods the services call (balance, sync, refresh, send, address, createLnInvoice, driveLn, startBoard, pendingActions, htlcClaim, htlcCosignRefund, _key) and the storage contract (load → state or null, save ← state) are unchanged between the two commits, and nothing new is imported from a package the server lacks. names/translate.js imports translate-split.js from the submodule now, as feed/cache.js already did lang-guess.js: the vendored copies were byte-equal to what the pin now carries. The README's note about them goes with them. Resolve-checked every service entry (bun build --target=bun); the moved tests (registry-ownership, public-feed-cache) and the bun-test files (deepl-translate, names/store) pass. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
Diffstat (limited to 'names/vendor/translate-split.js')
-rw-r--r--names/vendor/translate-split.js61
1 files changed, 0 insertions, 61 deletions
diff --git a/names/vendor/translate-split.js b/names/vendor/translate-split.js
deleted file mode 100644
index 95f6468..0000000
--- a/names/vendor/translate-split.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// What must come back from a translation exactly as it went in: links,
-// nostr: mentions, custom emoji shortcodes, hashtags, @handles, invoices and
-// other long codes. Translation models mangle them ("https: / / example.com
-// / fot.jpg"), so only the prose between them is translated and the text is
-// put back together around the untouched tokens. Shared by the registrar
-// (names/translate.js) and the browser's own translator (messages.js).
-import { scriptOf, LANG_SCRIPT } from './lang-guess.js';
-
-const KEEP = /(https?:\/\/\S+|nostr:[a-z0-9]+|:[a-z0-9_+-]{1,40}:|#[\p{L}\p{N}_]+|@[\w.-]+(?:@[\w.-]+)?|\b(?:ln|lightning:|cashu|bitcoin:|nevent|npub|nprofile|note|naddr)[a-z0-9]{20,}|\S{40,})/giu;
-
-export function splitProse(text) {
- const parts = [];
- let last = 0;
- for (const m of String(text || '').matchAll(KEEP)) {
- if (m.index > last) parts.push({ prose: text.slice(last, m.index) });
- parts.push({ keep: m[0] });
- last = m.index + m[0].length;
- }
- if (last < text.length) parts.push({ prose: text.slice(last) });
- return parts;
-}
-// a piece worth translating: has words, not just spaces and punctuation
-export const hasWords = (s) => /\p{L}{2,}/u.test(s || '');
-
-// A hashtag stays a hashtag (it's a link to its topic), but one written in
-// another script than the reader's means nothing to them: such a tag gets
-// its translation in brackets after it, "#総合部絵チャ (general art chat)".
-const tagWords = (tag) => tag.slice(1).replace(/_/g, ' ');
-export function glossable(tag, target) {
- if (!tag.startsWith('#') || !target) return false;
- const s = scriptOf(tagWords(tag), 1);
- return !!s && !!LANG_SCRIPT[target] && s !== LANG_SCRIPT[target];
-}
-// What a translator gets to see of a post: its prose, then the words of the
-// hashtags the reader can't read (also what language detection runs on).
-export function translatable(text, target) {
- const parts = splitProse(text);
- return {
- parts,
- prose: parts.filter((p) => p.prose && hasWords(p.prose)),
- tags: parts.filter((p) => p.keep && glossable(p.keep, target)),
- };
-}
-
-// Translate the prose pieces and the glossed tags (one call for all of them)
-// and reassemble. Each piece keeps its own leading/trailing whitespace —
-// line breaks matter.
-export async function translatePieces(text, translateMany, target = null) {
- const { parts, prose, tags } = translatable(text, target);
- if (!prose.length && !tags.length) return text;
- const outs = await translateMany([...prose.map((p) => p.prose.trim()), ...tags.map((p) => tagWords(p.keep))]);
- prose.forEach((p, i) => {
- const lead = p.prose.match(/^\s*/)[0], trail = p.prose.match(/\s*$/)[0];
- p.out = lead + String(outs[i] ?? p.prose.trim()) + trail;
- });
- tags.forEach((p, i) => {
- const g = String(outs[prose.length + i] ?? '').trim();
- p.out = g && g.toLowerCase() !== tagWords(p.keep).toLowerCase() ? p.keep + ' (' + g + ')' : p.keep;
- });
- return parts.map((p) => p.out ?? p.keep ?? p.prose).join('');
-}