// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Audit paired language labels // Not compiled or tested in-world // Setup: Add a saved plain-text notecard named Config. Use a unique key followed by two short translations separated by pipes. Touch as owner; reset to scan again. // Stop / restore: Remove or disable. This auditor never changes object settings or inventory. // Notes: Reads at most 40 short lines, skips blanks and # comments, and times out each asynchronous request after 20 seconds. No translation is performed or judged. Pipes inside translations are not supported; checks structural completeness only. // License: see LICENSE in this distribution. // Original Incoprea example. MIT. list keys; key pending=NULL_KEY; integer lineNumber; integer scannedRows; integer issues; integer finished; issue(string text) { ++issues; llOwnerSay("Line "+(string)(lineNumber+1)+": "+text); } requestLine() { pending=llGetNotecardLine("Config",lineNumber); llSetTimerEvent(20); } finish() { pending=NULL_KEY; finished=TRUE; llSetTimerEvent(0); llOwnerSay("Audited rows: "+(string)scannedRows+"; findings: "+(string)issues); } check(string data) { list p=llParseStringKeepNulls(data,["|"],[]); if(llGetListLength(p)!=3) { issue("Expected key|languageA|languageB."); return; } string name=llList2String(p,0); if(name=="" || llStringTrim(llList2String(p,1),STRING_TRIM)=="" || llStringTrim(llList2String(p,2),STRING_TRIM)=="")issue("Missing key or translation."); if(llListFindList(keys,[name])!=-1)issue("Duplicate translation key."); else keys += [name]; } default { touch_start(integer touches) { if(llDetectedKey(0)!=llGetOwner())return; if(pending!=NULL_KEY || finished) { llOwnerSay("Reset before starting another audit."); return; } if(llGetInventoryType("Config")!=INVENTORY_NOTECARD) { llOwnerSay("Add a saved Config notecard."); return; } requestLine(); } dataserver(key query,string data) { if(query!=pending || pending==NULL_KEY)return; if(data==EOF) { finish(); return; } data=llStringTrim(data,STRING_TRIM); if(data!="" && llGetSubString(data,0,0)!="#") { ++scannedRows; check(data); } ++lineNumber; if(lineNumber>=40) { llOwnerSay("40-line cap reached; report may be partial."); finish(); return; } requestLine(); } timer() { pending=NULL_KEY; finished=TRUE; llSetTimerEvent(0); llOwnerSay("Audit timed out; partial checks only. Reset to retry."); } changed(integer flags) { if(flags & (CHANGED_OWNER|CHANGED_INVENTORY))llResetScript(); } }