diff options
| author | Adam Soltys <[email protected]> | 2026-10-16 16:33:53 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-16 16:33:53 -0700 |
| commit | 13da0eda3b972eafb3962960165f73181497b7e5 (patch) | |
| tree | e12eb5732ed05dc32794a82ab5ed1309c6ecb0a3 /names/vendor/translate-split.js | |
| parent | 35c974e4255006ae0a99f6f900a373613af35fd0 (diff) | |
| download | coinosv3-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.js | 61 |
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(''); -} |
