<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Andrew+Hellershanks</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Andrew+Hellershanks"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/Andrew_Hellershanks"/>
	<updated>2026-07-30T17:33:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Mesh/Creating_a_mesh&amp;diff=1162888</id>
		<title>Mesh/Creating a mesh</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Mesh/Creating_a_mesh&amp;diff=1162888"/>
		<updated>2012-02-14T16:40:33Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Added URL to DAZ 3D website&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Multi-lang}}&lt;br /&gt;
{{Navbox/Mesh|tools}}__NOTOC__ &lt;br /&gt;
You create mesh models using a third-party 3D modeling tool.  If you&#039;re a seasoned content creator, you may already be familiar with tools such as [http://usa.autodesk.com/adsk/servlet/pc/index?siteID=123112&amp;amp;id=13567410 3ds Max], [http://usa.autodesk.com/adsk/servlet/pc/index?siteID=123112&amp;amp;id=13577897 Maya], [http://www.blender.org/ Blender], or other popular professional tools; Google&#039;s [http://sketchup.google.com/ SketchUp] also provides a low barrier to entry for aspiring 3D modelers.  Any 3D modeling software will work, as long as it can output models in [http://en.wikipedia.org/wiki/Collada COLLADA] (&#039;&#039;.dae&#039;&#039;) format. &#039;&#039;Note: Second Life uses COLLADA 1.4.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A list of software that has COLLADA support can be found at [http://www.collada.org/mediawiki/index.php/Portal:Products_directory COLLADA.org Products Directory]&lt;br /&gt;
A very extensive list of 3d software can be found at [http://www.3dlinks.com/ 3Dlinks.com] under the software section.  Which of either the COLLADA or 3Dlinks items&lt;br /&gt;
will work with Second Life is not known, but at least it is a starting point to look.&lt;br /&gt;
&lt;br /&gt;
To learn more about some of the available 3D modeling tools, visit the [[Sculpted_Prims:_3d_Software_Guide|3D software guide]] created for use with [[Sculpted prims|sculpted prims]].  Most of the tools that work for sculpted prims should work with mesh, as long as they can export models in COLLADA format.&lt;br /&gt;
&lt;br /&gt;
=== Collada(DAE) Supported Programs for Mesh===&lt;br /&gt;
Notes on mesh support for specific versions of various applications - please update if you have additional information:&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|- {{Hl2}}&lt;br /&gt;
! Programs&lt;br /&gt;
! Bone&lt;br /&gt;
! UV Mapping&lt;br /&gt;
! Method&lt;br /&gt;
! Version&lt;br /&gt;
|-&lt;br /&gt;
|| 3ds Max || Yes || Yes || Import/Export via [http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&amp;amp;id=10775855 FBX Plug-in ] || 2009 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.inivis.com/ AC3D ] || No|| Yes || Import/Export || V6.7 and up&lt;br /&gt;
|-&lt;br /&gt;
|| Bentley&#039;s MicroStation || No || Yes || Import/Export || V8i and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.blender.org/ Blender ] || Yes || Yes || Import/Export || 2.49 and up&lt;br /&gt;
|-&lt;br /&gt;
|| Cinema 4D || Yes || Yes || Import/Export || R11 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.daz3d.com/ DAZ 3D ] || Yes || Yes || Import/Export || 2.0 and up&lt;br /&gt;
|-&lt;br /&gt;
|| Lightwave || Yes || Yes || Import/Export || 9.5 and up&lt;br /&gt;
|-&lt;br /&gt;
|| Maya || Yes || Yes || Import/Export via [http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&amp;amp;id=10775855 FBX Plug-in ] || 2009 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://chumbalum.swissquake.ch/ms3d/index.html Milkshape 3D ] || ? || Yes || Export || ?&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.luxology.com/modo/features/modeling/index.aspx Modo] || No || Yes || Import/Export || modo 401, 501. [http://sourceforge.net/projects/colladamodo/ Collada plugin on sourceforge]&lt;br /&gt;
|-&lt;br /&gt;
|| PhotoShop || No || ? || Direct open || Creative Suite 4 (11) and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://sketchup.google.com/ SketchUp ] || No || ? || Import/Export || 5.0 &amp;amp; 7.0 and up (6.0 was not supported)&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.wings3d.com/ Wings3D ] || No || Yes || Import/Export || 1.2 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://www.meshmixer.com/ MeshMixer(FREE) ] || No || Yes || Import obj/Export obj,dae || 5.0 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://kanae.net/secondlife/rokuro.html ROKURO(FREE) ] || No || C-SP || Export [http://kanaemesh-e.blogspot.com/2011/10/mr302-make-mesh-object-by-rokuro-30.html Tutorial] [http://www.youtube.com/watch?v=MYg7xrEEJ_k Video] || 3.0.9 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://kanae.net/secondlife/rokuro_pro.html ROKURO Pro ] || No || C-SP || Export [http://kanaemesh-e.blogspot.com/2011/10/mp302-make-mesh-object-by-rokuro-pro-30.html Tutorial] [http://www.youtube.com/watch?v=sZCFzJ7jrZ8 Video] || 3.0.59 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://kanae.net/secondlife/tatara.html TATARA ] || No || C-SP || Export [http://kanaemesh-e.blogspot.com/2011/10/mt602-make-mesh-object-by-tatara-60.html Tutorial] [http://www.youtube.com/watch?v=HT8Q0eMInUk Video] || 6.0.200 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://kanae.net/secondlife/nomi.html NOMI ] || No || C-SP || Export [http://kanaemesh-e.blogspot.com/2011/10/mn402-make-mesh-object-by-nomi-40.html Tutorial] [http://www.youtube.com/watch?v=W5SQIVqH2TU Video] || 4.0.47 and up&lt;br /&gt;
|-&lt;br /&gt;
|| [http://kanae.net/secondlife/kumiki.html KUMIKI ] || No || C-SP || Export [http://kanaemesh-e.blogspot.com/2011/10/mk102-make-mesh-object-by-kumiki-10.html Tutorial] [http://www.youtube.com/watch?v=RRJNl0oRQGw Video] || 1.0.31 and up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
C-SP: compatible with sculpted prim&lt;br /&gt;
&lt;br /&gt;
===General Tips===&lt;br /&gt;
* For the best results, first try outputting individual models before trying whole 3D scenes. &lt;br /&gt;
* If you already have a library of 3D models and need a way to convert them to COLLADA format, try [http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&amp;amp;id=10775855#section7 Autodesk&#039;s FBX Converter] (our preferred converter) or [http://meshlab.sourceforge.net/ MeshLab].&lt;br /&gt;
* Check out the [[Mesh/Troubleshooting|troubleshooting guide]] for more tips.&lt;br /&gt;
* Check out the [http://blog.machinimatrix.org/kettle-quest Kettle-Quest tutorials] for a comparison of Mesh vs. Sculpted Prims&lt;br /&gt;
* [http://www.youtube.com/watch?v=PKejMyeQF_g SL Mesh Clothing/Avatar Scale Issue in Non-Mesh Viewers]&lt;br /&gt;
&lt;br /&gt;
{{KBnote|If you use FBX converter, you may need to convert your models to an intermediate format, then to DAE, depending on the original format.}}&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Universal_Translator&amp;diff=1072782</id>
		<title>Universal Translator</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Universal_Translator&amp;diff=1072782"/>
		<updated>2010-10-25T17:17:10Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Fixed bad escape sequence. (\n was missing the n)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
This is the complete source code to the widely popular and free &amp;quot;HR Universal Translator&amp;quot; by [[Hank Ramos]].  This device is a dynamic public chat listener that automatically translates between 50+ languages and delivers translations of spoken text to those nearby that don&#039;t speak the language of the original speaker.&lt;br /&gt;
&lt;br /&gt;
Please help to further development on this open-source project. &lt;br /&gt;
&lt;br /&gt;
== Future Upgrades Needed ==&lt;br /&gt;
1. Support for Google Spellcheck.  Would be great to be able to spell-check chat first, and automatically do suggested corrections before the translation.&lt;br /&gt;
&lt;br /&gt;
2. Break the engine script into two or more scripts to allow for future expansion and to be able to handle low memory situations better.&lt;br /&gt;
&lt;br /&gt;
3. Support pseudo-instant message.  This could be done with avatars wearing the device within 100m of each others, or could be done world-wide using email or some other communications mechanism. Avatars would chat on a hidden channel, and would be able to communicate with another avatar or group chat.  Would require inworld servers of prims to link translators up together and find one another.&lt;br /&gt;
&lt;br /&gt;
4. Ensure that unicode is supported correctly.  Ensure that Right-to-Left languages are input and output correctly.  May need additional options since the SL client doesn&#039;t support this correctly and sometimes people speak backwards into SL chat to get around this.&lt;br /&gt;
&lt;br /&gt;
5. Rework auto-detection of language code. Should only automatically change the avatar&#039;s language if it is reliably predicted that they have changed languages.&lt;br /&gt;
&lt;br /&gt;
6. Add in automatic &amp;quot;spam&amp;quot; detection and prevent translation.  Find way to detect gesture &amp;quot;chat spam&amp;quot; and filter that out from the translation.  Filter out bad translations that only return the same or similar input.  Support replacement of common abbreviations or slang so that the google translation system can translate correctly.  May require support of a user-definable dictionary notecard.&lt;br /&gt;
&lt;br /&gt;
7. Handle translation errors from Google and resubmit the translation, rather than just ignoring it.&lt;br /&gt;
&lt;br /&gt;
8. Can you think of other improvements?&lt;br /&gt;
&lt;br /&gt;
= The Code =&lt;br /&gt;
The device consists of 3 key scripts, with several ancillary scripts to function.  The key scripts are listed here...&lt;br /&gt;
&lt;br /&gt;
==Universal Translator Engine==&lt;br /&gt;
This is the &amp;quot;heart&amp;quot; of the translator.  It handles communications with other translators, handles listening to avatars for chat, and handles most of the HTTP traffic.&lt;br /&gt;
&lt;br /&gt;
How do multiple translators communicate?  There are two chat channels at work...&lt;br /&gt;
&lt;br /&gt;
The heartbeat channel: this channel is fixed and common amongst all Universal Translators.  This is where each translator regularly announces its presence to other translators in the area.  If another one is found, a &amp;quot;master&#039; translator is elected at random (with higher version releases of the translators getting higher values).  The master translator is in charge of listening to all chat, and sending text to be translated and IMed to the recipient to the other &amp;quot;slave&amp;quot; translators.  &lt;br /&gt;
&lt;br /&gt;
Unique translator channel: each translator will select it&#039;s own channel to listen for incoming translations.  This serves as a unique conduit for the master translator to communicate with each individual slave.  This allows the heartbeat channel to be free for command messages to be sent, since the translated text being passed around can quickly saturate it.&lt;br /&gt;
&lt;br /&gt;
This multi-translator communication might be useful in other scripting projects.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//Universal Translator&lt;br /&gt;
//Version 1.9.0&lt;br /&gt;
//November 12, 2009&lt;br /&gt;
//LSL Script copyright 2006-2009 by Hank Ramos&lt;br /&gt;
//Web Server Services powered by Google&lt;br /&gt;
&lt;br /&gt;
//Variables&lt;br /&gt;
list agentsInTranslation;&lt;br /&gt;
list agentsInTranslationOptions;&lt;br /&gt;
list requestList;&lt;br /&gt;
integer listenID;&lt;br /&gt;
&lt;br /&gt;
integer isMaster = 1;&lt;br /&gt;
integer autoLanguage = TRUE;&lt;br /&gt;
integer enabled = FALSE;&lt;br /&gt;
integer showTranslation = FALSE;&lt;br /&gt;
integer tranObjects = TRUE;&lt;br /&gt;
&lt;br /&gt;
integer lastHeartBeat;&lt;br /&gt;
list    languageCodes = [&lt;br /&gt;
&amp;quot;zh-CN&amp;quot;, &amp;quot;zh-TW&amp;quot;, &amp;quot;hr&amp;quot;,  &lt;br /&gt;
&amp;quot;bg&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;ca&amp;quot;,&lt;br /&gt;
&amp;quot;af&amp;quot;, &amp;quot;sq&amp;quot;, &amp;quot;ar&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;tl&amp;quot;, &amp;quot;fr&amp;quot;, &amp;quot;gl&amp;quot;,    &lt;br /&gt;
&amp;quot;fi&amp;quot;, &amp;quot;en&amp;quot;, &amp;quot;et&amp;quot;,     &lt;br /&gt;
&amp;quot;cs&amp;quot;, &amp;quot;da&amp;quot;, &amp;quot;nl&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;id&amp;quot;, &amp;quot;ga&amp;quot;, &amp;quot;it&amp;quot;,      &lt;br /&gt;
&amp;quot;hi&amp;quot;, &amp;quot;hu&amp;quot;, &amp;quot;is&amp;quot;, &lt;br /&gt;
&amp;quot;de&amp;quot;, &amp;quot;el&amp;quot;, &amp;quot;iw&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;mt&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;fa&amp;quot;,   &lt;br /&gt;
&amp;quot;lt&amp;quot;, &amp;quot;mk&amp;quot;, &amp;quot;ms&amp;quot;,   &lt;br /&gt;
&amp;quot;ja&amp;quot;, &amp;quot;ko&amp;quot;, &amp;quot;lv&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;sl&amp;quot;, &amp;quot;es&amp;quot;, &amp;quot;sw&amp;quot;, &lt;br /&gt;
&amp;quot;ru&amp;quot;, &amp;quot;sr&amp;quot;, &amp;quot;sk&amp;quot;, &lt;br /&gt;
&amp;quot;pl&amp;quot;, &amp;quot;pt-PT&amp;quot;, &amp;quot;ro&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;yi&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
&amp;quot;uk&amp;quot;, &amp;quot;vi&amp;quot;, &amp;quot;cy&amp;quot;,&lt;br /&gt;
&amp;quot;sv&amp;quot;,&amp;quot;th&amp;quot;, &amp;quot;tr&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
list    translators;&lt;br /&gt;
list    sayCache;&lt;br /&gt;
list    sayCachePrivate;&lt;br /&gt;
integer priorityNumber;&lt;br /&gt;
integer priorityNumListenID;&lt;br /&gt;
integer isInitialized = FALSE;&lt;br /&gt;
string  options;&lt;br /&gt;
&lt;br /&gt;
//Options&lt;br /&gt;
//integer debug = TRUE;&lt;br /&gt;
integer broadcastChannel = -9999999; //note this is not the channel used by the HR Universal Translator&lt;br /&gt;
string  password = &amp;quot;password&amp;quot;; //note this is not the password used to encrypt comms of the HR Universal Translator&lt;br /&gt;
integer version = 190;&lt;br /&gt;
sendIM(key id, string str)&lt;br /&gt;
{&lt;br /&gt;
    if (llGetParcelFlags(llGetPos()) &amp;amp; PARCEL_FLAG_ALLOW_SCRIPTS)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 85234119, str, id); &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 85304563, str, id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sendTextBatch(integer channel, string sendText)&lt;br /&gt;
{&lt;br /&gt;
    sendText = llXorBase64StringsCorrect(llStringToBase64(sendText), llStringToBase64(password));;&lt;br /&gt;
    while (llStringLength(sendText) &amp;gt; 508) //If string is 509 characters or longer &lt;br /&gt;
    {&lt;br /&gt;
        llSay(channel, llGetSubString(sendText, 0, 507)); //send 508 character chunk&lt;br /&gt;
        sendText = llGetSubString(sendText, 508, -1);  //delete 508 character chunk&lt;br /&gt;
    }&lt;br /&gt;
    llSay(channel, sendText);  //send out any remainder chunk or original chunk&lt;br /&gt;
    if (llStringLength(sendText) == 508)&lt;br /&gt;
        llSay(channel, (string)(channel*4958654));&lt;br /&gt;
    llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0, 0.25&amp;gt;, &amp;quot;&amp;quot;); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string receiveTextBatch(key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    string  tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    listPos = llListFindList(sayCache, [id]);&lt;br /&gt;
    if (listPos &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPos &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            tempString = tempString + llList2String(sayCache, listPos + 1);&lt;br /&gt;
            sayCache = llDeleteSubList(sayCache, listPos, listPos + 1);&lt;br /&gt;
            listPos = llListFindList(sayCache, [id]);&lt;br /&gt;
        }&lt;br /&gt;
        message = tempString + message;&lt;br /&gt;
    }&lt;br /&gt;
    message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password)));&lt;br /&gt;
    return message;&lt;br /&gt;
}&lt;br /&gt;
string receiveTextBatchPrivate(key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    string  tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    listPos = llListFindList(sayCachePrivate, [id]);&lt;br /&gt;
    if (listPos &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPos &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            tempString = tempString + llList2String(sayCachePrivate, listPos + 1);&lt;br /&gt;
            sayCachePrivate = llDeleteSubList(sayCachePrivate, listPos, listPos + 1);&lt;br /&gt;
            listPos = llListFindList(sayCachePrivate, [id]);&lt;br /&gt;
        }&lt;br /&gt;
        message = tempString + message;&lt;br /&gt;
    }&lt;br /&gt;
    message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password)));&lt;br /&gt;
    return message;&lt;br /&gt;
}&lt;br /&gt;
updateTranslatorList()&lt;br /&gt;
{&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer listLength;&lt;br /&gt;
    list    newList;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer newMaster;&lt;br /&gt;
    &lt;br /&gt;
    //Scan and remove translators not in the area&lt;br /&gt;
    for (x = 0; x &amp;lt; llGetListLength(translators); x += 2)&lt;br /&gt;
    {&lt;br /&gt;
        tempString = llList2String(llGetObjectDetails(llList2Key(translators, x + 1), [OBJECT_POS]), 0);&lt;br /&gt;
        if ((llVecDist(llGetPos(), (vector)tempString) &amp;lt;= 20.0) &amp;amp;&amp;amp; (tempString != &amp;quot;&amp;quot;))&lt;br /&gt;
            newList += llList2List(translators, x, x + 1);&lt;br /&gt;
    }&lt;br /&gt;
    translators = newList;&lt;br /&gt;
&lt;br /&gt;
    listLength = llGetListLength(translators);&lt;br /&gt;
    llMessageLinked(LINK_THIS, 65635544, (string)listLength, &amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (listLength == 0)&lt;br /&gt;
    {&lt;br /&gt;
        newMaster = 1;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (enabled)&lt;br /&gt;
        {&lt;br /&gt;
            newMaster = 2;&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(translators); x += 2)&lt;br /&gt;
            {&lt;br /&gt;
                //llOwnerSay(&amp;quot;Checking Priority Number(&amp;quot; +  (string)priorityNumber + &amp;quot;): &amp;quot; + (string)llList2Integer(translators, x));&lt;br /&gt;
                if (llList2Integer(translators, x) &amp;gt; priorityNumber)&lt;br /&gt;
                {&lt;br /&gt;
                    newMaster = 0;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            newMaster = 0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ((isMaster &amp;gt; 0) &amp;amp;&amp;amp; (newMaster == 0))&lt;br /&gt;
    {&lt;br /&gt;
        //We are being demoted from master to slave&lt;br /&gt;
        //Flush agentsInTranslation to master&lt;br /&gt;
        if (llGetListLength(agentsInTranslation) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            //Demotion Dump of agentsInTranslation to Master&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1003, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
            if (isInitialized == FALSE) return;&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1004, options])); //error&lt;br /&gt;
        }&lt;br /&gt;
        llListenRemove(listenID);&lt;br /&gt;
    }&lt;br /&gt;
    if ((isMaster == 0) &amp;amp;&amp;amp; (newMaster &amp;gt; 0))&lt;br /&gt;
    {&lt;br /&gt;
        llListenRemove(listenID);&lt;br /&gt;
        listenID = llListen(0, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;); &lt;br /&gt;
    }&lt;br /&gt;
    isMaster = newMaster;&lt;br /&gt;
    llMessageLinked(LINK_THIS, 34829304, (string)isMaster, &amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sendHeartbeat()&lt;br /&gt;
{&lt;br /&gt;
    updateTranslatorList();&lt;br /&gt;
    sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber]));&lt;br /&gt;
&lt;br /&gt;
    //Broadcast agentList to Slaves&lt;br /&gt;
    if (isMaster == 2)&lt;br /&gt;
    {&lt;br /&gt;
        sendTextBatch(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Functions&lt;br /&gt;
checkThrottle(integer num, string msg, list params)&lt;br /&gt;
{&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer maxCount;&lt;br /&gt;
    float   oldTime;&lt;br /&gt;
    float   sleepTime;&lt;br /&gt;
    list    newList;&lt;br /&gt;
    key     returnValue;&lt;br /&gt;
    integer channelToSpeak;&lt;br /&gt;
    &lt;br /&gt;
    //loop though list and remove items older than 25 seconds&lt;br /&gt;
    for (x = 0; x &amp;lt; llGetListLength(requestList); x += 1)&lt;br /&gt;
    {&lt;br /&gt;
        oldTime = llList2Float(requestList, x);&lt;br /&gt;
        //Construct new list with only times less than 25 seconds&lt;br /&gt;
        if ((llGetTime() - oldTime) &amp;lt;= 25.0) &lt;br /&gt;
            newList += oldTime;&lt;br /&gt;
    }&lt;br /&gt;
    requestList = newList;&lt;br /&gt;
    &lt;br /&gt;
    x = llGetListLength(requestList);&lt;br /&gt;
    &lt;br /&gt;
    //Shunt all translations to linked translators if master&lt;br /&gt;
    if (isMaster == 2)&lt;br /&gt;
    {&lt;br /&gt;
        if (num == 0)&lt;br /&gt;
        {&lt;br /&gt;
            //Send HTTP request to other translator&lt;br /&gt;
            //Send out Request to Random Translator Channel&lt;br /&gt;
&lt;br /&gt;
            channelToSpeak = llList2Integer(llListRandomize(llList2ListStrided(translators, 0, -1, 2), 1), 0);&lt;br /&gt;
            if (channelToSpeak &amp;gt; 0) &lt;br /&gt;
            {&lt;br /&gt;
                sendTextBatch(channelToSpeak, llList2CSV([num, llList2CSV(params)]) + &amp;quot;~&amp;quot; + msg);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (x == 19)&lt;br /&gt;
    {&lt;br /&gt;
        sleepTime =  25.0 - (llGetTime() - llList2Float(requestList, 0));&lt;br /&gt;
        if (sleepTime &amp;gt; 0) &lt;br /&gt;
        {&lt;br /&gt;
            llSleep(sleepTime);&lt;br /&gt;
        }&lt;br /&gt;
        requestList = llDeleteSubList(requestList, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (num == 0)&lt;br /&gt;
    {&lt;br /&gt;
        msg = &amp;quot;translate?v=1.0&amp;amp;q=&amp;quot; + msg;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
        msg = &amp;quot;detect?v=1.0&amp;amp;q=&amp;quot; + msg;&lt;br /&gt;
&lt;br /&gt;
    requestList += llGetTime();&lt;br /&gt;
    returnValue = llHTTPRequest(&amp;quot;http://ajax.googleapis.com/ajax/services/language/&amp;quot; + msg, [HTTP_METHOD, &amp;quot;GET&amp;quot;, HTTP_MIMETYPE, &amp;quot;plain/text;charset=utf-8&amp;quot;], &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (returnValue != NULL_KEY)&lt;br /&gt;
    {&lt;br /&gt;
        if (num == 0)&lt;br /&gt;
            llMessageLinked(LINK_THIS, 235365342, llList2CSV(params), returnValue); &lt;br /&gt;
        else&lt;br /&gt;
            llMessageLinked(LINK_THIS, 235365343, llList2CSV(params), returnValue); &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llSleep(40.0); //Something has gone horribly wrong, sleep 40 seconds to clear throttle&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string checkLanguage(string tempString)&lt;br /&gt;
{&lt;br /&gt;
    if      (llGetSubString(tempString, 0, 1) == &amp;quot;zh&amp;quot;)    tempString = &amp;quot;zh-CN&amp;quot;;&lt;br /&gt;
    else if (tempString == &amp;quot;und&amp;quot;)   tempString = &amp;quot;el&amp;quot;;&lt;br /&gt;
    else if (llListFindList(languageCodes, [tempString]) &amp;lt; 0) tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    tempString = llGetSubString(tempString, 0, 1);&lt;br /&gt;
    return tempString;&lt;br /&gt;
}&lt;br /&gt;
addAgent(key id, string language, integer recheckLangauge)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    integer listPosID;&lt;br /&gt;
    integer idNum;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
&lt;br /&gt;
    listPos = llListFindList(agentsInTranslation, [id]);&lt;br /&gt;
    if (listPos &amp;lt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPosID &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            idNum = llRound(llFrand(2000000)) + 1;&lt;br /&gt;
            listPosID = llListFindList(agentsInTranslation, [idNum]);&lt;br /&gt;
        }&lt;br /&gt;
        agentsInTranslation += [id, language, recheckLangauge, idNum];&lt;br /&gt;
        llMessageLinked(LINK_THIS, 64562349, language, id);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
        agentsInTranslation = llListReplaceList(agentsInTranslation, [language, recheckLangauge], listPos + 1, listPos + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string addNewAgent(key id)&lt;br /&gt;
{&lt;br /&gt;
    string speakerLanguage;&lt;br /&gt;
    &lt;br /&gt;
    if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY)&lt;br /&gt;
    {&lt;br /&gt;
        speakerLanguage  = checkLanguage(llGetAgentLanguage(id));&lt;br /&gt;
        if (speakerLanguage == &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            speakerLanguage = &amp;quot;en&amp;quot;;&lt;br /&gt;
            addAgent(id, speakerLanguage, TRUE);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            addAgent(id, speakerLanguage, FALSE);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return speakerLanguage;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
key getAgentKey(integer agentID)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos = llListFindList(agentsInTranslation, [agentID]);&lt;br /&gt;
    if (listPos &amp;lt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2Key(agentsInTranslation, listPos - 3);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
processHTTPResponse(integer type, string body, list params)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    list    recepientList;&lt;br /&gt;
    key     recepientID;&lt;br /&gt;
    string  recepientLanguage;&lt;br /&gt;
    string  languagePair;&lt;br /&gt;
    key     speakerID;&lt;br /&gt;
    string  speakerName;&lt;br /&gt;
    string  speakerLanguage;&lt;br /&gt;
    string  translatedText;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer speakerLanguageReliable;&lt;br /&gt;
    float   speakerLanguageConfidence;&lt;br /&gt;
    list    tempList;&lt;br /&gt;
    &lt;br /&gt;
    //===================&lt;br /&gt;
    //Process Translation&lt;br /&gt;
    //===================&lt;br /&gt;
    if (type == 0)&lt;br /&gt;
    {&lt;br /&gt;
        speakerID  = llList2Key(params, 1);&lt;br /&gt;
        speakerName = llKey2Name(speakerID);&lt;br /&gt;
        if (speakerName == &amp;quot;&amp;quot;)&lt;br /&gt;
            speakerName = llList2String(llGetObjectDetails(speakerID, [OBJECT_NAME]), 0);&lt;br /&gt;
        &lt;br /&gt;
        recepientList = llParseString2List(llList2String(params, 2), [&amp;quot;@&amp;quot;], []);&lt;br /&gt;
        tempList = llParseStringKeepNulls(llList2String(params, 3), [&amp;quot;|&amp;quot;],[]);&lt;br /&gt;
        recepientLanguage = llList2String(tempList, 1);&lt;br /&gt;
        languagePair = llDumpList2String(tempList, &amp;quot;&amp;gt;&amp;gt;&amp;quot;); &lt;br /&gt;
        &lt;br /&gt;
        //Perform Text Cleanup&lt;br /&gt;
        x = llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;detectedSourceLanguage\&amp;quot;:\&amp;quot;&amp;quot;); &lt;br /&gt;
        if (x &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            translatedText  = llGetSubString(body,  llSubStringIndex(body, &amp;quot;{\&amp;quot;translatedText\&amp;quot;:\&amp;quot;&amp;quot;) + 18, x);&lt;br /&gt;
            speakerLanguage = checkLanguage(llGetSubString(body, x + 28, llSubStringIndex(body, &amp;quot;\&amp;quot;}, \&amp;quot;responseDetails\&amp;quot;:&amp;quot;) - 1));&lt;br /&gt;
            &lt;br /&gt;
            listPos = llListFindList(agentsInTranslation, [speakerID]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                if (speakerLanguage != llList2String(agentsInTranslation, listPos + 1))&lt;br /&gt;
                    agentsInTranslation = llListReplaceList(agentsInTranslation, [TRUE], listPos + 2, listPos + 2);  //Mark for recheck of actual spoken language.&lt;br /&gt;
            }                   &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            translatedText = llGetSubString(body, llSubStringIndex(body, &amp;quot;{\&amp;quot;translatedText\&amp;quot;:\&amp;quot;&amp;quot;) + 18, llSubStringIndex(body, &amp;quot;\&amp;quot;}, \&amp;quot;responseDetails\&amp;quot;&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Reverse order if Recepient Language is Hebrew or Arabic&lt;br /&gt;
        if ((recepientLanguage == &amp;quot;iw&amp;quot;) || (recepientLanguage == &amp;quot;ar&amp;quot;))&lt;br /&gt;
        {  &lt;br /&gt;
            tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
            for(x = llStringLength(translatedText);x &amp;gt;= 0; x--)&lt;br /&gt;
            {&lt;br /&gt;
                tempString += llGetSubString(translatedText, x, x); &lt;br /&gt;
            }&lt;br /&gt;
            translatedText = tempString;&lt;br /&gt;
        }                    &lt;br /&gt;
        tempString = speakerName + &amp;quot;(&amp;quot; + languagePair + &amp;quot;): &amp;quot; + translatedText;&lt;br /&gt;
        if (showTranslation)&lt;br /&gt;
            sendIM(speakerID, tempString);  &lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(recepientList); x += 1)&lt;br /&gt;
        {&lt;br /&gt;
            recepientID = getAgentKey(llList2Integer(recepientList, x));&lt;br /&gt;
            &lt;br /&gt;
            if (recepientID != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                recepientLanguage = llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [recepientID]) + 1);&lt;br /&gt;
                if (recepientLanguage != speakerLanguage)&lt;br /&gt;
                    sendIM(recepientID, tempString);&lt;br /&gt;
            }  &lt;br /&gt;
        }&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //===========================&lt;br /&gt;
    //Process Language Detection&lt;br /&gt;
    //===========================&lt;br /&gt;
    if (type == 1)&lt;br /&gt;
    {&lt;br /&gt;
        speakerID = llList2Key(params, 1);&lt;br /&gt;
        &lt;br /&gt;
        speakerLanguageReliable = llToLower(llGetSubString(body, llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;isReliable\&amp;quot;:&amp;quot;) + 15, llSubStringIndex(body, &amp;quot;,\&amp;quot;confidence\&amp;quot;:&amp;quot;) - 1)) == &amp;quot;true&amp;quot;;&lt;br /&gt;
        speakerLanguageConfidence = (float)llGetSubString(body, llSubStringIndex(body, &amp;quot;,\&amp;quot;confidence\&amp;quot;:&amp;quot;) + 14, llSubStringIndex(body, &amp;quot;}, \&amp;quot;responseDetails\&amp;quot;:&amp;quot;) - 1);&lt;br /&gt;
        &lt;br /&gt;
        listPos = llListFindList(agentsInTranslation, [speakerID]);&lt;br /&gt;
&lt;br /&gt;
        if (((listPos &amp;lt; 0) &amp;amp;&amp;amp; (speakerLanguageReliable) || (speakerLanguageConfidence &amp;gt;= 0.18)))&lt;br /&gt;
        {&lt;br /&gt;
            //Analyze Data&lt;br /&gt;
            tempString = checkLanguage(llToLower(llGetSubString(body, llSubStringIndex(body, &amp;quot;{\&amp;quot;language\&amp;quot;:\&amp;quot;&amp;quot;) + 13, llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;isReliable\&amp;quot;:&amp;quot;) - 1)));&lt;br /&gt;
            if (tempString == &amp;quot;&amp;quot;) return;&lt;br /&gt;
            &lt;br /&gt;
            if (speakerLanguageConfidence &amp;lt; 0.14)&lt;br /&gt;
                addAgent(speakerID, tempString, TRUE);&lt;br /&gt;
            else&lt;br /&gt;
                addAgent(speakerID, tempString, FALSE);&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        //Multiplexor Initialization&lt;br /&gt;
        priorityNumber = version*1000000 + llRound(llFrand(499999) + 50000);&lt;br /&gt;
        llListen(broadcastChannel, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        priorityNumListenID = llListen(priorityNumber, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        //Send out initial heartbeat&lt;br /&gt;
        lastHeartBeat = llGetUnixTime();&lt;br /&gt;
        sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber]));&lt;br /&gt;
        &lt;br /&gt;
        //Wait for the network to settle down&lt;br /&gt;
        llSetTimerEvent(5); &lt;br /&gt;
        //llSetTimerEvent(10 + ((1-llGetRegionTimeDilation()) * 1));       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    sensor(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        key     id;&lt;br /&gt;
&lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x += 1)&lt;br /&gt;
        {&lt;br /&gt;
            id = llDetectedKey(x);&lt;br /&gt;
            if (llListFindList(agentsInTranslation, [id]) &amp;lt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                addNewAgent(id);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        integer channelToSpeak;&lt;br /&gt;
        &lt;br /&gt;
        //Old Multiplexor&lt;br /&gt;
        if (num == 8434532)&lt;br /&gt;
        {&lt;br /&gt;
            enabled = (integer)str;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3342976)&lt;br /&gt;
        {&lt;br /&gt;
            //Send Preferences&lt;br /&gt;
            options = str;&lt;br /&gt;
            if (isInitialized == FALSE) return;&lt;br /&gt;
            tempList = llCSV2List(options);&lt;br /&gt;
            showTranslation = llList2Integer(tempList, 0);&lt;br /&gt;
            tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
            autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1004, options]));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 9384610)&lt;br /&gt;
        {&lt;br /&gt;
            if (isMaster == 0) //markering&lt;br /&gt;
                //llMessageLinked(LINK_THIS, 5598321, llList2CSV([id, str, FALSE]), &amp;quot;&amp;quot;);&lt;br /&gt;
                sendTextBatch(broadcastChannel, llList2CSV([1003, id, str, FALSE]));&lt;br /&gt;
            else&lt;br /&gt;
                addAgent(id, str, TRUE);&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149625)&lt;br /&gt;
        {&lt;br /&gt;
            //Return Translation&lt;br /&gt;
            processHTTPResponse(0, str, llCSV2List(id));&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149626)&lt;br /&gt;
        {&lt;br /&gt;
            //Return Detection&lt;br /&gt;
            processHTTPResponse(1, str, llCSV2List(id));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        list    newList;&lt;br /&gt;
        integer translatorCount = llGetListLength(translators)/2;&lt;br /&gt;
        &lt;br /&gt;
        if (isInitialized == FALSE)&lt;br /&gt;
        {&lt;br /&gt;
            isInitialized = TRUE;&lt;br /&gt;
            enabled = TRUE;&lt;br /&gt;
            listenID = llListen(0, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;); &lt;br /&gt;
            llListen(777, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
            llMessageLinked(LINK_THIS, 6877259, (string)enabled, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        llMessageLinked(LINK_THIS, 94558323, llList2CSV(agentsInTranslation), &amp;quot;&amp;quot;);&lt;br /&gt;
        if (isMaster &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(agentsInTranslation); x += 4)&lt;br /&gt;
            {&lt;br /&gt;
                tempString = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_POS]), 0);&lt;br /&gt;
                if ((llVecDist(llGetPos(), (vector)tempString) &amp;lt;= 20.0) &amp;amp;&amp;amp; (tempString != &amp;quot;&amp;quot;))&lt;br /&gt;
                    newList += llList2List(agentsInTranslation, x, x + 3);&lt;br /&gt;
            }&lt;br /&gt;
    &lt;br /&gt;
            agentsInTranslation = newList;&lt;br /&gt;
            if ((llGetUnixTime() - lastHeartBeat) &amp;gt;= 5)&lt;br /&gt;
            {&lt;br /&gt;
                //Send heartbeat&lt;br /&gt;
                sendHeartbeat();&lt;br /&gt;
                lastHeartBeat = llGetUnixTime();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if ((llGetUnixTime() - lastHeartBeat) &amp;gt;= 0 + llGetListLength(agentsInTranslation)*2 + llPow(translatorCount, 1.4) + translatorCount + ((1-llGetRegionTimeDilation()) * 5))&lt;br /&gt;
            {&lt;br /&gt;
                //Send heartbeat&lt;br /&gt;
                sendHeartbeat();&lt;br /&gt;
                lastHeartBeat = llGetUnixTime();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
                    &lt;br /&gt;
        //turn on and off scanner&lt;br /&gt;
        if ((autoLanguage) &amp;amp;&amp;amp; (isMaster &amp;gt; 0))&lt;br /&gt;
        {&lt;br /&gt;
            llSensor(&amp;quot;&amp;quot;, NULL_KEY, AGENT, 20.0, PI);&lt;br /&gt;
        }&lt;br /&gt;
        //llSetTimerEvent(4 + ((1-llGetRegionTimeDilation()) * 5));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  speakerLanguage;&lt;br /&gt;
        string  recepientLanguage;&lt;br /&gt;
        integer recepientID;&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        string  languagePair;&lt;br /&gt;
        list    translationCache;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        integer ImessageType;&lt;br /&gt;
        string  Imessage;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        string  tempString2;&lt;br /&gt;
        &lt;br /&gt;
        //Multiplexor Code&lt;br /&gt;
        if ((channel == broadcastChannel) || (channel == priorityNumber))&lt;br /&gt;
        {&lt;br /&gt;
            //==========================&lt;br /&gt;
            //Process Proxy HTTP Request&lt;br /&gt;
            //==========================&lt;br /&gt;
&lt;br /&gt;
            if (channel == priorityNumber)&lt;br /&gt;
            {&lt;br /&gt;
                if (llStringLength(message) &amp;gt;= 508)&lt;br /&gt;
                {&lt;br /&gt;
                    if (((integer)message/channel) != 4958654)&lt;br /&gt;
                    {&lt;br /&gt;
                        sayCachePrivate += [id, message];&lt;br /&gt;
                        return; &lt;br /&gt;
                    }&lt;br /&gt;
                    message = &amp;quot;&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
                message = receiveTextBatchPrivate(id, message);&lt;br /&gt;
                //Received packet to translate&lt;br /&gt;
                llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0.05, 0.25&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
                &lt;br /&gt;
                tempList = llParseString2List(message, [&amp;quot;~&amp;quot;], []);&lt;br /&gt;
                tempString = llList2String(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
&lt;br /&gt;
                tempString2 = llDumpList2String(tempList, &amp;quot;|&amp;quot;);&lt;br /&gt;
                tempList = llCSV2List(tempString);&lt;br /&gt;
                listPos = llList2Integer(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
&lt;br /&gt;
                checkThrottle(listPos, tempString2, tempList);&lt;br /&gt;
&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            //=======================&lt;br /&gt;
            //Process Global Messages&lt;br /&gt;
            //=======================&lt;br /&gt;
            if (llStringLength(message) &amp;gt;= 508)&lt;br /&gt;
            {&lt;br /&gt;
                if (((integer)message/channel) != 4958654)&lt;br /&gt;
                {&lt;br /&gt;
                    sayCache += [id, message];&lt;br /&gt;
                    return; &lt;br /&gt;
                }&lt;br /&gt;
                message = &amp;quot;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            message = receiveTextBatch(id, message);&lt;br /&gt;
            &lt;br /&gt;
            tempList = llCSV2List(message);&lt;br /&gt;
            &lt;br /&gt;
            if (llGetListLength(tempList) &amp;gt;= 2)    &lt;br /&gt;
            {&lt;br /&gt;
                ImessageType = llList2Integer(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
                Imessage = llList2CSV(tempList);        &lt;br /&gt;
            &lt;br /&gt;
                llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0, 0.25&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
                //Process Message Here&lt;br /&gt;
                if (ImessageType == 1001)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming Heartbeat&lt;br /&gt;
                    if ((integer)Imessage == priorityNumber)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Priority Number Conflict!  Resetting Script...&amp;quot;);&lt;br /&gt;
                        llResetScript(); //Reset if conflicting priority number&lt;br /&gt;
                    }&lt;br /&gt;
                    listPos = llListFindList(translators, [id]);&lt;br /&gt;
                    if (listPos &amp;lt; 0) &lt;br /&gt;
                    {&lt;br /&gt;
                        translators += [(integer)Imessage, id];&lt;br /&gt;
                        if ((isMaster &amp;gt; 0) &amp;amp;&amp;amp; (isInitialized))&lt;br /&gt;
                        {&lt;br /&gt;
                            sendTextBatch((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
                            sendTextBatch((integer)Imessage, llList2CSV([1004, options]));&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        translators = llListReplaceList(translators, [(integer)Imessage], listPos - 1, listPos - 1);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1002)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming agentsInTranslation Master Broadcast&lt;br /&gt;
                    if (isMaster == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        //llMessageLinked(LINK_THIS, 9458021, Imessage, &amp;quot;&amp;quot;);  &lt;br /&gt;
                        tempList = llCSV2List(Imessage);&lt;br /&gt;
                        agentsInTranslation = [];&lt;br /&gt;
                        for (x = 0; x &amp;lt; llGetListLength(tempList); x += 4)&lt;br /&gt;
                        {&lt;br /&gt;
                            agentsInTranslation += [llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2), llList2Integer(tempList, x + 3)];&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1003)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming agentsInTranslation dump from Slave&lt;br /&gt;
                    tempList = llCSV2List(Imessage);&lt;br /&gt;
                    for (x = 0; x &amp;lt; llGetListLength(tempList); x += 4)&lt;br /&gt;
                    {&lt;br /&gt;
                        addAgent(llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1004)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming Preferences&lt;br /&gt;
                    options = Imessage;&lt;br /&gt;
                    tempList = llCSV2List(options);&lt;br /&gt;
                    showTranslation = llList2Integer(tempList, 0);&lt;br /&gt;
                    tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
                    autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
&lt;br /&gt;
                    llMessageLinked(LINK_THIS, 3342977, Imessage, &amp;quot;&amp;quot;);  &lt;br /&gt;
                }&lt;br /&gt;
            }            &lt;br /&gt;
            &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Translator Engine Code&lt;br /&gt;
        if ((llToLower(message) == &amp;quot;translator&amp;quot;) &amp;amp;&amp;amp; (isMaster &amp;gt; 0)) &lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, 2540664, message, id);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ((!enabled) &amp;amp;&amp;amp; (isMaster == 1)) return;&lt;br /&gt;
        &lt;br /&gt;
        if (!tranObjects)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) != NULL_KEY) return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        listPos = llListFindList(agentsInTranslation, [id]);&lt;br /&gt;
        if (listPos &amp;gt;= 0)&lt;br /&gt;
        {            &lt;br /&gt;
            speakerLanguage = llList2String(agentsInTranslation, listPos + 1);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            speakerLanguage = addNewAgent(id);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (speakerLanguage == &amp;quot;xx&amp;quot;) return;  //Agent Opt-Out&lt;br /&gt;
        &lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 1, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
        //===============================&lt;br /&gt;
        //Formulate Translation Requests&lt;br /&gt;
        //===============================&lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(agentsInTranslation); x += 4)&lt;br /&gt;
        {&lt;br /&gt;
            //Loop through translation group and do appropriate translations as needed&lt;br /&gt;
            recepientID = llList2Integer(agentsInTranslation, x + 3);&lt;br /&gt;
            recepientLanguage =  checkLanguage(llList2Key(agentsInTranslation, x + 1)); &lt;br /&gt;
            if ((speakerLanguage != recepientLanguage) &amp;amp;&amp;amp; (recepientLanguage != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (recepientLanguage != &amp;quot;xx&amp;quot;))&lt;br /&gt;
            {&lt;br /&gt;
                languagePair = speakerLanguage + &amp;quot;|&amp;quot; + recepientLanguage;&lt;br /&gt;
                    &lt;br /&gt;
                listPos = llListFindList(translationCache, [languagePair]);&lt;br /&gt;
                if (listPos &amp;lt; 0)&lt;br /&gt;
                  translationCache += [languagePair, recepientID];&lt;br /&gt;
                else&lt;br /&gt;
                  translationCache = llListReplaceList(translationCache, [llList2String(translationCache, listPos + 1) + &amp;quot;@&amp;quot; + (string)recepientID], listPos + 1, listPos + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        //Process Requests&lt;br /&gt;
        if (llGetListLength(translationCache) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(translationCache); x += 2)&lt;br /&gt;
            {&lt;br /&gt;
                //====================================&lt;br /&gt;
                //Translation&lt;br /&gt;
                //====================================&lt;br /&gt;
                //Forumulate and Send Translation Request&lt;br /&gt;
                languagePair = &amp;quot;|&amp;quot; + llList2String(llParseStringKeepNulls(llList2String(translationCache, x), [&amp;quot;|&amp;quot;],[]), 1); &lt;br /&gt;
                checkThrottle(0, llEscapeURL(message) + &amp;quot;&amp;amp;langpair=&amp;quot; + llEscapeURL(languagePair), [llGetTime(), id , llList2String(translationCache, x + 1), llList2String(translationCache, x)]);&lt;br /&gt;
            } &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            speakerLanguage = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        //====================================&lt;br /&gt;
        //Language Detection&lt;br /&gt;
        //====================================&lt;br /&gt;
        if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY)&lt;br /&gt;
        {&lt;br /&gt;
            if (((speakerLanguage == &amp;quot;&amp;quot;) || (llList2Integer(agentsInTranslation, llListFindList(agentsInTranslation, [id]) + 2) == TRUE)) || (isMaster == 2))&lt;br /&gt;
            {&lt;br /&gt;
                //Forumulate and Send Language Detect Request&lt;br /&gt;
                checkThrottle(1, llEscapeURL(message), [llGetTime(), id]);&lt;br /&gt;
            }       &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        string  tempString;&lt;br /&gt;
&lt;br /&gt;
        if (status != 200) &lt;br /&gt;
        {&lt;br /&gt;
            //llOwnerSay(&amp;quot;WWW Error:&amp;quot; + (string)status);&lt;br /&gt;
            llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 0, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
            //llOwnerSay(body);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Process Resonse Code&lt;br /&gt;
        tempString = llGetSubString(body, llSubStringIndex(body, &amp;quot;\&amp;quot;responseStatus\&amp;quot;:&amp;quot;), -1);&lt;br /&gt;
        status = (integer)llGetSubString(tempString, 17, llSubStringIndex(tempString, &amp;quot;}&amp;quot;) - 1);&lt;br /&gt;
        if (status != 200)&lt;br /&gt;
        {&lt;br /&gt;
            //llOwnerSay(&amp;quot;Language Server Returned Error Code: &amp;quot; + (string)status);&lt;br /&gt;
            //llOwnerSay(body);&lt;br /&gt;
            llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 0, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0, 0, 1&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, 345149624, body, request_id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HTTP Handler==&lt;br /&gt;
Even though the name of this script is &amp;quot;HTTP Handler&amp;quot;, it really just stores the requested translation traffic so that we can match incoming translations from Google with what was requested.  Since this takes a lot of memory for storage, this information is kept out of the engine script.  When an incoming HTTP response comes in, we fetch the data from here.  If the requests didn&#039;t come back in a timely fashion, we remove it from the queue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//HTTP Handler&lt;br /&gt;
//Copyright 2006-2009 by Hank Ramos&lt;br /&gt;
&lt;br /&gt;
list requestedTranslations;&lt;br /&gt;
list requestedDetections;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSetTimerEvent(5);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        list    newList;&lt;br /&gt;
        float timeElapsed; &lt;br /&gt;
        &lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(requestedDetections); x += 2)&lt;br /&gt;
        {&lt;br /&gt;
            timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedDetections, x + 1)), 0);&lt;br /&gt;
            if (timeElapsed &amp;lt; 60.0) &lt;br /&gt;
                newList += llList2List(requestedDetections, x, x + 1);&lt;br /&gt;
        }&lt;br /&gt;
        requestedDetections = newList;&lt;br /&gt;
        newList = [];&lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(requestedTranslations); x += 2)&lt;br /&gt;
        {&lt;br /&gt;
            timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedTranslations, x + 1)), 0);&lt;br /&gt;
            if (timeElapsed &amp;lt; 60.0) &lt;br /&gt;
            {&lt;br /&gt;
                newList += llList2List(requestedTranslations, x, x + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        requestedTranslations = newList;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        &lt;br /&gt;
        if (num == 235365342)&lt;br /&gt;
        {&lt;br /&gt;
            //Translation&lt;br /&gt;
            requestedTranslations += [id, str];&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 235365343)&lt;br /&gt;
        {&lt;br /&gt;
            //Detection&lt;br /&gt;
            requestedDetections += [id, str];&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149624)&lt;br /&gt;
        {&lt;br /&gt;
            listPos = llListFindList(requestedTranslations, [id]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, 345149625, str, llList2String(requestedTranslations, listPos + 1));&lt;br /&gt;
                requestedTranslations = llDeleteSubList(requestedTranslations, listPos, listPos + 1);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            listPos = llListFindList(requestedDetections, [id]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, 345149626, str, llList2String(requestedDetections, listPos + 1));&lt;br /&gt;
                requestedDetections = llDeleteSubList(requestedDetections, listPos, listPos + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interface Handler==&lt;br /&gt;
This is the interface, or menu-system of the translator.  It handles all of the numerous dialogs, language selection, etc. of the translator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//Menu System&lt;br /&gt;
//Copyright 2006-2009 by Hank Ramos&lt;br /&gt;
&lt;br /&gt;
//Variables&lt;br /&gt;
integer randomDialogChannel;&lt;br /&gt;
integer lastAttachPoint;&lt;br /&gt;
list    detectedAgentKeyList;&lt;br /&gt;
list    detectedAgentNameList;&lt;br /&gt;
key     agentInDialog;&lt;br /&gt;
integer isInitialized = FALSE;&lt;br /&gt;
list    agentsInTranslation;&lt;br /&gt;
integer translatorCount;&lt;br /&gt;
&lt;br /&gt;
//Options&lt;br /&gt;
integer groupAccess    = FALSE;&lt;br /&gt;
integer autoLanguage   = TRUE;&lt;br /&gt;
integer deviceAttached;&lt;br /&gt;
integer enabled        = FALSE;&lt;br /&gt;
integer isShowTran     = FALSE;&lt;br /&gt;
integer showAgents     = TRUE;&lt;br /&gt;
string  displayStringMD5;&lt;br /&gt;
integer isMaster = 1;&lt;br /&gt;
integer tranObjects = TRUE;&lt;br /&gt;
&lt;br /&gt;
//Constants&lt;br /&gt;
list    languages= [&lt;br /&gt;
&amp;quot;Chinese-Simple&amp;quot;, &amp;quot;Chinese-Trad&amp;quot;, &amp;quot;Croatian&amp;quot;,  &lt;br /&gt;
&amp;quot;Bulgarian&amp;quot;, &amp;quot;Belarusian&amp;quot;, &amp;quot;Catlan&amp;quot;,&lt;br /&gt;
&amp;quot;Afrikaans&amp;quot;, &amp;quot;Albanian&amp;quot;, &amp;quot;Arabic&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Filipino&amp;quot;, &amp;quot;French&amp;quot;, &amp;quot;Galician&amp;quot;,    &lt;br /&gt;
&amp;quot;Finnish&amp;quot;, &amp;quot;English&amp;quot;, &amp;quot;Estonian&amp;quot;,     &lt;br /&gt;
&amp;quot;Czech&amp;quot;, &amp;quot;Danish&amp;quot;, &amp;quot;Dutch&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Indonesian&amp;quot;, &amp;quot;Irish&amp;quot;, &amp;quot;Italian&amp;quot;,      &lt;br /&gt;
&amp;quot;Hindi&amp;quot;, &amp;quot;Hungarian&amp;quot;, &amp;quot;Icelandic&amp;quot;, &lt;br /&gt;
&amp;quot;German&amp;quot;, &amp;quot;Greek&amp;quot;, &amp;quot;Hebrew&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;Maltese&amp;quot;, &amp;quot;Norwegian&amp;quot;, &amp;quot;Persian&amp;quot;,   &lt;br /&gt;
&amp;quot;Lithuanian&amp;quot;, &amp;quot;Macedonian&amp;quot;, &amp;quot;Malay&amp;quot;,   &lt;br /&gt;
&amp;quot;Japanese&amp;quot;, &amp;quot;Korean&amp;quot;, &amp;quot;Latvian&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Slovenian&amp;quot;, &amp;quot;Spanish&amp;quot;, &amp;quot;Swahili&amp;quot;, &lt;br /&gt;
&amp;quot;Russian&amp;quot;, &amp;quot;Serbian&amp;quot;, &amp;quot;Slovak&amp;quot;, &lt;br /&gt;
&amp;quot;Polish&amp;quot;, &amp;quot;Portuguese&amp;quot;, &amp;quot;Romanian&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Yiddish&amp;quot;, &amp;quot;\t     &amp;quot;, &amp;quot;\t     &amp;quot;,&lt;br /&gt;
&amp;quot;Ukrainian&amp;quot;, &amp;quot;Vietnamese&amp;quot;, &amp;quot;Welsh&amp;quot;,&lt;br /&gt;
&amp;quot;Swedish&amp;quot;, &amp;quot;Thai&amp;quot;, &amp;quot;Turkish&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
list    languageCodes = [&lt;br /&gt;
&amp;quot;zh-CN&amp;quot;, &amp;quot;zh-TW&amp;quot;, &amp;quot;hr&amp;quot;,  &lt;br /&gt;
&amp;quot;bg&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;ca&amp;quot;,&lt;br /&gt;
&amp;quot;af&amp;quot;, &amp;quot;sq&amp;quot;, &amp;quot;ar&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;tl&amp;quot;, &amp;quot;fr&amp;quot;, &amp;quot;gl&amp;quot;,    &lt;br /&gt;
&amp;quot;fi&amp;quot;, &amp;quot;en&amp;quot;, &amp;quot;et&amp;quot;,     &lt;br /&gt;
&amp;quot;cs&amp;quot;, &amp;quot;da&amp;quot;, &amp;quot;nl&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;id&amp;quot;, &amp;quot;ga&amp;quot;, &amp;quot;it&amp;quot;,      &lt;br /&gt;
&amp;quot;hi&amp;quot;, &amp;quot;hu&amp;quot;, &amp;quot;is&amp;quot;, &lt;br /&gt;
&amp;quot;de&amp;quot;, &amp;quot;el&amp;quot;, &amp;quot;iw&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;mt&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;fa&amp;quot;,   &lt;br /&gt;
&amp;quot;lt&amp;quot;, &amp;quot;mk&amp;quot;, &amp;quot;ms&amp;quot;,   &lt;br /&gt;
&amp;quot;ja&amp;quot;, &amp;quot;ko&amp;quot;, &amp;quot;lv&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;sl&amp;quot;, &amp;quot;es&amp;quot;, &amp;quot;sw&amp;quot;, &lt;br /&gt;
&amp;quot;ru&amp;quot;, &amp;quot;sr&amp;quot;, &amp;quot;sk&amp;quot;, &lt;br /&gt;
&amp;quot;pl&amp;quot;, &amp;quot;pt-PT&amp;quot;, &amp;quot;ro&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;yi&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
&amp;quot;uk&amp;quot;, &amp;quot;vi&amp;quot;, &amp;quot;cy&amp;quot;,&lt;br /&gt;
&amp;quot;sv&amp;quot;, &amp;quot;th&amp;quot;, &amp;quot;tr&amp;quot;];&lt;br /&gt;
  &lt;br /&gt;
//Functions&lt;br /&gt;
//Takes in the offsets, and the attach point &lt;br /&gt;
vector fn_makePos(integer attach_point, vector offset) {&lt;br /&gt;
    if ((attach_point == 31) || (attach_point == 35)) { //center 2 &amp;amp; center        &lt;br /&gt;
        return &amp;lt;0,0,0&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 32) { // Top right&lt;br /&gt;
        return &amp;lt;offset.x, offset.y, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 33) { // Top&lt;br /&gt;
        return &amp;lt;offset.x, 0, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 34) { // Top Left&lt;br /&gt;
        return &amp;lt;offset.x, offset.y * -1, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 36) { // Bottom Left&lt;br /&gt;
        return &amp;lt;offset.x, offset.y * -1 , offset.z&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 37) { // Bottom&lt;br /&gt;
        return &amp;lt;offset.x, 0, offset.z&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 38) { // Bottom Right - Baseline&lt;br /&gt;
        return offset;&lt;br /&gt;
    } else { //Not a HUD point? Then return it&#039;s current pos&lt;br /&gt;
        return llGetLocalPos();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
updateDisplay()&lt;br /&gt;
{&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer listLength;&lt;br /&gt;
    integer x;&lt;br /&gt;
    string  agentName;&lt;br /&gt;
    &lt;br /&gt;
    if (isInitialized == FALSE) return;&lt;br /&gt;
    tempString = &amp;quot;Universal Translator&amp;quot;;&lt;br /&gt;
    if (isMaster != 1)&lt;br /&gt;
        tempString += &amp;quot; (Link-&amp;quot; + (string)(translatorCount + 1) + &amp;quot;)&amp;quot;;&lt;br /&gt;
    tempString += &amp;quot;\n===============&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (enabled) &lt;br /&gt;
    {&lt;br /&gt;
        listLength = llGetListLength(agentsInTranslation);&lt;br /&gt;
        if (((showAgents) &amp;amp;&amp;amp; (listLength &amp;lt;= 40)) &amp;amp;&amp;amp; (listLength != 0))&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; listLength; x += 4)&lt;br /&gt;
            {&lt;br /&gt;
                agentName = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_NAME]), 0);&lt;br /&gt;
                if (llStringLength(agentName) &amp;gt; 25)&lt;br /&gt;
                    agentName = llGetSubString(agentName, 0, 24);&lt;br /&gt;
                if (agentName != &amp;quot;&amp;quot;)&lt;br /&gt;
                    tempString += &amp;quot;\n&amp;quot; + agentName + &amp;quot;(&amp;quot; + llList2String(agentsInTranslation, x + 1) + &amp;quot;)&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            tempString += &amp;quot;\n# Agents Translated: &amp;quot; + (string)llRound(listLength/3);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        tempString += &amp;quot;\n&amp;gt;&amp;gt; Disabled &amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (llMD5String(tempString, 0) != displayStringMD5)&lt;br /&gt;
    {&lt;br /&gt;
        displayStringMD5 = llMD5String(tempString, 0);&lt;br /&gt;
        llSetText(tempString, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showMainMenu(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (isInitialized == FALSE) return;&lt;br /&gt;
    integer avatarParticipating;&lt;br /&gt;
    list buttonList = [&amp;quot;Language&amp;quot;, &amp;quot;Help&amp;quot;];&lt;br /&gt;
    string dialogMsg = &amp;quot;Main Menu\nLANGUAGE: manually choose your source language. Target languages are detected automatically\nHELP: get help notecard&amp;quot;;&lt;br /&gt;
    buttonList += &amp;quot;FREE Copy&amp;quot;;&lt;br /&gt;
    dialogMsg += &amp;quot;\nFREE COPY: receive FREE copy of Universal Translator.&amp;quot;; &lt;br /&gt;
     &lt;br /&gt;
    if (llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [(string)id]) + 1) != &amp;quot;xx&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Opt-Out&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nOPT-OUT: disable receipt of translations&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Opt-In&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nOPT-IN: join the translations&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Donate&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nDONATE: donate L$ to the developer of Universal Translator.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Reset&amp;quot;;&lt;br /&gt;
        buttonList += &amp;quot;Options&amp;quot;;&lt;br /&gt;
        buttonList += &amp;quot;Send Copy&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nSEND COPY: send FREE copy of Universal Translator.&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        if (enabled)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Disable&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Enable&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        dialogMsg += &amp;quot;\nRESET: reset all scripts in translator&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llDialog(id, dialogMsg, buttonList, randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showOptionsMenu(key id)&lt;br /&gt;
{&lt;br /&gt;
    integer avatarParticipating;&lt;br /&gt;
    list buttonList = [];&lt;br /&gt;
    string dialogMsg = &amp;quot;Options Menu.&amp;quot;;&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        if (groupAccess)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Group OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Group ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nGROUP: allow group members to admin.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Main Menu&amp;quot;;&lt;br /&gt;
        if (!deviceAttached)&lt;br /&gt;
        {&lt;br /&gt;
            if (autoLanguage)&lt;br /&gt;
            {&lt;br /&gt;
                buttonList += &amp;quot;Scan OFF&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                buttonList += &amp;quot;Scan ON&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nSCAN: scan for Avatars and automatically add to translation matrix.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (isShowTran)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Echo OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Echo ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nECHO: show translations of your chat sent to others.&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        if (tranObjects)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Objects OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Objects ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nOBJECTS: translate chat of scripted objects&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        if (showAgents)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Agents OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Agents ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nAGENTS: show list of agents translated.&amp;quot;; &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llDialog(id, dialogMsg, buttonList, randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showLanguageDialog1(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language...&amp;quot;, [&amp;quot;\t&amp;quot;, &amp;quot;\t&amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT&amp;quot;] + llList2List(languages, 0, 8),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog2(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK&amp;quot;, &amp;quot;\t &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT &amp;quot;] + llList2List(languages, 9, 17),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog3(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK &amp;quot;, &amp;quot;\t  &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT  &amp;quot;] + llList2List(languages, 18, 26),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog4(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK  &amp;quot;, &amp;quot;\t   &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT   &amp;quot;] + llList2List(languages, 27, 35),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog5(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK   &amp;quot;, &amp;quot;\t    &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT    &amp;quot;] + llList2List(languages, 36, 44),  randomDialogChannel);&lt;br /&gt;
}showLanguageDialog6(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK    &amp;quot;, &amp;quot;\t     &amp;quot;, &amp;quot;\t     &amp;quot;] + llList2List(languages, 45, 53),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
processListen(string name, key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    key listenKey;&lt;br /&gt;
    &lt;br /&gt;
    if (llListFindList(languages, [message]) &amp;gt; -1) //Language Selected in Dialog&lt;br /&gt;
    {&lt;br /&gt;
        if (message != &amp;quot;&amp;quot;) llMessageLinked(LINK_THIS, 9384610, llList2String(languageCodes, llListFindList(languages, [message])), id);&lt;br /&gt;
    }    &lt;br /&gt;
    else if (llToLower(message) == &amp;quot;help&amp;quot;) &lt;br /&gt;
    {&lt;br /&gt;
        llGiveInventory(id, &amp;quot;Universal Translator Help&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Main Menu&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showMainMenu(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Options&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showOptionsMenu(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Language&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Opt-In&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Opt-Out&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 9384610, &amp;quot;xx&amp;quot;, id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;FREE Copy&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 9455209, llKey2Name(id), id);&lt;br /&gt;
    }&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        if (message == &amp;quot;Group ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            groupAccess = TRUE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Group OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            groupAccess = FALSE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Donate&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, 324235353254, &amp;quot;&amp;quot;, llGetOwner());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        if (message == &amp;quot;Reset&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
           llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Enable&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            enabled  = TRUE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Disable&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            enabled  = FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Echo ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            isShowTran = TRUE;&lt;br /&gt;
            //llMessageLinked(LINK_THIS, 2734322, (string)isShowTran, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Echo OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            isShowTran = FALSE;&lt;br /&gt;
       }&lt;br /&gt;
        else if (message == &amp;quot;Objects OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            tranObjects = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Objects ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            tranObjects = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Agents OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 455832, (string)showAgents, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Agents ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = TRUE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 455832, (string)showAgents, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Scan ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            autoLanguage  = TRUE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Scan OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            autoLanguage = FALSE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if ((message == &amp;quot;Send Copy&amp;quot;) || (message == &amp;quot;&amp;gt;&amp;gt;RESCAN&amp;lt;&amp;lt;&amp;quot;))&lt;br /&gt;
        {        &lt;br /&gt;
            agentInDialog = id;&lt;br /&gt;
            llSensor(&amp;quot;&amp;quot;, NULL_KEY, AGENT, 20.0, TWO_PI);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetListLength(detectedAgentNameList) &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                listenKey = llList2Key(detectedAgentKeyList, llListFindList(detectedAgentNameList, [message]));&lt;br /&gt;
                if (listenKey != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, 9455209, message, listenKey);&lt;br /&gt;
                }&lt;br /&gt;
                detectedAgentNameList = [];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (message == &amp;quot;&amp;gt;&amp;gt; NEXT&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog6(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    if (message == &amp;quot;\t&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t     &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog6(id);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), id);&lt;br /&gt;
}&lt;br /&gt;
checkAttach()&lt;br /&gt;
{&lt;br /&gt;
    if (llGetAttached() &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        llSetScale(&amp;lt;0.125, 0.125, 0.087&amp;gt;);&lt;br /&gt;
        if(lastAttachPoint != llGetAttached())&lt;br /&gt;
        {&lt;br /&gt;
            llSetPos(fn_makePos(llGetAttached(), &amp;lt;0.00000, 0.13500, 0.15433&amp;gt;));&lt;br /&gt;
            llSetRot(&amp;lt;0,0,0,1&amp;gt;);&lt;br /&gt;
            lastAttachPoint = llGetAttached();                &lt;br /&gt;
        }&lt;br /&gt;
        llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);&lt;br /&gt;
        llMessageLinked(llGetLinkNumber(), 3792114, (string)TRUE, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llSetScale(&amp;lt;0.5, 0.5, 0.750&amp;gt;);&lt;br /&gt;
        llReleaseControls();&lt;br /&gt;
        llMessageLinked(llGetLinkNumber(), 3792114, (string)FALSE, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    run_time_permissions(integer perms)&lt;br /&gt;
    {&lt;br /&gt;
        //integer hasPerms = llGetPermissions();&lt;br /&gt;
        llTakeControls( CONTROL_UP , TRUE, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        //llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS );&lt;br /&gt;
        &lt;br /&gt;
        string speakerLanguage;&lt;br /&gt;
        //llOwnerSay(&amp;quot;Welcome to the Universal Translator, the best FREE translator in SL! Please consider making a L$ donation to help with maintenance and further updates. Select DONATE in the translator menu to make a donation.&amp;quot;);&lt;br /&gt;
        //llSetText(&amp;quot;Initializing...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
    &lt;br /&gt;
        llSetText(&amp;quot;Searching for\nnearby translators...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
        checkAttach();&lt;br /&gt;
        &lt;br /&gt;
        randomDialogChannel = -(integer)llFrand(2147483647);&lt;br /&gt;
&lt;br /&gt;
        llMessageLinked(LINK_SET, 20957454, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Universal Translator Engine&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;HTTP Handler&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;No-Script IM Handler&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Auto-Update&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Donation&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        //Other Setup&lt;br /&gt;
        llSleep(5);&lt;br /&gt;
        llListen(randomDialogChannel, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), &amp;quot;&amp;quot;);        &lt;br /&gt;
&lt;br /&gt;
        //llOwnerSay(&amp;quot;Mem Free=&amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer startup_param)&lt;br /&gt;
    {&lt;br /&gt;
        //checkAttach();&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    sensor(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        &lt;br /&gt;
        if (num_detected &amp;gt; 11)&lt;br /&gt;
            num_detected = 11;&lt;br /&gt;
        &lt;br /&gt;
        detectedAgentKeyList = [];&lt;br /&gt;
        detectedAgentNameList = [];&lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x += 1)&lt;br /&gt;
        {&lt;br /&gt;
             detectedAgentKeyList += llDetectedKey(x);&lt;br /&gt;
             tempString = llDetectedName(x);&lt;br /&gt;
             if (llStringLength(tempString) &amp;gt; 24) tempString = llGetSubString(tempString, 0, 23);&lt;br /&gt;
             detectedAgentNameList += tempString;&lt;br /&gt;
        }&lt;br /&gt;
        if (llGetListLength(detectedAgentNameList) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(agentInDialog, &amp;quot;Select someone nearby to receive FREE a copy of the Universal Translator...&amp;quot;, [&amp;quot;&amp;gt;&amp;gt;RESCAN&amp;lt;&amp;lt;&amp;quot;] + detectedAgentNameList, randomDialogChannel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        &lt;br /&gt;
        if (num == 2540664)&lt;br /&gt;
        {&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3792114)&lt;br /&gt;
        {&lt;br /&gt;
            deviceAttached = (integer)str;&lt;br /&gt;
            if (deviceAttached) autoLanguage = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 65635544)&lt;br /&gt;
        {&lt;br /&gt;
            translatorCount = ((integer)str)/2;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 6877259)&lt;br /&gt;
        {&lt;br /&gt;
            if (isInitialized == FALSE)&lt;br /&gt;
            {&lt;br /&gt;
                isInitialized = TRUE;&lt;br /&gt;
                //Owner Language Detection&lt;br /&gt;
                tempString  = llGetAgentLanguage(llGetOwner());&lt;br /&gt;
                if (llGetSubString(tempString, 0, 1) == &amp;quot;en&amp;quot;) tempString = &amp;quot;en&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                if (tempString == &amp;quot;&amp;quot;) &lt;br /&gt;
                {&lt;br /&gt;
                    tempString = &amp;quot;en&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
                llMessageLinked(LINK_THIS, 9384610, tempString, llGetOwner());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
          enabled = (integer)str; //marker&lt;br /&gt;
          updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 34829304)&lt;br /&gt;
        {&lt;br /&gt;
            isMaster = (integer)str;&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 455832)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = (integer)str;&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 94558323)&lt;br /&gt;
        {&lt;br /&gt;
            agentsInTranslation = llCSV2List(str);&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3342977)&lt;br /&gt;
        {&lt;br /&gt;
            //Options are Show Tran and tranObjects at this time&lt;br /&gt;
            tempList = llCSV2List(str);&lt;br /&gt;
            isShowTran = llList2Integer(tempList, 0);&lt;br /&gt;
            tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
            autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
       }&lt;br /&gt;
        else if (num == 32364364)&lt;br /&gt;
        {&lt;br /&gt;
            //Send Options&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        key avatarKey;&lt;br /&gt;
        &lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x++)&lt;br /&gt;
        {&lt;br /&gt;
            avatarKey = llDetectedKey(x);&lt;br /&gt;
            showMainMenu(avatarKey);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {                &lt;br /&gt;
        processListen(name, id, message);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    attach(key id)&lt;br /&gt;
    {&lt;br /&gt;
        checkAttach();&lt;br /&gt;
        if (id) //tests if it is a valid key and not NULL_KEY&lt;br /&gt;
        {&lt;br /&gt;
            llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    control(key id,integer held, integer change) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Universal_Translator&amp;diff=1072682</id>
		<title>Universal Translator</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Universal_Translator&amp;diff=1072682"/>
		<updated>2010-10-25T16:13:23Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Removed extraneous character that caused syntax error on script save&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
This is the complete source code to the widely popular and free &amp;quot;HR Universal Translator&amp;quot; by [[Hank Ramos]].  This device is a dynamic public chat listener that automatically translates between 50+ languages and delivers translations of spoken text to those nearby that don&#039;t speak the language of the original speaker.&lt;br /&gt;
&lt;br /&gt;
Please help to further development on this open-source project. &lt;br /&gt;
&lt;br /&gt;
== Future Upgrades Needed ==&lt;br /&gt;
1. Support for Google Spellcheck.  Would be great to be able to spell-check chat first, and automatically do suggested corrections before the translation.&lt;br /&gt;
&lt;br /&gt;
2. Break the engine script into two or more scripts to allow for future expansion and to be able to handle low memory situations better.&lt;br /&gt;
&lt;br /&gt;
3. Support pseudo-instant message.  This could be done with avatars wearing the device within 100m of each others, or could be done world-wide using email or some other communications mechanism. Avatars would chat on a hidden channel, and would be able to communicate with another avatar or group chat.  Would require inworld servers of prims to link translators up together and find one another.&lt;br /&gt;
&lt;br /&gt;
4. Ensure that unicode is supported correctly.  Ensure that Right-to-Left languages are input and output correctly.  May need additional options since the SL client doesn&#039;t support this correctly and sometimes people speak backwards into SL chat to get around this.&lt;br /&gt;
&lt;br /&gt;
5. Rework auto-detection of language code. Should only automatically change the avatar&#039;s language if it is reliably predicted that they have changed languages.&lt;br /&gt;
&lt;br /&gt;
6. Add in automatic &amp;quot;spam&amp;quot; detection and prevent translation.  Find way to detect gesture &amp;quot;chat spam&amp;quot; and filter that out from the translation.  Filter out bad translations that only return the same or similar input.  Support replacement of common abbreviations or slang so that the google translation system can translate correctly.  May require support of a user-definable dictionary notecard.&lt;br /&gt;
&lt;br /&gt;
7. Handle translation errors from Google and resubmit the translation, rather than just ignoring it.&lt;br /&gt;
&lt;br /&gt;
8. Can you think of other improvements?&lt;br /&gt;
&lt;br /&gt;
= The Code =&lt;br /&gt;
The device consists of 3 key scripts, with several ancillary scripts to function.  The key scripts are listed here...&lt;br /&gt;
&lt;br /&gt;
==Universal Translator Engine==&lt;br /&gt;
This is the &amp;quot;heart&amp;quot; of the translator.  It handles communications with other translators, handles listening to avatars for chat, and handles most of the HTTP traffic.&lt;br /&gt;
&lt;br /&gt;
How do multiple translators communicate?  There are two chat channels at work...&lt;br /&gt;
&lt;br /&gt;
The heartbeat channel: this channel is fixed and common amongst all Universal Translators.  This is where each translator regularly announces its presence to other translators in the area.  If another one is found, a &amp;quot;master&#039; translator is elected at random (with higher version releases of the translators getting higher values).  The master translator is in charge of listening to all chat, and sending text to be translated and IMed to the recipient to the other &amp;quot;slave&amp;quot; translators.  &lt;br /&gt;
&lt;br /&gt;
Unique translator channel: each translator will select it&#039;s own channel to listen for incoming translations.  This serves as a unique conduit for the master translator to communicate with each individual slave.  This allows the heartbeat channel to be free for command messages to be sent, since the translated text being passed around can quickly saturate it.&lt;br /&gt;
&lt;br /&gt;
This multi-translator communication might be useful in other scripting projects.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//Universal Translator&lt;br /&gt;
//Version 1.9.0&lt;br /&gt;
//November 12, 2009&lt;br /&gt;
//LSL Script copyright 2006-2009 by Hank Ramos&lt;br /&gt;
//Web Server Services powered by Google&lt;br /&gt;
&lt;br /&gt;
//Variables&lt;br /&gt;
list agentsInTranslation;&lt;br /&gt;
list agentsInTranslationOptions;&lt;br /&gt;
list requestList;&lt;br /&gt;
integer listenID;&lt;br /&gt;
&lt;br /&gt;
integer isMaster = 1;&lt;br /&gt;
integer autoLanguage = TRUE;&lt;br /&gt;
integer enabled = FALSE;&lt;br /&gt;
integer showTranslation = FALSE;&lt;br /&gt;
integer tranObjects = TRUE;&lt;br /&gt;
&lt;br /&gt;
integer lastHeartBeat;&lt;br /&gt;
list    languageCodes = [&lt;br /&gt;
&amp;quot;zh-CN&amp;quot;, &amp;quot;zh-TW&amp;quot;, &amp;quot;hr&amp;quot;,  &lt;br /&gt;
&amp;quot;bg&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;ca&amp;quot;,&lt;br /&gt;
&amp;quot;af&amp;quot;, &amp;quot;sq&amp;quot;, &amp;quot;ar&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;tl&amp;quot;, &amp;quot;fr&amp;quot;, &amp;quot;gl&amp;quot;,    &lt;br /&gt;
&amp;quot;fi&amp;quot;, &amp;quot;en&amp;quot;, &amp;quot;et&amp;quot;,     &lt;br /&gt;
&amp;quot;cs&amp;quot;, &amp;quot;da&amp;quot;, &amp;quot;nl&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;id&amp;quot;, &amp;quot;ga&amp;quot;, &amp;quot;it&amp;quot;,      &lt;br /&gt;
&amp;quot;hi&amp;quot;, &amp;quot;hu&amp;quot;, &amp;quot;is&amp;quot;, &lt;br /&gt;
&amp;quot;de&amp;quot;, &amp;quot;el&amp;quot;, &amp;quot;iw&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;mt&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;fa&amp;quot;,   &lt;br /&gt;
&amp;quot;lt&amp;quot;, &amp;quot;mk&amp;quot;, &amp;quot;ms&amp;quot;,   &lt;br /&gt;
&amp;quot;ja&amp;quot;, &amp;quot;ko&amp;quot;, &amp;quot;lv&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;sl&amp;quot;, &amp;quot;es&amp;quot;, &amp;quot;sw&amp;quot;, &lt;br /&gt;
&amp;quot;ru&amp;quot;, &amp;quot;sr&amp;quot;, &amp;quot;sk&amp;quot;, &lt;br /&gt;
&amp;quot;pl&amp;quot;, &amp;quot;pt-PT&amp;quot;, &amp;quot;ro&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;yi&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
&amp;quot;uk&amp;quot;, &amp;quot;vi&amp;quot;, &amp;quot;cy&amp;quot;,&lt;br /&gt;
&amp;quot;sv&amp;quot;,&amp;quot;th&amp;quot;, &amp;quot;tr&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
list    translators;&lt;br /&gt;
list    sayCache;&lt;br /&gt;
list    sayCachePrivate;&lt;br /&gt;
integer priorityNumber;&lt;br /&gt;
integer priorityNumListenID;&lt;br /&gt;
integer isInitialized = FALSE;&lt;br /&gt;
string  options;&lt;br /&gt;
&lt;br /&gt;
//Options&lt;br /&gt;
//integer debug = TRUE;&lt;br /&gt;
integer broadcastChannel = -9999999; //note this is not the channel used by the HR Universal Translator&lt;br /&gt;
string  password = &amp;quot;password&amp;quot;; //note this is not the password used to encrypt comms of the HR Universal Translator&lt;br /&gt;
integer version = 190;&lt;br /&gt;
sendIM(key id, string str)&lt;br /&gt;
{&lt;br /&gt;
    if (llGetParcelFlags(llGetPos()) &amp;amp; PARCEL_FLAG_ALLOW_SCRIPTS)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 85234119, str, id); &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 85304563, str, id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sendTextBatch(integer channel, string sendText)&lt;br /&gt;
{&lt;br /&gt;
    sendText = llXorBase64StringsCorrect(llStringToBase64(sendText), llStringToBase64(password));;&lt;br /&gt;
    while (llStringLength(sendText) &amp;gt; 508) //If string is 509 characters or longer &lt;br /&gt;
    {&lt;br /&gt;
        llSay(channel, llGetSubString(sendText, 0, 507)); //send 508 character chunk&lt;br /&gt;
        sendText = llGetSubString(sendText, 508, -1);  //delete 508 character chunk&lt;br /&gt;
    }&lt;br /&gt;
    llSay(channel, sendText);  //send out any remainder chunk or original chunk&lt;br /&gt;
    if (llStringLength(sendText) == 508)&lt;br /&gt;
        llSay(channel, (string)(channel*4958654));&lt;br /&gt;
    llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0, 0.25&amp;gt;, &amp;quot;&amp;quot;); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string receiveTextBatch(key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    string  tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    listPos = llListFindList(sayCache, [id]);&lt;br /&gt;
    if (listPos &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPos &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            tempString = tempString + llList2String(sayCache, listPos + 1);&lt;br /&gt;
            sayCache = llDeleteSubList(sayCache, listPos, listPos + 1);&lt;br /&gt;
            listPos = llListFindList(sayCache, [id]);&lt;br /&gt;
        }&lt;br /&gt;
        message = tempString + message;&lt;br /&gt;
    }&lt;br /&gt;
    message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password)));&lt;br /&gt;
    return message;&lt;br /&gt;
}&lt;br /&gt;
string receiveTextBatchPrivate(key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    string  tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    listPos = llListFindList(sayCachePrivate, [id]);&lt;br /&gt;
    if (listPos &amp;gt;= 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPos &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            tempString = tempString + llList2String(sayCachePrivate, listPos + 1);&lt;br /&gt;
            sayCachePrivate = llDeleteSubList(sayCachePrivate, listPos, listPos + 1);&lt;br /&gt;
            listPos = llListFindList(sayCachePrivate, [id]);&lt;br /&gt;
        }&lt;br /&gt;
        message = tempString + message;&lt;br /&gt;
    }&lt;br /&gt;
    message = llBase64ToString(llXorBase64StringsCorrect(message, llStringToBase64(password)));&lt;br /&gt;
    return message;&lt;br /&gt;
}&lt;br /&gt;
updateTranslatorList()&lt;br /&gt;
{&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer listLength;&lt;br /&gt;
    list    newList;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer newMaster;&lt;br /&gt;
    &lt;br /&gt;
    //Scan and remove translators not in the area&lt;br /&gt;
    for (x = 0; x &amp;lt; llGetListLength(translators); x += 2)&lt;br /&gt;
    {&lt;br /&gt;
        tempString = llList2String(llGetObjectDetails(llList2Key(translators, x + 1), [OBJECT_POS]), 0);&lt;br /&gt;
        if ((llVecDist(llGetPos(), (vector)tempString) &amp;lt;= 20.0) &amp;amp;&amp;amp; (tempString != &amp;quot;&amp;quot;))&lt;br /&gt;
            newList += llList2List(translators, x, x + 1);&lt;br /&gt;
    }&lt;br /&gt;
    translators = newList;&lt;br /&gt;
&lt;br /&gt;
    listLength = llGetListLength(translators);&lt;br /&gt;
    llMessageLinked(LINK_THIS, 65635544, (string)listLength, &amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (listLength == 0)&lt;br /&gt;
    {&lt;br /&gt;
        newMaster = 1;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (enabled)&lt;br /&gt;
        {&lt;br /&gt;
            newMaster = 2;&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(translators); x += 2)&lt;br /&gt;
            {&lt;br /&gt;
                //llOwnerSay(&amp;quot;Checking Priority Number(&amp;quot; +  (string)priorityNumber + &amp;quot;): &amp;quot; + (string)llList2Integer(translators, x));&lt;br /&gt;
                if (llList2Integer(translators, x) &amp;gt; priorityNumber)&lt;br /&gt;
                {&lt;br /&gt;
                    newMaster = 0;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            newMaster = 0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ((isMaster &amp;gt; 0) &amp;amp;&amp;amp; (newMaster == 0))&lt;br /&gt;
    {&lt;br /&gt;
        //We are being demoted from master to slave&lt;br /&gt;
        //Flush agentsInTranslation to master&lt;br /&gt;
        if (llGetListLength(agentsInTranslation) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            //Demotion Dump of agentsInTranslation to Master&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1003, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
            if (isInitialized == FALSE) return;&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1004, options])); //error&lt;br /&gt;
        }&lt;br /&gt;
        llListenRemove(listenID);&lt;br /&gt;
    }&lt;br /&gt;
    if ((isMaster == 0) &amp;amp;&amp;amp; (newMaster &amp;gt; 0))&lt;br /&gt;
    {&lt;br /&gt;
        llListenRemove(listenID);&lt;br /&gt;
        listenID = llListen(0, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;); &lt;br /&gt;
    }&lt;br /&gt;
    isMaster = newMaster;&lt;br /&gt;
    llMessageLinked(LINK_THIS, 34829304, (string)isMaster, &amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
sendHeartbeat()&lt;br /&gt;
{&lt;br /&gt;
    updateTranslatorList();&lt;br /&gt;
    sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber]));&lt;br /&gt;
&lt;br /&gt;
    //Broadcast agentList to Slaves&lt;br /&gt;
    if (isMaster == 2)&lt;br /&gt;
    {&lt;br /&gt;
        sendTextBatch(broadcastChannel, llList2CSV([1002, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Functions&lt;br /&gt;
checkThrottle(integer num, string msg, list params)&lt;br /&gt;
{&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer maxCount;&lt;br /&gt;
    float   oldTime;&lt;br /&gt;
    float   sleepTime;&lt;br /&gt;
    list    newList;&lt;br /&gt;
    key     returnValue;&lt;br /&gt;
    integer channelToSpeak;&lt;br /&gt;
    &lt;br /&gt;
    //loop though list and remove items older than 25 seconds&lt;br /&gt;
    for (x = 0; x &amp;lt; llGetListLength(requestList); x += 1)&lt;br /&gt;
    {&lt;br /&gt;
        oldTime = llList2Float(requestList, x);&lt;br /&gt;
        //Construct new list with only times less than 25 seconds&lt;br /&gt;
        if ((llGetTime() - oldTime) &amp;lt;= 25.0) &lt;br /&gt;
            newList += oldTime;&lt;br /&gt;
    }&lt;br /&gt;
    requestList = newList;&lt;br /&gt;
    &lt;br /&gt;
    x = llGetListLength(requestList);&lt;br /&gt;
    &lt;br /&gt;
    //Shunt all translations to linked translators if master&lt;br /&gt;
    if (isMaster == 2)&lt;br /&gt;
    {&lt;br /&gt;
        if (num == 0)&lt;br /&gt;
        {&lt;br /&gt;
            //Send HTTP request to other translator&lt;br /&gt;
            //Send out Request to Random Translator Channel&lt;br /&gt;
&lt;br /&gt;
            channelToSpeak = llList2Integer(llListRandomize(llList2ListStrided(translators, 0, -1, 2), 1), 0);&lt;br /&gt;
            if (channelToSpeak &amp;gt; 0) &lt;br /&gt;
            {&lt;br /&gt;
                sendTextBatch(channelToSpeak, llList2CSV([num, llList2CSV(params)]) + &amp;quot;~&amp;quot; + msg);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (x == 19)&lt;br /&gt;
    {&lt;br /&gt;
        sleepTime =  25.0 - (llGetTime() - llList2Float(requestList, 0));&lt;br /&gt;
        if (sleepTime &amp;gt; 0) &lt;br /&gt;
        {&lt;br /&gt;
            llSleep(sleepTime);&lt;br /&gt;
        }&lt;br /&gt;
        requestList = llDeleteSubList(requestList, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (num == 0)&lt;br /&gt;
    {&lt;br /&gt;
        msg = &amp;quot;translate?v=1.0&amp;amp;q=&amp;quot; + msg;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
        msg = &amp;quot;detect?v=1.0&amp;amp;q=&amp;quot; + msg;&lt;br /&gt;
&lt;br /&gt;
    requestList += llGetTime();&lt;br /&gt;
    returnValue = llHTTPRequest(&amp;quot;http://ajax.googleapis.com/ajax/services/language/&amp;quot; + msg, [HTTP_METHOD, &amp;quot;GET&amp;quot;, HTTP_MIMETYPE, &amp;quot;plain/text;charset=utf-8&amp;quot;], &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    if (returnValue != NULL_KEY)&lt;br /&gt;
    {&lt;br /&gt;
        if (num == 0)&lt;br /&gt;
            llMessageLinked(LINK_THIS, 235365342, llList2CSV(params), returnValue); &lt;br /&gt;
        else&lt;br /&gt;
            llMessageLinked(LINK_THIS, 235365343, llList2CSV(params), returnValue); &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llSleep(40.0); //Something has gone horribly wrong, sleep 40 seconds to clear throttle&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string checkLanguage(string tempString)&lt;br /&gt;
{&lt;br /&gt;
    if      (llGetSubString(tempString, 0, 1) == &amp;quot;zh&amp;quot;)    tempString = &amp;quot;zh-CN&amp;quot;;&lt;br /&gt;
    else if (tempString == &amp;quot;und&amp;quot;)   tempString = &amp;quot;el&amp;quot;;&lt;br /&gt;
    else if (llListFindList(languageCodes, [tempString]) &amp;lt; 0) tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
    tempString = llGetSubString(tempString, 0, 1);&lt;br /&gt;
    return tempString;&lt;br /&gt;
}&lt;br /&gt;
addAgent(key id, string language, integer recheckLangauge)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    integer listPosID;&lt;br /&gt;
    integer idNum;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
&lt;br /&gt;
    listPos = llListFindList(agentsInTranslation, [id]);&lt;br /&gt;
    if (listPos &amp;lt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        while (listPosID &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            idNum = llRound(llFrand(2000000)) + 1;&lt;br /&gt;
            listPosID = llListFindList(agentsInTranslation, [idNum]);&lt;br /&gt;
        }&lt;br /&gt;
        agentsInTranslation += [id, language, recheckLangauge, idNum];&lt;br /&gt;
        llMessageLinked(LINK_THIS, 64562349, language, id);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
        agentsInTranslation = llListReplaceList(agentsInTranslation, [language, recheckLangauge], listPos + 1, listPos + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
string addNewAgent(key id)&lt;br /&gt;
{&lt;br /&gt;
    string speakerLanguage;&lt;br /&gt;
    &lt;br /&gt;
    if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY)&lt;br /&gt;
    {&lt;br /&gt;
        speakerLanguage  = checkLanguage(llGetAgentLanguage(id));&lt;br /&gt;
        if (speakerLanguage == &amp;quot;&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            speakerLanguage = &amp;quot;en&amp;quot;;&lt;br /&gt;
            addAgent(id, speakerLanguage, TRUE);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            addAgent(id, speakerLanguage, FALSE);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return speakerLanguage;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
key getAgentKey(integer agentID)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos = llListFindList(agentsInTranslation, [agentID]);&lt;br /&gt;
    if (listPos &amp;lt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2Key(agentsInTranslation, listPos - 3);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
processHTTPResponse(integer type, string body, list params)&lt;br /&gt;
{&lt;br /&gt;
    integer listPos;&lt;br /&gt;
    list    recepientList;&lt;br /&gt;
    key     recepientID;&lt;br /&gt;
    string  recepientLanguage;&lt;br /&gt;
    string  languagePair;&lt;br /&gt;
    key     speakerID;&lt;br /&gt;
    string  speakerName;&lt;br /&gt;
    string  speakerLanguage;&lt;br /&gt;
    string  translatedText;&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer x;&lt;br /&gt;
    integer speakerLanguageReliable;&lt;br /&gt;
    float   speakerLanguageConfidence;&lt;br /&gt;
    list    tempList;&lt;br /&gt;
    &lt;br /&gt;
    //===================&lt;br /&gt;
    //Process Translation&lt;br /&gt;
    //===================&lt;br /&gt;
    if (type == 0)&lt;br /&gt;
    {&lt;br /&gt;
        speakerID  = llList2Key(params, 1);&lt;br /&gt;
        speakerName = llKey2Name(speakerID);&lt;br /&gt;
        if (speakerName == &amp;quot;&amp;quot;)&lt;br /&gt;
            speakerName = llList2String(llGetObjectDetails(speakerID, [OBJECT_NAME]), 0);&lt;br /&gt;
        &lt;br /&gt;
        recepientList = llParseString2List(llList2String(params, 2), [&amp;quot;@&amp;quot;], []);&lt;br /&gt;
        tempList = llParseStringKeepNulls(llList2String(params, 3), [&amp;quot;|&amp;quot;],[]);&lt;br /&gt;
        recepientLanguage = llList2String(tempList, 1);&lt;br /&gt;
        languagePair = llDumpList2String(tempList, &amp;quot;&amp;gt;&amp;gt;&amp;quot;); &lt;br /&gt;
        &lt;br /&gt;
        //Perform Text Cleanup&lt;br /&gt;
        x = llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;detectedSourceLanguage\&amp;quot;:\&amp;quot;&amp;quot;); &lt;br /&gt;
        if (x &amp;gt;= 0)&lt;br /&gt;
        {&lt;br /&gt;
            translatedText  = llGetSubString(body,  llSubStringIndex(body, &amp;quot;{\&amp;quot;translatedText\&amp;quot;:\&amp;quot;&amp;quot;) + 18, x);&lt;br /&gt;
            speakerLanguage = checkLanguage(llGetSubString(body, x + 28, llSubStringIndex(body, &amp;quot;\&amp;quot;}, \&amp;quot;responseDetails\&amp;quot;:&amp;quot;) - 1));&lt;br /&gt;
            &lt;br /&gt;
            listPos = llListFindList(agentsInTranslation, [speakerID]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                if (speakerLanguage != llList2String(agentsInTranslation, listPos + 1))&lt;br /&gt;
                    agentsInTranslation = llListReplaceList(agentsInTranslation, [TRUE], listPos + 2, listPos + 2);  //Mark for recheck of actual spoken language.&lt;br /&gt;
            }                   &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            translatedText = llGetSubString(body, llSubStringIndex(body, &amp;quot;{\&amp;quot;translatedText\&amp;quot;:\&amp;quot;&amp;quot;) + 18, llSubStringIndex(body, &amp;quot;\&amp;quot;}, \&amp;quot;responseDetails\&amp;quot;&amp;quot;));&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Reverse order if Recepient Language is Hebrew or Arabic&lt;br /&gt;
        if ((recepientLanguage == &amp;quot;iw&amp;quot;) || (recepientLanguage == &amp;quot;ar&amp;quot;))&lt;br /&gt;
        {  &lt;br /&gt;
            tempString = &amp;quot;&amp;quot;;&lt;br /&gt;
            for(x = llStringLength(translatedText);x &amp;gt;= 0; x--)&lt;br /&gt;
            {&lt;br /&gt;
                tempString += llGetSubString(translatedText, x, x); &lt;br /&gt;
            }&lt;br /&gt;
            translatedText = tempString;&lt;br /&gt;
        }                    &lt;br /&gt;
        tempString = speakerName + &amp;quot;(&amp;quot; + languagePair + &amp;quot;): &amp;quot; + translatedText;&lt;br /&gt;
        if (showTranslation)&lt;br /&gt;
            sendIM(speakerID, tempString);  &lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(recepientList); x += 1)&lt;br /&gt;
        {&lt;br /&gt;
            recepientID = getAgentKey(llList2Integer(recepientList, x));&lt;br /&gt;
            &lt;br /&gt;
            if (recepientID != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                recepientLanguage = llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [recepientID]) + 1);&lt;br /&gt;
                if (recepientLanguage != speakerLanguage)&lt;br /&gt;
                    sendIM(recepientID, tempString);&lt;br /&gt;
            }  &lt;br /&gt;
        }&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //===========================&lt;br /&gt;
    //Process Language Detection&lt;br /&gt;
    //===========================&lt;br /&gt;
    if (type == 1)&lt;br /&gt;
    {&lt;br /&gt;
        speakerID = llList2Key(params, 1);&lt;br /&gt;
        &lt;br /&gt;
        speakerLanguageReliable = llToLower(llGetSubString(body, llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;isReliable\&amp;quot;:&amp;quot;) + 15, llSubStringIndex(body, &amp;quot;,\&amp;quot;confidence\&amp;quot;:&amp;quot;) - 1)) == &amp;quot;true&amp;quot;;&lt;br /&gt;
        speakerLanguageConfidence = (float)llGetSubString(body, llSubStringIndex(body, &amp;quot;,\&amp;quot;confidence\&amp;quot;:&amp;quot;) + 14, llSubStringIndex(body, &amp;quot;}, \&amp;quot;responseDetails\&amp;quot;:&amp;quot;) - 1);&lt;br /&gt;
        &lt;br /&gt;
        listPos = llListFindList(agentsInTranslation, [speakerID]);&lt;br /&gt;
&lt;br /&gt;
        if (((listPos &amp;lt; 0) &amp;amp;&amp;amp; (speakerLanguageReliable) || (speakerLanguageConfidence &amp;gt;= 0.18)))&lt;br /&gt;
        {&lt;br /&gt;
            //Analyze Data&lt;br /&gt;
            tempString = checkLanguage(llToLower(llGetSubString(body, llSubStringIndex(body, &amp;quot;{\&amp;quot;language\&amp;quot;:\&amp;quot;&amp;quot;) + 13, llSubStringIndex(body, &amp;quot;\&amp;quot;,\&amp;quot;isReliable\&amp;quot;:&amp;quot;) - 1)));&lt;br /&gt;
            if (tempString == &amp;quot;&amp;quot;) return;&lt;br /&gt;
            &lt;br /&gt;
            if (speakerLanguageConfidence &amp;lt; 0.14)&lt;br /&gt;
                addAgent(speakerID, tempString, TRUE);&lt;br /&gt;
            else&lt;br /&gt;
                addAgent(speakerID, tempString, FALSE);&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        //Multiplexor Initialization&lt;br /&gt;
        priorityNumber = version*1000000 + llRound(llFrand(499999) + 50000);&lt;br /&gt;
        llListen(broadcastChannel, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        priorityNumListenID = llListen(priorityNumber, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        //Send out initial heartbeat&lt;br /&gt;
        lastHeartBeat = llGetUnixTime();&lt;br /&gt;
        sendTextBatch(broadcastChannel, llList2CSV([1001, priorityNumber]));&lt;br /&gt;
        &lt;br /&gt;
        //Wait for the network to settle down&lt;br /&gt;
        llSetTimerEvent(5); &lt;br /&gt;
        //llSetTimerEvent(10 + ((1-llGetRegionTimeDilation()) * 1));       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    sensor(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        key     id;&lt;br /&gt;
&lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x += 1)&lt;br /&gt;
        {&lt;br /&gt;
            id = llDetectedKey(x);&lt;br /&gt;
            if (llListFindList(agentsInTranslation, [id]) &amp;lt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                addNewAgent(id);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        integer channelToSpeak;&lt;br /&gt;
        &lt;br /&gt;
        //Old Multiplexor&lt;br /&gt;
        if (num == 8434532)&lt;br /&gt;
        {&lt;br /&gt;
            enabled = (integer)str;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3342976)&lt;br /&gt;
        {&lt;br /&gt;
            //Send Preferences&lt;br /&gt;
            options = str;&lt;br /&gt;
            if (isInitialized == FALSE) return;&lt;br /&gt;
            tempList = llCSV2List(options);&lt;br /&gt;
            showTranslation = llList2Integer(tempList, 0);&lt;br /&gt;
            tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
            autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
            sendTextBatch(broadcastChannel, llList2CSV([1004, options]));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 9384610)&lt;br /&gt;
        {&lt;br /&gt;
            if (isMaster == 0) //markering&lt;br /&gt;
                //llMessageLinked(LINK_THIS, 5598321, llList2CSV([id, str, FALSE]), &amp;quot;&amp;quot;);&lt;br /&gt;
                sendTextBatch(broadcastChannel, llList2CSV([1003, id, str, FALSE]));&lt;br /&gt;
            else&lt;br /&gt;
                addAgent(id, str, TRUE);&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149625)&lt;br /&gt;
        {&lt;br /&gt;
            //Return Translation&lt;br /&gt;
            processHTTPResponse(0, str, llCSV2List(id));&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149626)&lt;br /&gt;
        {&lt;br /&gt;
            //Return Detection&lt;br /&gt;
            processHTTPResponse(1, str, llCSV2List(id));&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        list    newList;&lt;br /&gt;
        integer translatorCount = llGetListLength(translators)/2;&lt;br /&gt;
        &lt;br /&gt;
        if (isInitialized == FALSE)&lt;br /&gt;
        {&lt;br /&gt;
            isInitialized = TRUE;&lt;br /&gt;
            enabled = TRUE;&lt;br /&gt;
            listenID = llListen(0, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;); &lt;br /&gt;
            llListen(777, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
            llMessageLinked(LINK_THIS, 6877259, (string)enabled, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        llMessageLinked(LINK_THIS, 94558323, llList2CSV(agentsInTranslation), &amp;quot;&amp;quot;);&lt;br /&gt;
        if (isMaster &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(agentsInTranslation); x += 4)&lt;br /&gt;
            {&lt;br /&gt;
                tempString = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_POS]), 0);&lt;br /&gt;
                if ((llVecDist(llGetPos(), (vector)tempString) &amp;lt;= 20.0) &amp;amp;&amp;amp; (tempString != &amp;quot;&amp;quot;))&lt;br /&gt;
                    newList += llList2List(agentsInTranslation, x, x + 3);&lt;br /&gt;
            }&lt;br /&gt;
    &lt;br /&gt;
            agentsInTranslation = newList;&lt;br /&gt;
            if ((llGetUnixTime() - lastHeartBeat) &amp;gt;= 5)&lt;br /&gt;
            {&lt;br /&gt;
                //Send heartbeat&lt;br /&gt;
                sendHeartbeat();&lt;br /&gt;
                lastHeartBeat = llGetUnixTime();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if ((llGetUnixTime() - lastHeartBeat) &amp;gt;= 0 + llGetListLength(agentsInTranslation)*2 + llPow(translatorCount, 1.4) + translatorCount + ((1-llGetRegionTimeDilation()) * 5))&lt;br /&gt;
            {&lt;br /&gt;
                //Send heartbeat&lt;br /&gt;
                sendHeartbeat();&lt;br /&gt;
                lastHeartBeat = llGetUnixTime();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
                    &lt;br /&gt;
        //turn on and off scanner&lt;br /&gt;
        if ((autoLanguage) &amp;amp;&amp;amp; (isMaster &amp;gt; 0))&lt;br /&gt;
        {&lt;br /&gt;
            llSensor(&amp;quot;&amp;quot;, NULL_KEY, AGENT, 20.0, PI);&lt;br /&gt;
        }&lt;br /&gt;
        //llSetTimerEvent(4 + ((1-llGetRegionTimeDilation()) * 5));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  speakerLanguage;&lt;br /&gt;
        string  recepientLanguage;&lt;br /&gt;
        integer recepientID;&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        string  languagePair;&lt;br /&gt;
        list    translationCache;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        integer ImessageType;&lt;br /&gt;
        string  Imessage;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        string  tempString2;&lt;br /&gt;
        &lt;br /&gt;
        //Multiplexor Code&lt;br /&gt;
        if ((channel == broadcastChannel) || (channel == priorityNumber))&lt;br /&gt;
        {&lt;br /&gt;
            //==========================&lt;br /&gt;
            //Process Proxy HTTP Request&lt;br /&gt;
            //==========================&lt;br /&gt;
&lt;br /&gt;
            if (channel == priorityNumber)&lt;br /&gt;
            {&lt;br /&gt;
                if (llStringLength(message) &amp;gt;= 508)&lt;br /&gt;
                {&lt;br /&gt;
                    if (((integer)message/channel) != 4958654)&lt;br /&gt;
                    {&lt;br /&gt;
                        sayCachePrivate += [id, message];&lt;br /&gt;
                        return; &lt;br /&gt;
                    }&lt;br /&gt;
                    message = &amp;quot;&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
                message = receiveTextBatchPrivate(id, message);&lt;br /&gt;
                //Received packet to translate&lt;br /&gt;
                llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0.05, 0.25&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
                &lt;br /&gt;
                tempList = llParseString2List(message, [&amp;quot;~&amp;quot;], []);&lt;br /&gt;
                tempString = llList2String(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
&lt;br /&gt;
                tempString2 = llDumpList2String(tempList, &amp;quot;|&amp;quot;);&lt;br /&gt;
                tempList = llCSV2List(tempString);&lt;br /&gt;
                listPos = llList2Integer(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
&lt;br /&gt;
                checkThrottle(listPos, tempString2, tempList);&lt;br /&gt;
&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            //=======================&lt;br /&gt;
            //Process Global Messages&lt;br /&gt;
            //=======================&lt;br /&gt;
            if (llStringLength(message) &amp;gt;= 508)&lt;br /&gt;
            {&lt;br /&gt;
                if (((integer)message/channel) != 4958654)&lt;br /&gt;
                {&lt;br /&gt;
                    sayCache += [id, message];&lt;br /&gt;
                    return; &lt;br /&gt;
                }&lt;br /&gt;
                message = &amp;quot;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            message = receiveTextBatch(id, message);&lt;br /&gt;
            &lt;br /&gt;
            tempList = llCSV2List(message);&lt;br /&gt;
            &lt;br /&gt;
            if (llGetListLength(tempList) &amp;gt;= 2)    &lt;br /&gt;
            {&lt;br /&gt;
                ImessageType = llList2Integer(tempList, 0);&lt;br /&gt;
                tempList = llDeleteSubList(tempList, 0, 0);&lt;br /&gt;
                Imessage = llList2CSV(tempList);        &lt;br /&gt;
            &lt;br /&gt;
                llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0.25, 0, 0.25&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
                //Process Message Here&lt;br /&gt;
                if (ImessageType == 1001)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming Heartbeat&lt;br /&gt;
                    if ((integer)Imessage == priorityNumber)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Priority Number Conflict!  Resetting Script...&amp;quot;);&lt;br /&gt;
                        llResetScript(); //Reset if conflicting priority number&lt;br /&gt;
                    }&lt;br /&gt;
                    listPos = llListFindList(translators, [id]);&lt;br /&gt;
                    if (listPos &amp;lt; 0) &lt;br /&gt;
                    {&lt;br /&gt;
                        translators += [(integer)Imessage, id];&lt;br /&gt;
                        if ((isMaster &amp;gt; 0) &amp;amp;&amp;amp; (isInitialized))&lt;br /&gt;
                        {&lt;br /&gt;
                            sendTextBatch((integer)Imessage, llList2CSV([1002, llList2CSV(agentsInTranslation)]));&lt;br /&gt;
                            sendTextBatch((integer)Imessage, llList2CSV([1004, options]));&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        translators = llListReplaceList(translators, [(integer)Imessage], listPos - 1, listPos - 1);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1002)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming agentsInTranslation Master Broadcast&lt;br /&gt;
                    if (isMaster == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        //llMessageLinked(LINK_THIS, 9458021, Imessage, &amp;quot;&amp;quot;);  &lt;br /&gt;
                        tempList = llCSV2List(Imessage);&lt;br /&gt;
                        agentsInTranslation = [];&lt;br /&gt;
                        for (x = 0; x &amp;lt; llGetListLength(tempList); x += 4)&lt;br /&gt;
                        {&lt;br /&gt;
                            agentsInTranslation += [llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2), llList2Integer(tempList, x + 3)];&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1003)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming agentsInTranslation dump from Slave&lt;br /&gt;
                    tempList = llCSV2List(Imessage);&lt;br /&gt;
                    for (x = 0; x &amp;lt; llGetListLength(tempList); x += 4)&lt;br /&gt;
                    {&lt;br /&gt;
                        addAgent(llList2Key(tempList, x), llList2String(tempList, x + 1), llList2Integer(tempList, x + 2));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else if (ImessageType == 1004)&lt;br /&gt;
                {&lt;br /&gt;
                    //Incoming Preferences&lt;br /&gt;
                    options = Imessage;&lt;br /&gt;
                    tempList = llCSV2List(options);&lt;br /&gt;
                    showTranslation = llList2Integer(tempList, 0);&lt;br /&gt;
                    tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
                    autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
&lt;br /&gt;
                    llMessageLinked(LINK_THIS, 3342977, Imessage, &amp;quot;&amp;quot;);  &lt;br /&gt;
                }&lt;br /&gt;
            }            &lt;br /&gt;
            &lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Translator Engine Code&lt;br /&gt;
        if ((llToLower(message) == &amp;quot;translator&amp;quot;) &amp;amp;&amp;amp; (isMaster &amp;gt; 0)) &lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, 2540664, message, id);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if ((!enabled) &amp;amp;&amp;amp; (isMaster == 1)) return;&lt;br /&gt;
        &lt;br /&gt;
        if (!tranObjects)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) != NULL_KEY) return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        listPos = llListFindList(agentsInTranslation, [id]);&lt;br /&gt;
        if (listPos &amp;gt;= 0)&lt;br /&gt;
        {            &lt;br /&gt;
            speakerLanguage = llList2String(agentsInTranslation, listPos + 1);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            speakerLanguage = addNewAgent(id);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (speakerLanguage == &amp;quot;xx&amp;quot;) return;  //Agent Opt-Out&lt;br /&gt;
        &lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 1, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
        //===============================&lt;br /&gt;
        //Formulate Translation Requests&lt;br /&gt;
        //===============================&lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(agentsInTranslation); x += 4)&lt;br /&gt;
        {&lt;br /&gt;
            //Loop through translation group and do appropriate translations as needed&lt;br /&gt;
            recepientID = llList2Integer(agentsInTranslation, x + 3);&lt;br /&gt;
            recepientLanguage =  checkLanguage(llList2Key(agentsInTranslation, x + 1)); &lt;br /&gt;
            if ((speakerLanguage != recepientLanguage) &amp;amp;&amp;amp; (recepientLanguage != &amp;quot;&amp;quot;) &amp;amp;&amp;amp; (recepientLanguage != &amp;quot;xx&amp;quot;))&lt;br /&gt;
            {&lt;br /&gt;
                languagePair = speakerLanguage + &amp;quot;|&amp;quot; + recepientLanguage;&lt;br /&gt;
                    &lt;br /&gt;
                listPos = llListFindList(translationCache, [languagePair]);&lt;br /&gt;
                if (listPos &amp;lt; 0)&lt;br /&gt;
                  translationCache += [languagePair, recepientID];&lt;br /&gt;
                else&lt;br /&gt;
                  translationCache = llListReplaceList(translationCache, [llList2String(translationCache, listPos + 1) + &amp;quot;@&amp;quot; + (string)recepientID], listPos + 1, listPos + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        //Process Requests&lt;br /&gt;
        if (llGetListLength(translationCache) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; llGetListLength(translationCache); x += 2)&lt;br /&gt;
            {&lt;br /&gt;
                //====================================&lt;br /&gt;
                //Translation&lt;br /&gt;
                //====================================&lt;br /&gt;
                //Forumulate and Send Translation Request&lt;br /&gt;
                languagePair = &amp;quot;|&amp;quot; + llList2String(llParseStringKeepNulls(llList2String(translationCache, x), [&amp;quot;|&amp;quot;],[]), 1); &lt;br /&gt;
                checkThrottle(0, llEscapeURL(message) + &amp;quot;&amp;amp;langpair=&amp;quot; + llEscapeURL(languagePair), [llGetTime(), id , llList2String(translationCache, x + 1), llList2String(translationCache, x)]);&lt;br /&gt;
            } &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            speakerLanguage = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        //====================================&lt;br /&gt;
        //Language Detection&lt;br /&gt;
        //====================================&lt;br /&gt;
        if (llList2Key(llGetObjectDetails(id, [OBJECT_CREATOR]), 0) == NULL_KEY)&lt;br /&gt;
        {&lt;br /&gt;
            if (((speakerLanguage == &amp;quot;&amp;quot;) || (llList2Integer(agentsInTranslation, llListFindList(agentsInTranslation, [id]) + 2) == TRUE)) || (isMaster == 2))&lt;br /&gt;
            {&lt;br /&gt;
                //Forumulate and Send Language Detect Request&lt;br /&gt;
                checkThrottle(1, llEscapeURL(message), [llGetTime(), id]);&lt;br /&gt;
            }       &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        string  tempString;&lt;br /&gt;
&lt;br /&gt;
        if (status != 200) &lt;br /&gt;
        {&lt;br /&gt;
            //llOwnerSay(&amp;quot;WWW Error:&amp;quot; + (string)status);&lt;br /&gt;
            llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 0, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
            //llOwnerSay(body);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        //Process Resonse Code&lt;br /&gt;
        tempString = llGetSubString(body, llSubStringIndex(body, &amp;quot;\&amp;quot;responseStatus\&amp;quot;:&amp;quot;), -1);&lt;br /&gt;
        status = (integer)llGetSubString(tempString, 17, llSubStringIndex(tempString, &amp;quot;}&amp;quot;) - 1);&lt;br /&gt;
        if (status != 200)&lt;br /&gt;
        {&lt;br /&gt;
            //llOwnerSay(&amp;quot;Language Server Returned Error Code: &amp;quot; + (string)status);&lt;br /&gt;
            //llOwnerSay(body);&lt;br /&gt;
            llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;1, 0, 0&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        llMessageLinked(LINK_ALL_CHILDREN, 6634934, (string)&amp;lt;0, 0, 1&amp;gt;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, 345149624, body, request_id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HTTP Handler==&lt;br /&gt;
Even though the name of this script is &amp;quot;HTTP Handler&amp;quot;, it really just stores the requested translation traffic so that we can match incoming translations from Google with what was requested.  Since this takes a lot of memory for storage, this information is kept out of the engine script.  When an incoming HTTP response comes in, we fetch the data from here.  If the requests didn&#039;t come back in a timely fashion, we remove it from the queue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//HTTP Handler&lt;br /&gt;
//Copyright 2006-2009 by Hank Ramos&lt;br /&gt;
&lt;br /&gt;
list requestedTranslations;&lt;br /&gt;
list requestedDetections;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llSetTimerEvent(5);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        list    newList;&lt;br /&gt;
        float timeElapsed; &lt;br /&gt;
        &lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(requestedDetections); x += 2)&lt;br /&gt;
        {&lt;br /&gt;
            timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedDetections, x + 1)), 0);&lt;br /&gt;
            if (timeElapsed &amp;lt; 60.0) &lt;br /&gt;
                newList += llList2List(requestedDetections, x, x + 1);&lt;br /&gt;
        }&lt;br /&gt;
        requestedDetections = newList;&lt;br /&gt;
        newList = [];&lt;br /&gt;
        for (x = 0; x &amp;lt; llGetListLength(requestedTranslations); x += 2)&lt;br /&gt;
        {&lt;br /&gt;
            timeElapsed = llGetTime() - llList2Float(llCSV2List(llList2String(requestedTranslations, x + 1)), 0);&lt;br /&gt;
            if (timeElapsed &amp;lt; 60.0) &lt;br /&gt;
            {&lt;br /&gt;
                newList += llList2List(requestedTranslations, x, x + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        requestedTranslations = newList;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        &lt;br /&gt;
        if (num == 235365342)&lt;br /&gt;
        {&lt;br /&gt;
            //Translation&lt;br /&gt;
            requestedTranslations += [id, str];&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 235365343)&lt;br /&gt;
        {&lt;br /&gt;
            //Detection&lt;br /&gt;
            requestedDetections += [id, str];&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 345149624)&lt;br /&gt;
        {&lt;br /&gt;
            listPos = llListFindList(requestedTranslations, [id]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, 345149625, str, llList2String(requestedTranslations, listPos + 1));&lt;br /&gt;
                requestedTranslations = llDeleteSubList(requestedTranslations, listPos, listPos + 1);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            listPos = llListFindList(requestedDetections, [id]);&lt;br /&gt;
            if (listPos &amp;gt;= 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, 345149626, str, llList2String(requestedDetections, listPos + 1));&lt;br /&gt;
                requestedDetections = llDeleteSubList(requestedDetections, listPos, listPos + 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interface Handler==&lt;br /&gt;
This is the interface, or menu-system of the translator.  It handles all of the numerous dialogs, language selection, etc. of the translator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//Menu System&lt;br /&gt;
//Copyright 2006-2009 by Hank Ramos&lt;br /&gt;
&lt;br /&gt;
//Variables&lt;br /&gt;
integer randomDialogChannel;&lt;br /&gt;
integer lastAttachPoint;&lt;br /&gt;
list    detectedAgentKeyList;&lt;br /&gt;
list    detectedAgentNameList;&lt;br /&gt;
key     agentInDialog;&lt;br /&gt;
integer isInitialized = FALSE;&lt;br /&gt;
list    agentsInTranslation;&lt;br /&gt;
integer translatorCount;&lt;br /&gt;
&lt;br /&gt;
//Options&lt;br /&gt;
integer groupAccess    = FALSE;&lt;br /&gt;
integer autoLanguage   = TRUE;&lt;br /&gt;
integer deviceAttached;&lt;br /&gt;
integer enabled        = FALSE;&lt;br /&gt;
integer isShowTran     = FALSE;&lt;br /&gt;
integer showAgents     = TRUE;&lt;br /&gt;
string  displayStringMD5;&lt;br /&gt;
integer isMaster = 1;&lt;br /&gt;
integer tranObjects = TRUE;&lt;br /&gt;
&lt;br /&gt;
//Constants&lt;br /&gt;
list    languages= [&lt;br /&gt;
&amp;quot;Chinese-Simple&amp;quot;, &amp;quot;Chinese-Trad&amp;quot;, &amp;quot;Croatian&amp;quot;,  &lt;br /&gt;
&amp;quot;Bulgarian&amp;quot;, &amp;quot;Belarusian&amp;quot;, &amp;quot;Catlan&amp;quot;,&lt;br /&gt;
&amp;quot;Afrikaans&amp;quot;, &amp;quot;Albanian&amp;quot;, &amp;quot;Arabic&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Filipino&amp;quot;, &amp;quot;French&amp;quot;, &amp;quot;Galician&amp;quot;,    &lt;br /&gt;
&amp;quot;Finnish&amp;quot;, &amp;quot;English&amp;quot;, &amp;quot;Estonian&amp;quot;,     &lt;br /&gt;
&amp;quot;Czech&amp;quot;, &amp;quot;Danish&amp;quot;, &amp;quot;Dutch&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Indonesian&amp;quot;, &amp;quot;Irish&amp;quot;, &amp;quot;Italian&amp;quot;,      &lt;br /&gt;
&amp;quot;Hindi&amp;quot;, &amp;quot;Hungarian&amp;quot;, &amp;quot;Icelandic&amp;quot;, &lt;br /&gt;
&amp;quot;German&amp;quot;, &amp;quot;Greek&amp;quot;, &amp;quot;Hebrew&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;Maltese&amp;quot;, &amp;quot;Norwegian&amp;quot;, &amp;quot;Persian&amp;quot;,   &lt;br /&gt;
&amp;quot;Lithuanian&amp;quot;, &amp;quot;Macedonian&amp;quot;, &amp;quot;Malay&amp;quot;,   &lt;br /&gt;
&amp;quot;Japanese&amp;quot;, &amp;quot;Korean&amp;quot;, &amp;quot;Latvian&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Slovenian&amp;quot;, &amp;quot;Spanish&amp;quot;, &amp;quot;Swahili&amp;quot;, &lt;br /&gt;
&amp;quot;Russian&amp;quot;, &amp;quot;Serbian&amp;quot;, &amp;quot;Slovak&amp;quot;, &lt;br /&gt;
&amp;quot;Polish&amp;quot;, &amp;quot;Portuguese&amp;quot;, &amp;quot;Romanian&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Yiddish&amp;quot;, &amp;quot;\t     &amp;quot;, &amp;quot;\t     &amp;quot;,&lt;br /&gt;
&amp;quot;Ukrainian&amp;quot;, &amp;quot;Vietnamese&amp;quot;, &amp;quot;Welsh&amp;quot;,&lt;br /&gt;
&amp;quot;Swedish&amp;quot;, &amp;quot;Thai&amp;quot;, &amp;quot;Turkish&amp;quot;];&lt;br /&gt;
&lt;br /&gt;
list    languageCodes = [&lt;br /&gt;
&amp;quot;zh-CN&amp;quot;, &amp;quot;zh-TW&amp;quot;, &amp;quot;hr&amp;quot;,  &lt;br /&gt;
&amp;quot;bg&amp;quot;, &amp;quot;be&amp;quot;, &amp;quot;ca&amp;quot;,&lt;br /&gt;
&amp;quot;af&amp;quot;, &amp;quot;sq&amp;quot;, &amp;quot;ar&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;tl&amp;quot;, &amp;quot;fr&amp;quot;, &amp;quot;gl&amp;quot;,    &lt;br /&gt;
&amp;quot;fi&amp;quot;, &amp;quot;en&amp;quot;, &amp;quot;et&amp;quot;,     &lt;br /&gt;
&amp;quot;cs&amp;quot;, &amp;quot;da&amp;quot;, &amp;quot;nl&amp;quot;,  &lt;br /&gt;
&lt;br /&gt;
&amp;quot;id&amp;quot;, &amp;quot;ga&amp;quot;, &amp;quot;it&amp;quot;,      &lt;br /&gt;
&amp;quot;hi&amp;quot;, &amp;quot;hu&amp;quot;, &amp;quot;is&amp;quot;, &lt;br /&gt;
&amp;quot;de&amp;quot;, &amp;quot;el&amp;quot;, &amp;quot;iw&amp;quot;,    &lt;br /&gt;
 &lt;br /&gt;
&amp;quot;mt&amp;quot;, &amp;quot;no&amp;quot;, &amp;quot;fa&amp;quot;,   &lt;br /&gt;
&amp;quot;lt&amp;quot;, &amp;quot;mk&amp;quot;, &amp;quot;ms&amp;quot;,   &lt;br /&gt;
&amp;quot;ja&amp;quot;, &amp;quot;ko&amp;quot;, &amp;quot;lv&amp;quot;,   &lt;br /&gt;
&lt;br /&gt;
&amp;quot;sl&amp;quot;, &amp;quot;es&amp;quot;, &amp;quot;sw&amp;quot;, &lt;br /&gt;
&amp;quot;ru&amp;quot;, &amp;quot;sr&amp;quot;, &amp;quot;sk&amp;quot;, &lt;br /&gt;
&amp;quot;pl&amp;quot;, &amp;quot;pt-PT&amp;quot;, &amp;quot;ro&amp;quot;, &lt;br /&gt;
&lt;br /&gt;
&amp;quot;yi&amp;quot;, &amp;quot;&amp;quot;, &amp;quot;&amp;quot;,&lt;br /&gt;
&amp;quot;uk&amp;quot;, &amp;quot;vi&amp;quot;, &amp;quot;cy&amp;quot;,&lt;br /&gt;
&amp;quot;sv&amp;quot;, &amp;quot;th&amp;quot;, &amp;quot;tr&amp;quot;];&lt;br /&gt;
  &lt;br /&gt;
//Functions&lt;br /&gt;
//Takes in the offsets, and the attach point &lt;br /&gt;
vector fn_makePos(integer attach_point, vector offset) {&lt;br /&gt;
    if ((attach_point == 31) || (attach_point == 35)) { //center 2 &amp;amp; center        &lt;br /&gt;
        return &amp;lt;0,0,0&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 32) { // Top right&lt;br /&gt;
        return &amp;lt;offset.x, offset.y, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 33) { // Top&lt;br /&gt;
        return &amp;lt;offset.x, 0, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 34) { // Top Left&lt;br /&gt;
        return &amp;lt;offset.x, offset.y * -1, offset.z * -1&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 36) { // Bottom Left&lt;br /&gt;
        return &amp;lt;offset.x, offset.y * -1 , offset.z&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 37) { // Bottom&lt;br /&gt;
        return &amp;lt;offset.x, 0, offset.z&amp;gt;;&lt;br /&gt;
    } else if (attach_point == 38) { // Bottom Right - Baseline&lt;br /&gt;
        return offset;&lt;br /&gt;
    } else { //Not a HUD point? Then return it&#039;s current pos&lt;br /&gt;
        return llGetLocalPos();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
updateDisplay()&lt;br /&gt;
{&lt;br /&gt;
    string  tempString;&lt;br /&gt;
    integer listLength;&lt;br /&gt;
    integer x;&lt;br /&gt;
    string  agentName;&lt;br /&gt;
    &lt;br /&gt;
    if (isInitialized == FALSE) return;&lt;br /&gt;
    tempString = &amp;quot;Universal Translator&amp;quot;;&lt;br /&gt;
    if (isMaster != 1)&lt;br /&gt;
        tempString += &amp;quot; (Link-&amp;quot; + (string)(translatorCount + 1) + &amp;quot;)&amp;quot;;&lt;br /&gt;
    tempString += &amp;quot;\n===============&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (enabled) &lt;br /&gt;
    {&lt;br /&gt;
        listLength = llGetListLength(agentsInTranslation);&lt;br /&gt;
        if (((showAgents) &amp;amp;&amp;amp; (listLength &amp;lt;= 40)) &amp;amp;&amp;amp; (listLength != 0))&lt;br /&gt;
        {&lt;br /&gt;
            for (x = 0; x &amp;lt; listLength; x += 4)&lt;br /&gt;
            {&lt;br /&gt;
                agentName = llList2String(llGetObjectDetails(llList2Key(agentsInTranslation, x), [OBJECT_NAME]), 0);&lt;br /&gt;
                if (llStringLength(agentName) &amp;gt; 25)&lt;br /&gt;
                    agentName = llGetSubString(agentName, 0, 24);&lt;br /&gt;
                if (agentName != &amp;quot;&amp;quot;)&lt;br /&gt;
                    tempString += &amp;quot;\n&amp;quot; + agentName + &amp;quot;(&amp;quot; + llList2String(agentsInTranslation, x + 1) + &amp;quot;)&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            tempString += &amp;quot;\n# Agents Translated: &amp;quot; + (string)llRound(listLength/3);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        tempString += &amp;quot;\n&amp;gt;&amp;gt; Disabled &amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (llMD5String(tempString, 0) != displayStringMD5)&lt;br /&gt;
    {&lt;br /&gt;
        displayStringMD5 = llMD5String(tempString, 0);&lt;br /&gt;
        llSetText(tempString, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showMainMenu(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (isInitialized == FALSE) return;&lt;br /&gt;
    integer avatarParticipating;&lt;br /&gt;
    list buttonList = [&amp;quot;Language&amp;quot;, &amp;quot;Help&amp;quot;];&lt;br /&gt;
    string dialogMsg = &amp;quot;Main Menu\nLANGUAGE: manually choose your source language. Target languages are detected automatically\nHELP: get help notecard&amp;quot;;&lt;br /&gt;
    buttonList += &amp;quot;FREE Copy&amp;quot;;&lt;br /&gt;
    dialogMsg += &amp;quot;\nFREE COPY: receive FREE copy of Universal Translator.&amp;quot;; &lt;br /&gt;
     &lt;br /&gt;
    if (llList2String(agentsInTranslation, llListFindList(agentsInTranslation, [(string)id]) + 1) != &amp;quot;xx&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Opt-Out&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nOPT-OUT: disable receipt of translations&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Opt-In&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nOPT-IN: join the translations&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Donate&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nDONATE: donate L$ to the developer of Universal Translator.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Reset&amp;quot;;&lt;br /&gt;
        buttonList += &amp;quot;Options&amp;quot;;&lt;br /&gt;
        buttonList += &amp;quot;Send Copy&amp;quot;;&lt;br /&gt;
        dialogMsg += &amp;quot;\nSEND COPY: send FREE copy of Universal Translator.&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        if (enabled)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Disable&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Enable&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        dialogMsg += &amp;quot;\nRESET: reset all scripts in translator&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llDialog(id, dialogMsg, buttonList, randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showOptionsMenu(key id)&lt;br /&gt;
{&lt;br /&gt;
    integer avatarParticipating;&lt;br /&gt;
    list buttonList = [];&lt;br /&gt;
    string dialogMsg = &amp;quot;Options Menu.&amp;quot;;&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        if (groupAccess)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Group OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Group ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nGROUP: allow group members to admin.&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        buttonList += &amp;quot;Main Menu&amp;quot;;&lt;br /&gt;
        if (!deviceAttached)&lt;br /&gt;
        {&lt;br /&gt;
            if (autoLanguage)&lt;br /&gt;
            {&lt;br /&gt;
                buttonList += &amp;quot;Scan OFF&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                buttonList += &amp;quot;Scan ON&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nSCAN: scan for Avatars and automatically add to translation matrix.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (isShowTran)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Echo OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Echo ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nECHO: show translations of your chat sent to others.&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        if (tranObjects)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Objects OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Objects ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\nOBJECTS: translate chat of scripted objects&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
        if (showAgents)&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Agents OFF&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            buttonList += &amp;quot;Agents ON&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        dialogMsg += &amp;quot;\AGENTS: show list of agents translated.&amp;quot;; &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llDialog(id, dialogMsg, buttonList, randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
showLanguageDialog1(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language...&amp;quot;, [&amp;quot;\t&amp;quot;, &amp;quot;\t&amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT&amp;quot;] + llList2List(languages, 0, 8),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog2(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK&amp;quot;, &amp;quot;\t &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT &amp;quot;] + llList2List(languages, 9, 17),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog3(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK &amp;quot;, &amp;quot;\t  &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT  &amp;quot;] + llList2List(languages, 18, 26),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog4(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK  &amp;quot;, &amp;quot;\t   &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT   &amp;quot;] + llList2List(languages, 27, 35),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
showLanguageDialog5(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK   &amp;quot;, &amp;quot;\t    &amp;quot;, &amp;quot;&amp;gt;&amp;gt; NEXT    &amp;quot;] + llList2List(languages, 36, 44),  randomDialogChannel);&lt;br /&gt;
}showLanguageDialog6(key id)&lt;br /&gt;
{&lt;br /&gt;
    llDialog(id, &amp;quot;Select your TARGET language..&amp;quot;, [&amp;quot;&amp;lt;&amp;lt; BACK    &amp;quot;, &amp;quot;\t     &amp;quot;, &amp;quot;\t     &amp;quot;] + llList2List(languages, 45, 53),  randomDialogChannel);&lt;br /&gt;
}&lt;br /&gt;
processListen(string name, key id, string message)&lt;br /&gt;
{&lt;br /&gt;
    key listenKey;&lt;br /&gt;
    &lt;br /&gt;
    if (llListFindList(languages, [message]) &amp;gt; -1) //Language Selected in Dialog&lt;br /&gt;
    {&lt;br /&gt;
        if (message != &amp;quot;&amp;quot;) llMessageLinked(LINK_THIS, 9384610, llList2String(languageCodes, llListFindList(languages, [message])), id);&lt;br /&gt;
    }    &lt;br /&gt;
    else if (llToLower(message) == &amp;quot;help&amp;quot;) &lt;br /&gt;
    {&lt;br /&gt;
        llGiveInventory(id, &amp;quot;Universal Translator Help&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Main Menu&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showMainMenu(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Options&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showOptionsMenu(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Language&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Opt-In&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;Opt-Out&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 9384610, &amp;quot;xx&amp;quot;, id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;FREE Copy&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, 9455209, llKey2Name(id), id);&lt;br /&gt;
    }&lt;br /&gt;
    if (id == llGetOwner())&lt;br /&gt;
    {&lt;br /&gt;
        if (message == &amp;quot;Group ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            groupAccess = TRUE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Group OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            groupAccess = FALSE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Donate&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, 324235353254, &amp;quot;&amp;quot;, llGetOwner());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if ((id == llGetOwner()) || ((groupAccess) &amp;amp;&amp;amp; (llSameGroup(id))))&lt;br /&gt;
    {&lt;br /&gt;
        if (message == &amp;quot;Reset&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
           llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Enable&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            enabled  = TRUE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Disable&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            enabled  = FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Echo ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            isShowTran = TRUE;&lt;br /&gt;
            //llMessageLinked(LINK_THIS, 2734322, (string)isShowTran, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Echo OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            isShowTran = FALSE;&lt;br /&gt;
       }&lt;br /&gt;
        else if (message == &amp;quot;Objects OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            tranObjects = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Objects ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            tranObjects = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Agents OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 455832, (string)showAgents, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Agents ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = TRUE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, 455832, (string)showAgents, id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Scan ON&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            autoLanguage  = TRUE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (message == &amp;quot;Scan OFF&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            autoLanguage = FALSE;&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if ((message == &amp;quot;Send Copy&amp;quot;) || (message == &amp;quot;&amp;gt;&amp;gt;RESCAN&amp;lt;&amp;lt;&amp;quot;))&lt;br /&gt;
        {        &lt;br /&gt;
            agentInDialog = id;&lt;br /&gt;
            llSensor(&amp;quot;&amp;quot;, NULL_KEY, AGENT, 20.0, TWO_PI);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetListLength(detectedAgentNameList) &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                listenKey = llList2Key(detectedAgentKeyList, llListFindList(detectedAgentNameList, [message]));&lt;br /&gt;
                if (listenKey != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, 9455209, message, listenKey);&lt;br /&gt;
                }&lt;br /&gt;
                detectedAgentNameList = [];&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    if (message == &amp;quot;&amp;gt;&amp;gt; NEXT&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;gt;&amp;gt; NEXT    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog6(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;&amp;lt;&amp;lt; BACK    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    if (message == &amp;quot;\t&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog1(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog2(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t  &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog3(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t   &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog4(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t    &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog5(id);&lt;br /&gt;
    }&lt;br /&gt;
    else if (message == &amp;quot;\t     &amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        showLanguageDialog6(id);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), id);&lt;br /&gt;
}&lt;br /&gt;
checkAttach()&lt;br /&gt;
{&lt;br /&gt;
    if (llGetAttached() &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        llSetScale(&amp;lt;0.125, 0.125, 0.087&amp;gt;);&lt;br /&gt;
        if(lastAttachPoint != llGetAttached())&lt;br /&gt;
        {&lt;br /&gt;
            llSetPos(fn_makePos(llGetAttached(), &amp;lt;0.00000, 0.13500, 0.15433&amp;gt;));&lt;br /&gt;
            llSetRot(&amp;lt;0,0,0,1&amp;gt;);&lt;br /&gt;
            lastAttachPoint = llGetAttached();                &lt;br /&gt;
        }&lt;br /&gt;
        llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);&lt;br /&gt;
        llMessageLinked(llGetLinkNumber(), 3792114, (string)TRUE, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llSetScale(&amp;lt;0.5, 0.5, 0.750&amp;gt;);&lt;br /&gt;
        llReleaseControls();&lt;br /&gt;
        llMessageLinked(llGetLinkNumber(), 3792114, (string)FALSE, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    run_time_permissions(integer perms)&lt;br /&gt;
    {&lt;br /&gt;
        //integer hasPerms = llGetPermissions();&lt;br /&gt;
        llTakeControls( CONTROL_UP , TRUE, TRUE);&lt;br /&gt;
    }&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        //llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS );&lt;br /&gt;
        &lt;br /&gt;
        string speakerLanguage;&lt;br /&gt;
        //llOwnerSay(&amp;quot;Welcome to the Universal Translator, the best FREE translator in SL! Please consider making a L$ donation to help with maintenance and further updates. Select DONATE in the translator menu to make a donation.&amp;quot;);&lt;br /&gt;
        //llSetText(&amp;quot;Initializing...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
    &lt;br /&gt;
        llSetText(&amp;quot;Searching for\nnearby translators...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
        checkAttach();&lt;br /&gt;
        &lt;br /&gt;
        randomDialogChannel = -(integer)llFrand(2147483647);&lt;br /&gt;
&lt;br /&gt;
        llMessageLinked(LINK_SET, 20957454, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Universal Translator Engine&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;HTTP Handler&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;No-Script IM Handler&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Auto-Update&amp;quot;);&lt;br /&gt;
        llResetOtherScript(&amp;quot;Donation&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        //Other Setup&lt;br /&gt;
        llSleep(5);&lt;br /&gt;
        llListen(randomDialogChannel, &amp;quot;&amp;quot;, NULL_KEY, &amp;quot;&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, 3342976, llList2CSV([isShowTran, tranObjects, autoLanguage]), &amp;quot;&amp;quot;);        &lt;br /&gt;
&lt;br /&gt;
        //llOwnerSay(&amp;quot;Mem Free=&amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer startup_param)&lt;br /&gt;
    {&lt;br /&gt;
        //checkAttach();&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    sensor(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        &lt;br /&gt;
        if (num_detected &amp;gt; 11)&lt;br /&gt;
            num_detected = 11;&lt;br /&gt;
        &lt;br /&gt;
        detectedAgentKeyList = [];&lt;br /&gt;
        detectedAgentNameList = [];&lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x += 1)&lt;br /&gt;
        {&lt;br /&gt;
             detectedAgentKeyList += llDetectedKey(x);&lt;br /&gt;
             tempString = llDetectedName(x);&lt;br /&gt;
             if (llStringLength(tempString) &amp;gt; 24) tempString = llGetSubString(tempString, 0, 23);&lt;br /&gt;
             detectedAgentNameList += tempString;&lt;br /&gt;
        }&lt;br /&gt;
        if (llGetListLength(detectedAgentNameList) &amp;gt; 0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(agentInDialog, &amp;quot;Select someone nearby to receive FREE a copy of the Universal Translator...&amp;quot;, [&amp;quot;&amp;gt;&amp;gt;RESCAN&amp;lt;&amp;lt;&amp;quot;] + detectedAgentNameList, randomDialogChannel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    link_message(integer sender_num, integer num, string str, key id)&lt;br /&gt;
    {&lt;br /&gt;
        integer listPos;&lt;br /&gt;
        list    tempList;&lt;br /&gt;
        string  tempString;&lt;br /&gt;
        &lt;br /&gt;
        if (num == 2540664)&lt;br /&gt;
        {&lt;br /&gt;
            showMainMenu(id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3792114)&lt;br /&gt;
        {&lt;br /&gt;
            deviceAttached = (integer)str;&lt;br /&gt;
            if (deviceAttached) autoLanguage = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 65635544)&lt;br /&gt;
        {&lt;br /&gt;
            translatorCount = ((integer)str)/2;&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 6877259)&lt;br /&gt;
        {&lt;br /&gt;
            if (isInitialized == FALSE)&lt;br /&gt;
            {&lt;br /&gt;
                isInitialized = TRUE;&lt;br /&gt;
                //Owner Language Detection&lt;br /&gt;
                tempString  = llGetAgentLanguage(llGetOwner());&lt;br /&gt;
                if (llGetSubString(tempString, 0, 1) == &amp;quot;en&amp;quot;) tempString = &amp;quot;en&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
                if (tempString == &amp;quot;&amp;quot;) &lt;br /&gt;
                {&lt;br /&gt;
                    tempString = &amp;quot;en&amp;quot;;&lt;br /&gt;
                }&lt;br /&gt;
                llMessageLinked(LINK_THIS, 9384610, tempString, llGetOwner());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
          enabled = (integer)str; //marker&lt;br /&gt;
          updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 34829304)&lt;br /&gt;
        {&lt;br /&gt;
            isMaster = (integer)str;&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 455832)&lt;br /&gt;
        {&lt;br /&gt;
            showAgents = (integer)str;&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 94558323)&lt;br /&gt;
        {&lt;br /&gt;
            agentsInTranslation = llCSV2List(str);&lt;br /&gt;
            updateDisplay();&lt;br /&gt;
        }&lt;br /&gt;
        else if (num == 3342977)&lt;br /&gt;
        {&lt;br /&gt;
            //Options are Show Tran and tranObjects at this time&lt;br /&gt;
            tempList = llCSV2List(str);&lt;br /&gt;
            isShowTran = llList2Integer(tempList, 0);&lt;br /&gt;
            tranObjects = llList2Integer(tempList, 1);&lt;br /&gt;
            autoLanguage = llList2Integer(tempList, 2);&lt;br /&gt;
       }&lt;br /&gt;
        else if (num == 32364364)&lt;br /&gt;
        {&lt;br /&gt;
            //Send Options&lt;br /&gt;
            llMessageLinked(LINK_THIS, 8434532, (string)enabled, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
   }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer num_detected)&lt;br /&gt;
    {&lt;br /&gt;
        integer x;&lt;br /&gt;
        key avatarKey;&lt;br /&gt;
        &lt;br /&gt;
        for (x = 0; x &amp;lt; num_detected; x++)&lt;br /&gt;
        {&lt;br /&gt;
            avatarKey = llDetectedKey(x);&lt;br /&gt;
            showMainMenu(avatarKey);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {                &lt;br /&gt;
        processListen(name, id, message);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    attach(key id)&lt;br /&gt;
    {&lt;br /&gt;
        checkAttach();&lt;br /&gt;
        if (id) //tests if it is a valid key and not NULL_KEY&lt;br /&gt;
        {&lt;br /&gt;
            llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    control(key id,integer held, integer change) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720722</id>
		<title>Periodicals</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720722"/>
		<updated>2010-02-03T17:15:05Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Minor formatting changes and put sl-newspaper in same order as in above section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Periodicals Related to Second Life==&lt;br /&gt;
*[http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine] - The Ultimate Fashion and Lifestyle Magazine&lt;br /&gt;
*[http://www.massively.com Massively] (formerly Second Life Insider) [http://www.massively.com/category/second-life SL specific section]&lt;br /&gt;
*[http://mattersofmusic.com/current-issue Music Matters Magazine]&lt;br /&gt;
*[http://sl.nmc.org New Media Consortium Observer]&lt;br /&gt;
*[http://www.news2life.com/ News2Life] - Second Life Business News portal&lt;br /&gt;
*[http://www.rezmagazine.co.uk/ Rez Magazine]&lt;br /&gt;
*[http://www.sl-newspaper.com/ sl-newspaper.com]&lt;br /&gt;
*[http://www.slatenight.com/ Slate Magazine]&lt;br /&gt;
*[http://www.sluncover.com/ Uncover Magazine]: stylish, sophisticated, artistic magazine about Second Life® experience&lt;br /&gt;
&lt;br /&gt;
==Editorial and Advertising Contacts for Second Life Related Periodicals==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Second Life Periodicals Editorial and Press Contacts&lt;br /&gt;
! Periodical !! Editorial contact !! Ad contact&lt;br /&gt;
|-&lt;br /&gt;
| [http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine] The Ultimate Fashion and Lifestyle Magazine || editorial@avenuesl.com || ads@avenuesl.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.massively.com/ Massively] ||[http://www.massively.com/contact/comments/ Editorial staff]||[http://www.weblogsinc.com/advertise/ Advertising Contact] &lt;br /&gt;
|-&lt;br /&gt;
| [http://www.metaversemessenger.com/ Metaverse Messenger] || [http://www.metaversemessenger.com/staff.htm Staff] ||  advertising AT metaversemessenger.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://mattersofmusic.com/current-issue Music Matters Magazine] || m3editor [AT] mattersofmusic [DOT] com || reslez [AT] mattersofmusic [DOT] com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.news2life.com/ News2Life] - Second Life Business News portal || [http://www.news2life.com/ Contact] || [http://www.slbiz2life.com/ Ad Contact]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sl-newspaper.com/ sl-newspaper.com] || dana.vanmoer@gmail.com || jamestjuno@gmail.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondlifeherald.com/ Second Life Herald] || [http://www.secondlifeherald.com/slh/about.html#write Editorial Staff] || [http://www.secondlifeherald.com/slh/about.html#advert Advertising Staff]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondstyle.com/ Second Style Magazine] || editor [AT] secondstyle.com || sales [AT] secondstyle.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.slatenight.com/ Slate Magazine] || [http://www.slatenight.com/index.php?option=com_magazine&amp;amp;func=author_articles&amp;amp;authorid=63&amp;amp;Itemid=51 Editorial Staff] ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back to [[Marketing]]&lt;br /&gt;
[[Category:Marketing]]&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720712</id>
		<title>Periodicals</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720712"/>
		<updated>2010-02-03T17:10:44Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Added entry for Music Matters Magazine and put list in alphabetical order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Periodicals Related to Second Life==&lt;br /&gt;
*[http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine] - The Ultimate Fashion and Lifestyle Magazine&lt;br /&gt;
*[http://www.massively.com Massively] (formerly Second Life Insider) [http://www.massively.com/category/second-life SL specific section]&lt;br /&gt;
*[http://mattersofmusic.com/current-issue Music Matters Magazine]&lt;br /&gt;
*[http://sl.nmc.org New Media Consortium Observer]&lt;br /&gt;
*[http://www.news2life.com/ News2Life] - Second Life Business News portal&lt;br /&gt;
*[http://www.rezmagazine.co.uk/ Rez Magazine]&lt;br /&gt;
*[http://www.sl-newspaper.com/ sl-newspaper.com]&lt;br /&gt;
*[http://www.slatenight.com/ Slate Magazine]&lt;br /&gt;
*[http://www.sluncover.com/ Uncover Magazine]: stylish, sophisticated, artistic magazine about Second Life® experience&lt;br /&gt;
&lt;br /&gt;
==Editorial and Advertising Contacts for Second Life Related Periodicals==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Second Life Periodicals Editorial and Press Contacts&lt;br /&gt;
! Periodical !! Editorial contact !! Ad contact&lt;br /&gt;
|-&lt;br /&gt;
| [http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine The Ultimate Fashion and Lifestyle Magazine] || editorial@avenuesl.com || ads@avenuesl.com ||&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.massively.com/ Massively] ||[http://www.massively.com/contact/comments/ Editorial staff]||[http://www.weblogsinc.com/advertise/ Advertising Contact] &lt;br /&gt;
|-&lt;br /&gt;
| [http://www.metaversemessenger.com/ Metaverse Messenger] || [http://www.metaversemessenger.com/staff.htm Staff] ||  advertising AT metaversemessenger.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://mattersofmusic.com/current-issue Music Matters Magazine] || m3editor [AT] mattersofmusic [DOT] com || reslez [AT] mattersofmusic [DOT] com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.news2life.com/ News2Life] - Second Life Business News portal || [http://www.news2life.com/ Contact] || [http://www.slbiz2life.com/ Ad Contact]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondlifeherald.com/ Second Life Herald] || [http://www.secondlifeherald.com/slh/about.html#write Editorial Staff] || [http://www.secondlifeherald.com/slh/about.html#advert Advertising Staff]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondstyle.com/ Second Style Magazine] || editor [AT] secondstyle.com || sales [AT] secondstyle.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.slatenight.com/ Slate Magazine] || [http://www.slatenight.com/index.php?option=com_magazine&amp;amp;func=author_articles&amp;amp;authorid=63&amp;amp;Itemid=51 Editorial Staff] ||&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sl-newspaper.com/ || dana.vanmoer@gmail.com || jamestjuno@gmail.com ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back to [[Marketing]]&lt;br /&gt;
[[Category:Marketing]]&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720702</id>
		<title>Periodicals</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Periodicals&amp;diff=720702"/>
		<updated>2010-02-03T16:55:39Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Added entry for Music Matters Magazine and put list in alphabetical order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Periodicals Related to Second Life==&lt;br /&gt;
*[http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine] - The Ultimate Fashion and Lifestyle Magazine&lt;br /&gt;
*[http://www.massively.com Massively] (formerly Second Life Insider) [http://www.massively.com/category/second-life SL specific section]&lt;br /&gt;
*[http://mattersofmusic.com/current-issue Music Matters Magazine]&lt;br /&gt;
*[http://sl.nmc.org New Media Consortium Observer]&lt;br /&gt;
*[http://www.news2life.com/ News2Life] - Second Life Business News portal&lt;br /&gt;
*[http://www.rezmagazine.co.uk/ Rez Magazine]&lt;br /&gt;
*[http://www.sl-newspaper.com/ sl-newspaper.com]&lt;br /&gt;
*[http://www.slatenight.com/ Slate Magazine]&lt;br /&gt;
*[http://www.sluncover.com/ Uncover Magazine]: stylish, sophisticated, artistic magazine about Second Life® experience&lt;br /&gt;
&lt;br /&gt;
==Editorial and Advertising Contacts for Second Life Related Periodicals==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Second Life Periodicals Editorial and Press Contacts&lt;br /&gt;
! Periodical !! Editorial contact !! Ad contact&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.metaversemessenger.com/ Metaverse Messenger] || [http://www.metaversemessenger.com/staff.htm Staff] ||  advertising AT metaversemessenger.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondstyle.com/ Second Style Magazine] || editor [AT] secondstyle.com || sales [AT] secondstyle.com&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.massively.com/ Massively] ||[http://www.massively.com/contact/comments/ Editorial staff]||[http://www.weblogsinc.com/advertise/ Advertising Contact] &lt;br /&gt;
|-&lt;br /&gt;
| [http://www.secondlifeherald.com/ Second Life Herald] || [http://www.secondlifeherald.com/slh/about.html#write Editorial Staff] || [http://www.secondlifeherald.com/slh/about.html#advert Advertising Staff]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.slatenight.com/ Slate Magazine] || [http://www.slatenight.com/index.php?option=com_magazine&amp;amp;func=author_articles&amp;amp;authorid=63&amp;amp;Itemid=51 Editorial Staff] ||&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.news2life.com/ News2Life - Second Life Business News portal] || [http://www.news2life.com/ Contact] || [http://www.slbiz2life.com/ Ad Contact]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sl-newspaper.com/ || dana.vanmoer@gmail.com || jamestjuno@gmail.com ||&lt;br /&gt;
|-&lt;br /&gt;
| [http://avenuesl.moonfruit.com/#/magazine/4537517371/ AVENUE Magazine The Ultimate Fashion and Lifestyle Magazine] || editorial@avenuesl.com || ads@avenuesl.com ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back to [[Marketing]]&lt;br /&gt;
[[Category:Marketing]]&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=164583</id>
		<title>XyzzyText</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=164583"/>
		<updated>2008-12-04T20:58:12Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Fixed cut and paste error&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
{{RightToc}}&lt;br /&gt;
XyzzyText is a new version of Xytext with some advanced features:&lt;br /&gt;
&lt;br /&gt;
* Efficiency!  You can now control an entire linkset with just one script.&lt;br /&gt;
* Flexible Speed vs Lag.  Just drop in plug-and-play slave scripts to increase rendering speed.  (More than 4-5 slaves not recommended, there is diminishing returns)&lt;br /&gt;
* Ease of use.  There is no need to know link numbers.  Simply name the child prims xyzzytext-banknumber-cellnumber.&lt;br /&gt;
* To use, pass the bank number to use in the &amp;quot;key&amp;quot; field of the link message of DISPLAY_STRING/EXTENDED.&lt;br /&gt;
&lt;br /&gt;
=Copyright &amp;amp; Licensing=&lt;br /&gt;
&amp;lt;font size=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
* Gigs Taggart hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Thraxis Epsilon hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Strife Onizuka hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Huney Jewell hereby releases her contributions to this under the MIT license.&lt;br /&gt;
* Salahzar Stenvaag hereby releases his contributions to this under the MIT license. (photoshop/GIMP vbs script for alternative fonts plus ZZText)&lt;br /&gt;
* Ruud Lathrop hereby releases her contributions to this under the MIT license.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=XyzzyText - 5 Character=&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Display Prims named: &lt;br /&gt;
xyzzytext-0-0 xyzzytext-0-1&lt;br /&gt;
xyzzytext-1-0 xyzzytext-1-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quickstart:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Store all scripts in your inventory&lt;br /&gt;
* Rez a box&lt;br /&gt;
* Drop the prim setup script in it (You now have one unit, name it xyzzytext-0-0)&lt;br /&gt;
* Make a row of four of these prims (xyzzytext-0-0 xyzzytext-0-1,xyzzytext-0-2,xyzzytext-0-3)&lt;br /&gt;
* Move a copy of this row a little down, and rename the new row(xyzzytext-1-0 xyzzytext-1-1,xyzzytext-1-2,xyzzytext-1-3)&lt;br /&gt;
* Do this for every row you make&lt;br /&gt;
* Create a big box that serves as the board-background(mainprim)&lt;br /&gt;
* Link all prims with the mainprim(selected last), so the mainprim keeps yellow after linking(root-prim)&lt;br /&gt;
* Copy the main script and usage script into the root prim&lt;br /&gt;
* Type something, and check if it all works&lt;br /&gt;
* Flatten the prims, so the text looks straight&lt;br /&gt;
* Consider adding slave scripts to the root prim if you have a lot of rows&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer gToggle;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;);&lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel,string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        if (gToggle)&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;0&amp;quot;);&lt;br /&gt;
        else&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;1&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        gToggle=!gToggle;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main Script==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyzzyText v2.1 Script (Set Line Color) by Huney Jewell&lt;br /&gt;
// XyzzyText v2.0 Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Core XyText Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS /////////////////// &lt;br /&gt;
// XyText Message Map. &lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out. &lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;;&lt;br /&gt;
key     null_key        = NULL_KEY;&lt;br /&gt;
///////////// END CONSTANTS //////////////// &lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
// This is whether or not to use the fade in/out special effect. &lt;br /&gt;
integer gCellUseFading      = FALSE; &lt;br /&gt;
// This is how long to display the text before fading out (if using &lt;br /&gt;
// fading special effect). &lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out. &lt;br /&gt;
float   gCellHoldDelay      = 1.0; &lt;br /&gt;
&lt;br /&gt;
integer gSlaveRegistered;&lt;br /&gt;
list gSlaveNames;&lt;br /&gt;
&lt;br /&gt;
integer BANK_STRIDE=3; //offset, length, highest_dirty&lt;br /&gt;
list gBankingData;&lt;br /&gt;
&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderWithEffects(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // First set the alpha to the lowest possible. &lt;br /&gt;
   llSetLinkAlpha(link,0.05, ALL_SIDES); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);          // Now turn up the alpha until it is at full strength. &lt;br /&gt;
    float Alpha = 0.10; &lt;br /&gt;
    for (; Alpha &amp;lt;= 1.0; Alpha += 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // See if we want to fade out as well. &lt;br /&gt;
   if (gCellHoldDelay &amp;lt; 0.0) &lt;br /&gt;
       // No, bail out. (Just keep showing the string at full strength). &lt;br /&gt;
       return; &lt;br /&gt;
          // Hold the text for a while. &lt;br /&gt;
   llSleep(gCellHoldDelay); &lt;br /&gt;
      // Now fade out. &lt;br /&gt;
   for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // Make the text transparent to fully hide it. &lt;br /&gt;
   llSetLinkTexture(link,TRANSPARENT, ALL_SIDES); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer RenderExtended(integer link, string str, integer render) {&lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   integer length = 0;&lt;br /&gt;
   list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   integer i = 0;&lt;br /&gt;
   for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1)); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
               length += 2 + TokenLength;&lt;br /&gt;
               if(render)&lt;br /&gt;
               {&lt;br /&gt;
                    // This is the extended character. &lt;br /&gt;
                    Indices += (llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95);&lt;br /&gt;
                    &lt;br /&gt;
                    // These are the normal characters.&lt;br /&gt;
                    integer j = 1; &lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                    {&lt;br /&gt;
                       Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               length += TokenLength;&lt;br /&gt;
               if(render)&lt;br /&gt;
               {               &lt;br /&gt;
                   integer j = 0; &lt;br /&gt;
                   for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   {                  &lt;br /&gt;
                       Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j));&lt;br /&gt;
                   }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions.&lt;br /&gt;
  if(render)&lt;br /&gt;
  {   &lt;br /&gt;
       vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
       vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
       vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
       vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
       vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
    &lt;br /&gt;
       // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
       ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);&lt;br /&gt;
   }&lt;br /&gt;
   return length;&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PassToRender(integer render,string message, integer bank)&lt;br /&gt;
{&lt;br /&gt;
//    float time;&lt;br /&gt;
    integer extendedlen = 0;&lt;br /&gt;
    integer link;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer msgLen = llStringLength(message);&lt;br /&gt;
    string TextToRender;&lt;br /&gt;
    integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
    string slave_name; //avoids unnecessary casts, keeping it as a string&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
    integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
    &lt;br /&gt;
    integer x = 0;&lt;br /&gt;
    for (;x &amp;lt; msgLen;x = x + 5)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;gt;= bank_length)  //we don&#039;t want to run off the end of the bank&lt;br /&gt;
        {&lt;br /&gt;
            //set the dirty to max, and bail out, we&#039;re done&lt;br /&gt;
            gBankingData=llListReplaceList(gBankingData, (list)bank_length, (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        TextToRender = llGetSubString(message, x, x + 15);&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves + 1)))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                //time = llGetAndResetTime();&lt;br /&gt;
                if(llSubStringIndex(TextToRender,&amp;quot;\e&amp;quot;) &amp;gt; x)&lt;br /&gt;
                    extendedlen = 5;&lt;br /&gt;
                else&lt;br /&gt;
                    extendedlen = RenderExtended(link,TextToRender,0);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY_EXTENDED, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
              // llOwnerSay((string)llGetAndResetTime());&lt;br /&gt;
            }&lt;br /&gt;
               //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                RenderString(link,TextToRender);&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                extendedlen = RenderExtended(link,TextToRender,1);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
            }&lt;br /&gt;
            if (render == 3)&lt;br /&gt;
                RenderWithEffects(link,TextToRender);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;            &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (bank_highest_dirty==0)&lt;br /&gt;
        bank_highest_dirty=bank_length;&lt;br /&gt;
    &lt;br /&gt;
    integer current_highest_dirty=i;&lt;br /&gt;
    while (i &amp;lt; bank_highest_dirty)&lt;br /&gt;
    {&lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves+1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_DISPLAY, &amp;quot;     &amp;quot;, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));       &lt;br /&gt;
            //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            RenderString(link,&amp;quot;     &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;        &lt;br /&gt;
    }&lt;br /&gt;
    gBankingData=llListReplaceList(gBankingData, (list)current_highest_dirty, (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka&lt;br /&gt;
list gXyTextPrims;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer get_number_of_prims()&lt;br /&gt;
{//ignores avatars.&lt;br /&gt;
    integer a = llGetNumberOfPrims();&lt;br /&gt;
    //Mono tweak&lt;br /&gt;
    vector size = llGetAgentSize(llGetLinkKey(a));&lt;br /&gt;
    while(size.z &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        --a;&lt;br /&gt;
        size = llGetAgentSize(llGetLinkKey(a));&lt;br /&gt;
    }&lt;br /&gt;
    return a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//functions to pack 8-bit shorts into ints&lt;br /&gt;
list pack_and_insert(list in_list, integer pos, integer value)&lt;br /&gt;
{&lt;br /&gt;
//    //figure out the bitpack position&lt;br /&gt;
//    integer pack = pos &amp;amp; 3; //4 bytes per int&lt;br /&gt;
//    pos=pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
//    integer shifted = value &amp;lt;&amp;lt; (pack &amp;lt;&amp;lt; 3);&lt;br /&gt;
//    integer old_value = llList2Integer(in_list, pos);&lt;br /&gt;
//    shifted = old_value | shifted;&lt;br /&gt;
//    in_list = llListReplaceList(in_list, (list)shifted, pos, pos);&lt;br /&gt;
//    return in_list;&lt;br /&gt;
    //Safe optimized version&lt;br /&gt;
    integer index = pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
    return llListReplaceList(in_list, (list)(llList2Integer(in_list, index) | (value &amp;lt;&amp;lt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3))), index, index);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer unpack(list in_list, integer pos)&lt;br /&gt;
{&lt;br /&gt;
    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;gt;&amp;gt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;amp; 0x000000FF;//unsigned&lt;br /&gt;
//    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;lt;&amp;lt; (((~pos) &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;gt;&amp;gt; 24;//signed&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_color(vector color)&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=llGetListLength(gXyTextPrims) &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    &lt;br /&gt;
    for (; i&amp;lt;=num_prims; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_line_color(integer bank, vector color)&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
&lt;br /&gt;
    for (; i &amp;lt; bank_end; ++i)&lt;br /&gt;
    {     &lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
init()&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=get_number_of_prims();&lt;br /&gt;
    string link_name;&lt;br /&gt;
    integer bank=0;&lt;br /&gt;
    integer prims_pointer=0; //&amp;quot;pointer&amp;quot; to the next entry to be used in the gXyTextPrims list.&lt;br /&gt;
    &lt;br /&gt;
    list temp_bank = [];&lt;br /&gt;
    integer temp_bank_stride=2;&lt;br /&gt;
    &lt;br /&gt;
    //FIXME: font texture might should be per-bank&lt;br /&gt;
    llMessageLinked(LINK_THIS, SET_FONT_TEXTURE, &amp;quot;&amp;quot;, gFontTexture);&lt;br /&gt;
    &lt;br /&gt;
    gXyTextPrims=[];&lt;br /&gt;
    integer x=0;&lt;br /&gt;
    for (;x&amp;lt;64;++x)&lt;br /&gt;
    {&lt;br /&gt;
        gXyTextPrims = (gXyTextPrims = []) + gXyTextPrims + 0;  //we need to pad out the list to make it easier to add things in any order later&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @loop;&lt;br /&gt;
    {&lt;br /&gt;
        //loop over all prims, looking for ones in the current bank&lt;br /&gt;
        for(x=0;x&amp;lt;=num_prims;++x)&lt;br /&gt;
        {&lt;br /&gt;
            link_name=llGetLinkName(x);&lt;br /&gt;
            list tmp = llParseString2List(link_name, (list)&amp;quot;-&amp;quot;, []);&lt;br /&gt;
            if(llList2String(tmp,0) == &amp;quot;xyzzytext&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                if (llList2Integer(tmp,1) == bank)&lt;br /&gt;
                {&lt;br /&gt;
                    temp_bank += llList2Integer(tmp,2) + (list)x;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (temp_bank != [])&lt;br /&gt;
        {&lt;br /&gt;
            //sort the current bank&lt;br /&gt;
            temp_bank = llListSort(temp_bank, temp_bank_stride, TRUE);&lt;br /&gt;
            &lt;br /&gt;
            integer temp_len = llGetListLength(temp_bank);&lt;br /&gt;
            &lt;br /&gt;
            //store metadata&lt;br /&gt;
            gBankingData += [prims_pointer, temp_len/temp_bank_stride, 0];&lt;br /&gt;
            &lt;br /&gt;
            //repack the bank into the prim list&lt;br /&gt;
            for (x = 0; x &amp;lt; temp_len; x += temp_bank_stride)&lt;br /&gt;
            {&lt;br /&gt;
                gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, x + 1));&lt;br /&gt;
                ++prims_pointer;&lt;br /&gt;
            }&lt;br /&gt;
            ++bank;&lt;br /&gt;
            temp_bank=[];&lt;br /&gt;
            jump loop;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llMessageLinked(LINK_THIS, SLAVE_RESET, &amp;quot;&amp;quot; , null_key);&lt;br /&gt;
    //llOwnerSay((string)llGetFreeMemory());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
   state_entry() { &lt;br /&gt;
       // Initialize the character index. &lt;br /&gt;
       ResetCharIndex();&lt;br /&gt;
       init();&lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   link_message(integer sender, integer channel, string data, key id) { &lt;br /&gt;
        if (id==null_key)&lt;br /&gt;
            id=&amp;quot;0&amp;quot;;&lt;br /&gt;
            &lt;br /&gt;
        if (channel == DISPLAY_STRING) { &lt;br /&gt;
            PassToRender(1,data, (integer)((string)id)); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == DISPLAY_EXTENDED) { &lt;br /&gt;
            PassToRender(2,data, (integer)((string)id)); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == REMAP_INDICES) { &lt;br /&gt;
            // Parse the message, splitting it up into index values. &lt;br /&gt;
            list Parsed = llCSV2List(data); &lt;br /&gt;
            integer i = 0; &lt;br /&gt;
            // Go through the list and swap each pair of indices. &lt;br /&gt;
            for (; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
                // Swap these index values. &lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
        &lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            } &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == RESCAN_LINKSET)&lt;br /&gt;
        {&lt;br /&gt;
            init();&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) { &lt;br /&gt;
            // Restore the character index back to default settings. &lt;br /&gt;
            ResetCharIndex(); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_FADE_OPTIONS) { &lt;br /&gt;
            // Change the channel we listen to for cell commands, the &lt;br /&gt;
            // starting character position to extract from, and &lt;br /&gt;
            // special effect attributes. &lt;br /&gt;
            list Parsed = llCSV2List(data); &lt;br /&gt;
            gCellUseFading      = (integer) llList2String(Parsed, 0); &lt;br /&gt;
            gCellHoldDelay      = (float)   llList2String(Parsed, 1);&lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_FONT_TEXTURE) { &lt;br /&gt;
            // Use the new texture instead of the current one. &lt;br /&gt;
            gFontTexture = id; &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_COLOR) {&lt;br /&gt;
            change_color((vector)data); &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_LINE_COLOR) {&lt;br /&gt;
            change_line_color((integer)((string)id), (vector)data); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == REGISTER_SLAVE)&lt;br /&gt;
        {&lt;br /&gt;
            if(!~llListFindList(gSlaveNames, (list)data))&lt;br /&gt;
            {//isn&#039;t registered yet&lt;br /&gt;
                gSlaveNames += data;&lt;br /&gt;
                gSlaveRegistered=TRUE;&lt;br /&gt;
                //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave(s) Recognized: &amp;quot; + data);&lt;br /&gt;
            }&lt;br /&gt;
//            else&lt;br /&gt;
//            {//it already exists&lt;br /&gt;
//                llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave, Existing Slave Recognized: &amp;quot; + data);&lt;br /&gt;
//            }&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , null_key);&lt;br /&gt;
        }&lt;br /&gt;
    } &lt;br /&gt;
   &lt;br /&gt;
   &lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if(change&amp;amp;CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            if(gSlaveRegistered)        &lt;br /&gt;
            {&lt;br /&gt;
                //by using negative indexes they don&#039;t need to be adjusted when an entry is deleted.&lt;br /&gt;
                integer x = ~llGetListLength(gSlaveNames);&lt;br /&gt;
                while(++x)&lt;br /&gt;
                {&lt;br /&gt;
                    if (!~llGetInventoryType(llList2String(gSlaveNames, x)))&lt;br /&gt;
                    {&lt;br /&gt;
                        //llOwnerSay(&amp;quot;Slave Removed: &amp;quot; + llList2String(gSlaveNames, x));&lt;br /&gt;
                        gSlaveNames = llDeleteSubList(gSlaveNames, x, x);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                gSlaveRegistered = !(gSlaveNames == []);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Slave Script==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyText v2.0 SLAVE Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon and Gigs Taggart 5/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
integer gActive; //if we are recognized, this is true&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderExtended(integer link, string str) { &lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   integer i = 0; &lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               Token = llGetSubString(Token, 0, IndicesLeft - 1); &lt;br /&gt;
               TokenLength = llStringLength(Token); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
&lt;br /&gt;
               // This is the extended character. &lt;br /&gt;
               Indices += (llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95); &lt;br /&gt;
&lt;br /&gt;
               // These are the normal characters. &lt;br /&gt;
               integer j = 1; &lt;br /&gt;
               for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               integer j; &lt;br /&gt;
               for (j = 0; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default &lt;br /&gt;
{ &lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);  &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer num)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) &lt;br /&gt;
    { &lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_RECOGNIZED)&lt;br /&gt;
        {&lt;br /&gt;
            if (data == llGetScriptName())&lt;br /&gt;
            {&lt;br /&gt;
                gActive=TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_DISPLAY) &lt;br /&gt;
        { &lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            RenderString(llList2Integer(params, 0),data);&lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
       if (channel == SLAVE_DISPLAY_EXTENDED) &lt;br /&gt;
       {&lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            RenderExtended(llList2Integer(params, 0),data);&lt;br /&gt;
       } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == SET_FONT_TEXTURE) &lt;br /&gt;
        { &lt;br /&gt;
           gFontTexture = id; &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == REMAP_INDICES) { &lt;br /&gt;
           // Parse the message, splitting it up into index values. &lt;br /&gt;
           list Parsed = llCSV2List(data); &lt;br /&gt;
           integer i; &lt;br /&gt;
           // Go through the list and swap each pair of indices. &lt;br /&gt;
           for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
               integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
               integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
               // Swap these index values. &lt;br /&gt;
               string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index1, Value2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index2, Value1); &lt;br /&gt;
           } &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == RESET_INDICES) { &lt;br /&gt;
           // Restore the character index back to default settings. &lt;br /&gt;
           ResetCharIndex(); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        if (channel == SLAVE_RESET)&lt;br /&gt;
        {&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            gActive=FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Prim Setup==&lt;br /&gt;
&#039;&#039;&#039;(Caution!  Not compatible with 5 face double texture Xytext)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText Prim Setup Script (5 Face)&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon&lt;br /&gt;
//&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        llSetPrimitiveParams([&lt;br /&gt;
                    PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_DEFAULT, &amp;lt;0.199, 0.8, 0.0&amp;gt;, 0.68, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &lt;br /&gt;
                    PRIM_SIZE, &amp;lt;0.03, 2.89, 0.5&amp;gt;, &lt;br /&gt;
                    PRIM_TEXTURE, 1, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.740013, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 6, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 4, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;-0.740, 0.10, 0.00&amp;gt;, &amp;lt;0.130009, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 7, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 3, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.255989, 0.0, 0.0&amp;gt;, 0.0]);&lt;br /&gt;
                    &lt;br /&gt;
        llRemoveInventory(llGetScriptName());&lt;br /&gt;
    } &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= How to produce textures with alternative fonts for 5 character version (Photoshop VBscript version) =&lt;br /&gt;
&lt;br /&gt;
Note: If you need to use XyzzyText for European or UTF-8 other languages, please see the following link: [[XyzzyText-UTF8]]&lt;br /&gt;
Use the following section for GIMP script-fu if you prefer opensource alternative. Use the following link: [[ZZText]] for an alternative international solution (still based on xytext and xyzzytext) using even fewer textures and lag than the xytext solution.&lt;br /&gt;
&lt;br /&gt;
If you need to display with another font, italics or other characters, you can do the following :)&lt;br /&gt;
&lt;br /&gt;
Using Photoshop VB Scripting on windows, just open up Photoshop CS3, and create with notepad the following MakeFonts.vbs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim appRef&lt;br /&gt;
Set appRef = CreateObject( &amp;quot;Photoshop.Application&amp;quot; )&lt;br /&gt;
&#039; Remember current unit settings and then set units to&lt;br /&gt;
&#039; the value expected by this script&lt;br /&gt;
Dim originalRulerUnits&lt;br /&gt;
originalRulerUnits = appRef.Preferences.RulerUnits&lt;br /&gt;
appRef.Preferences.RulerUnits = 1 &#039; psPixels&lt;br /&gt;
&#039; Create a new 512*512 pixel document and assign it to a variable.&lt;br /&gt;
Dim docRef&lt;br /&gt;
Dim artLayerRef&lt;br /&gt;
Dim textItemRef&lt;br /&gt;
dim rows(10)&lt;br /&gt;
rows(1)=&amp;quot; !&amp;quot;&amp;quot;#$%&amp;amp;&#039;()&amp;quot;&lt;br /&gt;
rows(2)=&amp;quot;*+,-./0123&amp;quot;&lt;br /&gt;
rows(3)=&amp;quot;456789:;&amp;lt;=&amp;quot;&lt;br /&gt;
rows(4)=&amp;quot;&amp;gt;?@ABCDEFG&amp;quot;&lt;br /&gt;
rows(5)=&amp;quot;HIJKLMNOPQ&amp;quot;&lt;br /&gt;
rows(6)=&amp;quot;RSTUVWXYZ[&amp;quot;&lt;br /&gt;
rows(7)=&amp;quot;\]^_`abcde&amp;quot;&lt;br /&gt;
rows(8)=&amp;quot;fghijklmno&amp;quot;&lt;br /&gt;
rows(9)=&amp;quot;pqrstuvwxy&amp;quot;&lt;br /&gt;
rows(10)=&amp;quot;z{|}~·ΘΩ√&amp;quot;      &lt;br /&gt;
&lt;br /&gt;
dim fontname&lt;br /&gt;
fontname=&amp;quot;Courier&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Set docRef = appRef.Documents.Add(512, 512, 72, &amp;quot;Table for font &amp;quot; &amp;amp; fontname, 2, 3, 1)&lt;br /&gt;
&#039; Create a new art layer containing text&lt;br /&gt;
Dim colorObj&lt;br /&gt;
Set colorObj=CreateObject(&amp;quot;Photoshop.SolidColor&amp;quot;)&lt;br /&gt;
colorObj.RGB.Red=255&lt;br /&gt;
colorObj.RGB.Green=255&lt;br /&gt;
colorObj.RGB.Blue=255&lt;br /&gt;
&#039; Set the contents of the text layer.&lt;br /&gt;
for i=1 to 10&lt;br /&gt;
   for j=1 to 10&lt;br /&gt;
     Set artLayerRef = docRef.ArtLayers.Add&lt;br /&gt;
     artLayerRef.Kind = 2&lt;br /&gt;
     Set textItemRef = artLayerRef.TextItem&lt;br /&gt;
     &#039; textItemRef.Font = fontname&lt;br /&gt;
     textItemRef.Color=colorObj&lt;br /&gt;
     textItemRef.Justification = 2 &lt;br /&gt;
     textItemRef.Font = &amp;quot;A Charming Font&amp;quot;&lt;br /&gt;
     textItemRef.Size = 38&lt;br /&gt;
     textItemRef.Contents = mid(rows(i),j,1)&lt;br /&gt;
     textItemRef.Position = Array((j-1)*51.2+25,i*51.2-7)&lt;br /&gt;
   next&lt;br /&gt;
next&lt;br /&gt;
&#039; Restore unit settingPhotoshop CS3&lt;br /&gt;
appRef.Preferences.RulerUnits = originalRulerUnits&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just click on the file in internet explorer and it will start working with your photoshop (I&#039;ll take a bit to display all the 100 characters, maybe around 1 sec for character).&lt;br /&gt;
&lt;br /&gt;
This will layout the 100 characters in photoshop on 100 different layers. Then do the following:&lt;br /&gt;
&lt;br /&gt;
* select all the layers with text and go to Text tool and change to whatever font (size etc) you want&lt;br /&gt;
* maybe need to add a black layer to see your fonts :) (after you have to hid or delete this)&lt;br /&gt;
* merge all the layers in just one&lt;br /&gt;
* add an alpha channel for transparency (all black)&lt;br /&gt;
* select all in the merged text layer and copy it to alpha channel&lt;br /&gt;
* enable the alpha channel and the RGB channel so that you see your font set and the transparent red&lt;br /&gt;
* save the font as TGA preserving alpha channel&lt;br /&gt;
* upload it to SecondLife 10 L$&lt;br /&gt;
* get the UUID from the inventory and specify it instead of the standard template.&lt;br /&gt;
&lt;br /&gt;
= How to produce textures with alternative fonts for 5 character version (GIMP script-fu version) =&lt;br /&gt;
&lt;br /&gt;
Use the following script for generating characters with GIMP:&lt;br /&gt;
&lt;br /&gt;
To use it you must put under the $HOME/.gimpXXX/scripts directory and name it something.scm.&lt;br /&gt;
Then you will find it under gimp &amp;lt;Toolbox&amp;gt;/Xtns/Script-Fu/Text. Clicking on it you are prompted for font to use (use monospaced fonts Andale Mono for instance). (Change only font and fontsize 50 should be ok, others are hard-coded in the script). Adapt with new unicode characters if you need them.&lt;br /&gt;
&lt;br /&gt;
Note: If you need to use XyzzyText for European or UTF-8 other languages, please see the following link: [[XyzzyText-UTF8]]&lt;br /&gt;
Use the following section for GIMP script-fu if you prefer opensource alternative. Use the following link: [[ZZText]] for an alternative international solution (still based on xytext and xyzzytext) using even fewer textures and lag than the xytext solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
(define (script-fu-xytext-simple inText inFont inFontSize inTextColor)&lt;br /&gt;
   (let*&lt;br /&gt;
       (&lt;br /&gt;
       ; define our local variables&lt;br /&gt;
       ; create a new image:&lt;br /&gt;
       (theImageWidth  512)&lt;br /&gt;
       (theImageHeight 512)&lt;br /&gt;
       (theImage)&lt;br /&gt;
       (theLayer )&lt;br /&gt;
       (x 0)&lt;br /&gt;
       (y 0)&lt;br /&gt;
       (p 32)&lt;br /&gt;
       (theText)&lt;br /&gt;
       (rows #(&lt;br /&gt;
               &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()&amp;quot;&lt;br /&gt;
               &amp;quot;*+,-./0123&amp;quot;&lt;br /&gt;
               &amp;quot;456789:;&amp;lt;=&amp;quot;&lt;br /&gt;
               &amp;quot;&amp;gt;?@ABCDEFG&amp;quot;&lt;br /&gt;
               &amp;quot;HIJKLMNOPQ&amp;quot;&lt;br /&gt;
               &amp;quot;RSTUVWXYZ[&amp;quot;&lt;br /&gt;
               &amp;quot;\\]^_`abcde&amp;quot;&lt;br /&gt;
               &amp;quot;fghijklmno&amp;quot;&lt;br /&gt;
               &amp;quot;pqrstuvwxy&amp;quot;&lt;br /&gt;
&lt;br /&gt;
               ;&amp;quot;z{|}~·thetaOmegaRadix.o &amp;quot;&lt;br /&gt;
               (list #\z #\{ #\| #\} #\~ #x387 #x3F4 #x3A9r #x221A #x387 )&lt;br /&gt;
              )&lt;br /&gt;
       )&lt;br /&gt;
       (el 0)&lt;br /&gt;
       (ch 0)&lt;br /&gt;
       ) ;end of our local variables&lt;br /&gt;
&lt;br /&gt;
  ; builds image&lt;br /&gt;
  (set! theImage (car    (gimp-image-new theImageWidth theImageHeight RGB)))&lt;br /&gt;
  ; builds layer&lt;br /&gt;
  (set! theLayer (car (gimp-layer-new theImage theImageWidth theImageHeight RGB-IMAGE &amp;quot;layer 1&amp;quot; 100 NORMAL) ) )&lt;br /&gt;
  ; add layer to image&lt;br /&gt;
  (gimp-image-add-layer theImage theLayer 0)&lt;br /&gt;
&lt;br /&gt;
  ; add alpha and set foreground&lt;br /&gt;
  (gimp-layer-add-alpha theLayer)&lt;br /&gt;
  (gimp-palette-set-foreground inTextColor)&lt;br /&gt;
&lt;br /&gt;
  ; clear all the image and remove selection&lt;br /&gt;
  (gimp-selection-all theImage)&lt;br /&gt;
  (gimp-edit-clear theLayer)&lt;br /&gt;
  (gimp-selection-none theImage)&lt;br /&gt;
&lt;br /&gt;
  ; do actual plot of characters&lt;br /&gt;
  (while (&amp;lt; x 10)&lt;br /&gt;
    (while (&amp;lt; y 10)&lt;br /&gt;
      (set! el (vector-ref rows x))&lt;br /&gt;
      (set! ch (if (string? el) (substring el y (+ y 1)) (list-ref el (+ y 1))))&lt;br /&gt;
      (if (integer? ch) (set! ch (integer-&amp;gt;char ch)))&lt;br /&gt;
      (if (char? ch)(set! ch (string ch)))&lt;br /&gt;
      (set! p ch)&lt;br /&gt;
      (set! theText (car (gimp-text-fontname theImage theLayer&lt;br /&gt;
          (+ (* y 51.2) 12) (- (* x 51.2) 7)&lt;br /&gt;
          p    0    TRUE&lt;br /&gt;
          inFontSize PIXELS&lt;br /&gt;
          inFont)))&lt;br /&gt;
&lt;br /&gt;
        ; go on next char&lt;br /&gt;
        ;(set! p (+ p 1))&lt;br /&gt;
        (set! y (+ y 1))&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
    (set! y 0)&lt;br /&gt;
    (set! x (+ x 1))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  ; apply the layers (apply transparence&lt;br /&gt;
  (gimp-image-merge-visible-layers theImage 0)&lt;br /&gt;
&lt;br /&gt;
  (gimp-display-new theImage)&lt;br /&gt;
  )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(script-fu-register&lt;br /&gt;
  &amp;quot;script-fu-xytext-simple&amp;quot;           ;func name&lt;br /&gt;
  &amp;quot;XYText-simple&amp;quot;                     ;menu label&lt;br /&gt;
  &amp;quot;Generate font for xytext-simple&amp;quot;   ;description&lt;br /&gt;
  &amp;quot;Salahzar Stenvaag&amp;quot;                 ;author&lt;br /&gt;
  &amp;quot;copyright 2008, Salahzar Stenvaag&amp;quot; ;copyright notice&lt;br /&gt;
  &amp;quot;October 27, 1997&amp;quot;                  ;date created&lt;br /&gt;
  &amp;quot;&amp;quot;                                  ;image type that the script works on&lt;br /&gt;
  SF-STRING      &amp;quot;Text:&amp;quot;         &amp;quot;Text Box&amp;quot;           ;a string variable&lt;br /&gt;
  SF-FONT        &amp;quot;Font:&amp;quot;         &amp;quot;Andale Mono&amp;quot;        ;a fixed font variable&lt;br /&gt;
  SF-ADJUSTMENT  &amp;quot;Font size&amp;quot;     &#039;(50 1 1000 1 10 0 1);a spin-button&lt;br /&gt;
  SF-COLOR       &amp;quot;Color:&amp;quot;        &#039;(255 255 255)       ;color variable&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(script-fu-menu-register &amp;quot;script-fu-xytext-simple&amp;quot; &amp;quot;&amp;lt;Toolbox&amp;gt;/Xtns/Text&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= XyzzyText - 10 Character =&lt;br /&gt;
&lt;br /&gt;
== Master Script ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyzzyText v2.1(10-Char) by Thraxis Epsilon&lt;br /&gt;
// XyzzyText v2.1 Script (Set Line Color) by Huney Jewell&lt;br /&gt;
// XyzzyText v2.0 Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
// Enabled 10-char per prim&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Core XyText Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS /////////////////// &lt;br /&gt;
// XyText Message Map. &lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET         = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence.&lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character.&lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1;&lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out. &lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;;&lt;br /&gt;
key     null_key        = NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
// This is a list of textures for all 2-character combinations. &lt;br /&gt;
list    CHARACTER_GRID  = [ &lt;br /&gt;
        &amp;quot;00e9f9f7-0669-181c-c192-7f8e67678c8d&amp;quot;, &lt;br /&gt;
        &amp;quot;347a5cb6-0031-7ec0-2fcf-f298eebf3c0e&amp;quot;, &lt;br /&gt;
        &amp;quot;4e7e689e-37f1-9eca-8596-a958bbd23963&amp;quot;, &lt;br /&gt;
        &amp;quot;19ea9c21-67ba-8f6f-99db-573b1b877eb1&amp;quot;, &lt;br /&gt;
        &amp;quot;dde7b412-cda1-652f-6fc2-73f4641f96e1&amp;quot;, &lt;br /&gt;
        &amp;quot;af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da&amp;quot;, &lt;br /&gt;
        &amp;quot;a201d3a2-364b-43b6-8686-5881c0f82a94&amp;quot;, &lt;br /&gt;
        &amp;quot;b674dec8-fead-99e5-c28d-2db8e4c51540&amp;quot;, &lt;br /&gt;
        &amp;quot;366e05f3-be6b-e5cf-c33b-731dff649caa&amp;quot;, &lt;br /&gt;
        &amp;quot;75c4925c-0427-dc0c-c71c-e28674ff4d27&amp;quot;, &lt;br /&gt;
        &amp;quot;dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6&amp;quot;, &lt;br /&gt;
        &amp;quot;0dca2feb-fc66-a762-db85-89026a4ecd68&amp;quot;, &lt;br /&gt;
        &amp;quot;a0fca76f-503a-946b-9336-0a918e886f7a&amp;quot;, &lt;br /&gt;
        &amp;quot;67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4&amp;quot;, &lt;br /&gt;
        &amp;quot;300470b2-da34-5470-074c-1b8464ca050c&amp;quot;, &lt;br /&gt;
        &amp;quot;d1f8e91c-ce2b-d85e-2120-930d3b630946&amp;quot;, &lt;br /&gt;
        &amp;quot;2a190e44-7b29-dadb-0bff-c31adaf5a170&amp;quot;, &lt;br /&gt;
        &amp;quot;75d55e71-f6f8-9835-e746-a45f189f30a1&amp;quot;, &lt;br /&gt;
        &amp;quot;300fac33-2b30-3da3-26bc-e2d70428ec19&amp;quot;, &lt;br /&gt;
        &amp;quot;0747c776-011a-53ce-13ee-8b5bb9e87c1e&amp;quot;, &lt;br /&gt;
        &amp;quot;85a855c3-a94f-01ca-33e0-7dde92e727e2&amp;quot;, &lt;br /&gt;
        &amp;quot;cbc1dab2-2d61-2986-1949-7a5235c954e1&amp;quot;, &lt;br /&gt;
        &amp;quot;f7aef047-f266-9596-16df-641010edd8e1&amp;quot;, &lt;br /&gt;
        &amp;quot;4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a69e98c-26a5-ad05-e92e-b5b906ad9ef9&amp;quot;, &lt;br /&gt;
        &amp;quot;462a9226-2a97-91ac-2d89-57ab33334b78&amp;quot;, &lt;br /&gt;
        &amp;quot;20b24b3a-8c57-82ee-c6ed-555003f5dbcd&amp;quot;, &lt;br /&gt;
        &amp;quot;9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217&amp;quot;, &lt;br /&gt;
        &amp;quot;c231dbdc-c842-15b0-7aa6-6da14745cfdc&amp;quot;, &lt;br /&gt;
        &amp;quot;c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf&amp;quot;, &lt;br /&gt;
        &amp;quot;f1e7d030-ff80-a242-cb69-f6951d4eae3b&amp;quot;, &lt;br /&gt;
        &amp;quot;ed32d6c4-d733-c0f1-f242-6df1d222220d&amp;quot;, &lt;br /&gt;
        &amp;quot;88f96a30-dccf-9b20-31ef-da0dfeb23c72&amp;quot;, &lt;br /&gt;
        &amp;quot;252f2595-58b8-4bcc-6515-fa274d0cfb65&amp;quot;, &lt;br /&gt;
        &amp;quot;f2838c4f-de80-cced-dff8-195dfdf36b2c&amp;quot;, &lt;br /&gt;
        &amp;quot;cc2594fe-add2-a3df-cdb3-a61711badf53&amp;quot;, &lt;br /&gt;
        &amp;quot;e0ce2972-da00-955c-129e-3289b3676776&amp;quot;, &lt;br /&gt;
        &amp;quot;3e0d336d-321f-ddfa-5c1b-e26131766f6a&amp;quot;, &lt;br /&gt;
        &amp;quot;d43b1dc4-6b51-76a7-8b90-38865b82bf06&amp;quot;, &lt;br /&gt;
        &amp;quot;06d16cbb-1868-fd1d-5c93-eae42164a37d&amp;quot;, &lt;br /&gt;
        &amp;quot;dd5d98cf-273e-3fd0-f030-48be58ee3a0b&amp;quot;, &lt;br /&gt;
        &amp;quot;0e47c89e-de4a-6233-a2da-cb852aad1b00&amp;quot;, &lt;br /&gt;
        &amp;quot;fb9c4a55-0e13-495b-25c4-f0b459dc06de&amp;quot;, &lt;br /&gt;
        &amp;quot;e3ce8def-312c-735b-0e48-018b6799c883&amp;quot;, &lt;br /&gt;
        &amp;quot;2f713216-4e71-d123-03ed-9c8554710c6b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a417d8a-1f4f-404b-9783-6672f8527911&amp;quot;, &lt;br /&gt;
        &amp;quot;ca5e21ec-5b20-5909-4c31-3f90d7316b33&amp;quot;, &lt;br /&gt;
        &amp;quot;06a4fcc3-e1c4-296d-8817-01f88fbd7367&amp;quot;, &lt;br /&gt;
        &amp;quot;130ac084-6f3c-95de-b5b6-d25c80703474&amp;quot;, &lt;br /&gt;
        &amp;quot;59d540a0-ae9d-3606-5ae0-4f2842b64cfa&amp;quot;, &lt;br /&gt;
        &amp;quot;8612ae9a-f53c-5bf4-2899-8174d7abc4fd&amp;quot;, &lt;br /&gt;
        &amp;quot;12467401-e979-2c49-34e0-6ac761542797&amp;quot;, &lt;br /&gt;
        &amp;quot;d53c3eaa-0404-3860-0675-3e375596c3e3&amp;quot;, &lt;br /&gt;
        &amp;quot;9f5b26bd-81d3-b25e-62fe-5b671d1e3e79&amp;quot;, &lt;br /&gt;
        &amp;quot;f57f0b64-a050-d617-ee00-c8e9e3adc9cb&amp;quot;, &lt;br /&gt;
        &amp;quot;beff166a-f5f3-f05e-e020-98f2b00e27ed&amp;quot;, &lt;br /&gt;
        &amp;quot;02278a65-94ba-6d5e-0d2b-93f2e4f4bf70&amp;quot;, &lt;br /&gt;
        &amp;quot;a707197d-449e-5b58-846c-0c850c61f9d6&amp;quot;, &lt;br /&gt;
        &amp;quot;021d4b1a-9503-a44f-ee2b-976eb5d80e68&amp;quot;, &lt;br /&gt;
        &amp;quot;0ae2ffae-7265-524d-cb76-c2b691992706&amp;quot;];&lt;br /&gt;
list    CHARACTER_GRID2  = [         &lt;br /&gt;
        &amp;quot;f6e41cf2-1104-bd0b-0190-dffad1bac813&amp;quot;, &lt;br /&gt;
        &amp;quot;2b4bb15e-956d-56ae-69f5-d26a20de0ce7&amp;quot;, &lt;br /&gt;
        &amp;quot;f816da2c-51f1-612a-2029-a542db7db882&amp;quot;, &lt;br /&gt;
        &amp;quot;345fea05-c7be-465c-409f-9dcb3bd2aa07&amp;quot;, &lt;br /&gt;
        &amp;quot;b3017e02-c063-5185-acd5-1ef5f9d79b89&amp;quot;, &lt;br /&gt;
        &amp;quot;4dcff365-1971-3c2b-d73c-77e1dc54242a&amp;quot; &lt;br /&gt;
          ]; &lt;br /&gt;
&lt;br /&gt;
///////////// END CONSTANTS ////////////////&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
// This is the channel to listen on while acting &lt;br /&gt;
// as a cell in a larger display. &lt;br /&gt;
integer gCellChannel      = -1; &lt;br /&gt;
// This is the starting character position in the cell channel message &lt;br /&gt;
// to render. &lt;br /&gt;
integer gCellCharPosition = 0;&lt;br /&gt;
// This is whether or not to use the fade in/out special effect. &lt;br /&gt;
integer gCellUseFading      = FALSE; &lt;br /&gt;
// This is how long to display the text before fading out (if using &lt;br /&gt;
// fading special effect). &lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out. &lt;br /&gt;
float   gCellHoldDelay      = 1.0; &lt;br /&gt;
&lt;br /&gt;
integer gSlaveRegistered;&lt;br /&gt;
list gSlaveNames;&lt;br /&gt;
&lt;br /&gt;
integer BANK_STRIDE=3; //offset, length, highest_dirty&lt;br /&gt;
list gBankingData;&lt;br /&gt;
&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug. &lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
    gCharIndex += &amp;quot;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridPos(integer index1, integer index2) { &lt;br /&gt;
    // There are two ways to use the lookup table... &lt;br /&gt;
    integer Col; &lt;br /&gt;
    integer Row; &lt;br /&gt;
    if (index1 &amp;gt;= index2) { &lt;br /&gt;
        // In this case, the row is the index of the first character: &lt;br /&gt;
        Row = index1; &lt;br /&gt;
        // And the col is the index of the second character (x2) &lt;br /&gt;
        Col = index2 * 2; &lt;br /&gt;
    } &lt;br /&gt;
    else { // Index1 &amp;lt; Index2 &lt;br /&gt;
        // In this case, the row is the index of the second character: &lt;br /&gt;
        Row = index2; &lt;br /&gt;
        // And the col is the index of the first character, x2, offset by 1. &lt;br /&gt;
        Col = index1 * 2 + 1; &lt;br /&gt;
    } &lt;br /&gt;
    return &amp;lt;Col, Row, 0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
string GetGridTexture(vector grid_pos) { &lt;br /&gt;
    // Calculate the texture in the grid to use. &lt;br /&gt;
    integer GridCol = llRound(grid_pos.x) / 20; &lt;br /&gt;
    integer GridRow = llRound(grid_pos.y) / 10; &lt;br /&gt;
&lt;br /&gt;
    // Lookup the texture. &lt;br /&gt;
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol); &lt;br /&gt;
    return Texture; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(vector grid_pos) { &lt;br /&gt;
    // Zoom in on the texture showing our character pair. &lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 20; &lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 10; &lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture. &lt;br /&gt;
    return &amp;lt;-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
     &lt;br /&gt;
               &lt;br /&gt;
   llSetLinkPrimitiveParams( link , [ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters. &lt;br /&gt;
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   &lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//RenderWithEffects(integer link, string str) { &lt;br /&gt;
//    // Get the grid positions for each pair of characters. &lt;br /&gt;
//    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
//    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
//    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
//    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
//    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                          //         &lt;br /&gt;
//&lt;br /&gt;
//      // First set the alpha to the lowest possible. &lt;br /&gt;
//   llSetAlpha(0.05, ALL_SIDES); &lt;br /&gt;
//&lt;br /&gt;
//    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
//    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
//&lt;br /&gt;
//    float Alpha = 0.10; &lt;br /&gt;
//    for (; Alpha &amp;lt;= 1.0; Alpha += 0.05)  &lt;br /&gt;
//       llSetAlpha(Alpha, ALL_SIDES); &lt;br /&gt;
//          // See if we want to fade out as well. &lt;br /&gt;
//   if (gCellHoldDelay &amp;lt; 0.0) &lt;br /&gt;
//       // No, bail out. (Just keep showing the string at full strength). &lt;br /&gt;
//       return; &lt;br /&gt;
//          // Hold the text for a while. &lt;br /&gt;
//   llSleep(gCellHoldDelay); &lt;br /&gt;
//      // Now fade out. &lt;br /&gt;
//   for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05) &lt;br /&gt;
//       llSetAlpha(Alpha, ALL_SIDES); &lt;br /&gt;
//          // Make the text transparent to fully hide it. &lt;br /&gt;
//   llSetTexture(TRANSPARENT, ALL_SIDES); &lt;br /&gt;
//} &lt;br /&gt;
&lt;br /&gt;
integer RenderExtended(integer link, string str,integer render) {&lt;br /&gt;
    // Look for escape sequences.&lt;br /&gt;
    integer length = 0;&lt;br /&gt;
    list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);&lt;br /&gt;
    integer ParsedLen = llGetListLength(Parsed);&lt;br /&gt;
&lt;br /&gt;
    // Create a list of index values to work with.&lt;br /&gt;
    list Indices;&lt;br /&gt;
    // We start with room for 6 indices.&lt;br /&gt;
    integer IndicesLeft = 10;&lt;br /&gt;
&lt;br /&gt;
    string Token;&lt;br /&gt;
    integer Clipped;&lt;br /&gt;
    integer LastWasEscapeSequence = FALSE;&lt;br /&gt;
    // Work from left to right.&lt;br /&gt;
    integer i=0;&lt;br /&gt;
    for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) {&lt;br /&gt;
        Token = llList2String(Parsed, i);&lt;br /&gt;
&lt;br /&gt;
        // If this is an escape sequence, just set the flag and move on.&lt;br /&gt;
        if (Token == ESCAPE_SEQUENCE) {&lt;br /&gt;
            LastWasEscapeSequence = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else { // Token != ESCAPE_SEQUENCE&lt;br /&gt;
            // Otherwise this is a normal token.  Check its length.&lt;br /&gt;
            Clipped = FALSE;&lt;br /&gt;
            integer TokenLength = llStringLength(Token);&lt;br /&gt;
            // Clip if necessary.&lt;br /&gt;
            if (TokenLength &amp;gt; IndicesLeft) {&lt;br /&gt;
                TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));&lt;br /&gt;
                IndicesLeft = 0;&lt;br /&gt;
                Clipped = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                IndicesLeft -= TokenLength;&lt;br /&gt;
&lt;br /&gt;
            // Was the previous token an escape sequence?&lt;br /&gt;
            if (LastWasEscapeSequence) {&lt;br /&gt;
                // Yes, the first character is an escape character, the rest are normal.&lt;br /&gt;
                length += 2 + TokenLength;&lt;br /&gt;
                if (render)&lt;br /&gt;
                {&lt;br /&gt;
                    // This is the extended character.&lt;br /&gt;
                    Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];&lt;br /&gt;
                    &lt;br /&gt;
                    // These are the normal characters.&lt;br /&gt;
                    integer j=1;&lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                    {&lt;br /&gt;
                        Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else { // Normal string.&lt;br /&gt;
                // Just add the characters normally.&lt;br /&gt;
                length += TokenLength;&lt;br /&gt;
                if(render)&lt;br /&gt;
                {&lt;br /&gt;
                    integer j=0;&lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                    {&lt;br /&gt;
                        Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Unset this flag, since this was not an escape sequence.&lt;br /&gt;
            LastWasEscapeSequence = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(render)&lt;br /&gt;
    {&lt;br /&gt;
        // Use the indices to create grid positions.&lt;br /&gt;
        vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );&lt;br /&gt;
        vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );&lt;br /&gt;
        vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );&lt;br /&gt;
        vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );&lt;br /&gt;
        vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );&lt;br /&gt;
        &lt;br /&gt;
        // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
        ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
    }&lt;br /&gt;
    return length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) {&lt;br /&gt;
    // This converts from an ASCII based index to our indexing scheme.&lt;br /&gt;
    if (index &amp;gt;= 32) // &#039; &#039; or higher&lt;br /&gt;
        index -= 32;&lt;br /&gt;
    else { // index &amp;lt; 32&lt;br /&gt;
        // Quick bounds check.&lt;br /&gt;
        if (index &amp;gt; 15)&lt;br /&gt;
            index = 15;&lt;br /&gt;
&lt;br /&gt;
        index += 94; // extended characters&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return index;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PassToRender(integer render,string message, integer bank)&lt;br /&gt;
{&lt;br /&gt;
    float time;&lt;br /&gt;
    integer extendedlen = 0;&lt;br /&gt;
    integer link;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer msgLen = llStringLength(message);&lt;br /&gt;
    string TextToRender;&lt;br /&gt;
    integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
    string slave_name; //avoids unnecessary casts, keeping it as a string&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
    integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
&lt;br /&gt;
    integer x=0;    &lt;br /&gt;
    for (;x &amp;lt; msgLen;x = x + 10)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;gt;= bank_length)  //we don&#039;t want to run off the end of the bank&lt;br /&gt;
        {&lt;br /&gt;
            //set the dirty to max, and bail out, we&#039;re done&lt;br /&gt;
            gBankingData=llListReplaceList(gBankingData, [bank_length], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
            return;&lt;br /&gt;
        }   &lt;br /&gt;
        &lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        TextToRender = llGetSubString(message, x, x + 20);&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves +1)))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if(llSubStringIndex(TextToRender,&amp;quot;\e&amp;quot;)&amp;gt;x+10)&lt;br /&gt;
                {&lt;br /&gt;
                    extendedlen = 10;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    extendedlen = RenderExtended(link,TextToRender,0);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if(extendedlen&amp;gt;10)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen-10;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                llMessageLinked(LINK_THIS,SLAVE_DISPLAY_EXTENDED,TextToRender,(key)((string)link+&amp;quot;,&amp;quot;+slave_name));&lt;br /&gt;
            }        &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                RenderString(link,TextToRender);&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                extendedlen = RenderExtended(link,TextToRender,1);&lt;br /&gt;
                if(extendedlen&amp;gt;10)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen-10;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
//            if (render == 3)&lt;br /&gt;
//                RenderWithEffects(link,TextToRender);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;            &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (bank_highest_dirty==0)&lt;br /&gt;
        bank_highest_dirty=bank_length;&lt;br /&gt;
    &lt;br /&gt;
    integer current_highest_dirty=i;&lt;br /&gt;
    while (i &amp;lt; bank_highest_dirty)&lt;br /&gt;
    {&lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves+1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_DISPLAY, &amp;quot;     &amp;quot;, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));       &lt;br /&gt;
            //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            RenderString(link,&amp;quot;          &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;        &lt;br /&gt;
    }&lt;br /&gt;
    gBankingData=llListReplaceList(gBankingData, [current_highest_dirty], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka&lt;br /&gt;
list gXyTextPrims;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer get_number_of_prims()&lt;br /&gt;
{//ignores avatars.&lt;br /&gt;
    integer a = llGetNumberOfPrims();&lt;br /&gt;
    while(llGetAgentSize(llGetLinkKey(a)))&lt;br /&gt;
        --a;&lt;br /&gt;
    return a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//functions to pack 8-bit shorts into ints&lt;br /&gt;
list pack_and_insert(list in_list, integer pos, integer value)&lt;br /&gt;
{&lt;br /&gt;
//    //figure out the bitpack position&lt;br /&gt;
//    integer pack = pos &amp;amp; 3; //4 bytes per int&lt;br /&gt;
//    pos=pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
//    integer shifted = value &amp;lt;&amp;lt; (pack &amp;lt;&amp;lt; 3);&lt;br /&gt;
//    integer old_value = llList2Integer(in_list, pos);&lt;br /&gt;
//    shifted = old_value | shifted;&lt;br /&gt;
//    in_list = llListReplaceList(in_list, (list)shifted, pos, pos);&lt;br /&gt;
//    return in_list;&lt;br /&gt;
    //Safe optimized version&lt;br /&gt;
    integer index = pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
    return llListReplaceList(in_list, (list)(llList2Integer(in_list, index) | (value &amp;lt;&amp;lt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3))), index, index);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer unpack(list in_list, integer pos)&lt;br /&gt;
{&lt;br /&gt;
    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;gt;&amp;gt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;amp; 0x000000FF;//unsigned&lt;br /&gt;
//    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;lt;&amp;lt; (((~pos) &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;gt;&amp;gt; 24;//signed&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
change_color(vector color)&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=llGetListLength(gXyTextPrims) &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    &lt;br /&gt;
    for (; i&amp;lt;=num_prims; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_line_color(integer bank, vector color)&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
&lt;br /&gt;
    for (; i &amp;lt; bank_end; ++i)&lt;br /&gt;
    {     &lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
init()&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=get_number_of_prims();&lt;br /&gt;
&lt;br /&gt;
    string link_name;&lt;br /&gt;
    integer bank=0;&lt;br /&gt;
    integer bank_empty=FALSE;&lt;br /&gt;
    integer prims_pointer=0; //&amp;quot;pointer&amp;quot; to the next entry to be used in the gXyTextPrims list.&lt;br /&gt;
    &lt;br /&gt;
    list temp_bank=[];&lt;br /&gt;
    integer temp_bank_stride=2;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
    gXyTextPrims=[];&lt;br /&gt;
    integer x=0;&lt;br /&gt;
    for (;x&amp;lt;64;++x)&lt;br /&gt;
    {&lt;br /&gt;
        gXyTextPrims= (gXyTextPrims = []) + gXyTextPrims + [0];  //we need to pad out the list to make it easier to add things in any order later&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @loop;&lt;br /&gt;
    &lt;br /&gt;
    {&lt;br /&gt;
       &lt;br /&gt;
        //loop over all prims, looking for ones in the current bank&lt;br /&gt;
        for(x=0;x&amp;lt;=num_prims;++x)&lt;br /&gt;
        {&lt;br /&gt;
            link_name=llGetLinkName(x);&lt;br /&gt;
            list tmp = llParseString2List(link_name, [&amp;quot;-&amp;quot;], []);&lt;br /&gt;
            if(llList2String(tmp,0)== &amp;quot;xyzzytext&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                integer prims_bank=llList2Integer(tmp,1);&lt;br /&gt;
                if (llList2Integer(tmp,1)==bank)&lt;br /&gt;
                {&lt;br /&gt;
                    temp_bank+=llList2Integer(tmp,2) + (list)x;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
        if (temp_bank!=[])&lt;br /&gt;
        {&lt;br /&gt;
            //sort the current bank&lt;br /&gt;
            temp_bank=llListSort(temp_bank, temp_bank_stride, TRUE);&lt;br /&gt;
            &lt;br /&gt;
            integer temp_len=llGetListLength(temp_bank);&lt;br /&gt;
            &lt;br /&gt;
            //store metadata&lt;br /&gt;
            gBankingData+=[prims_pointer,temp_len/temp_bank_stride,0];&lt;br /&gt;
            &lt;br /&gt;
            //repack the bank into the prim list&lt;br /&gt;
            for (x=0; x &amp;lt; temp_len; x+=temp_bank_stride)&lt;br /&gt;
            {&lt;br /&gt;
                gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, x+1));&lt;br /&gt;
                ++prims_pointer;&lt;br /&gt;
            }&lt;br /&gt;
            ++bank;&lt;br /&gt;
            temp_bank=[];&lt;br /&gt;
            jump loop;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llMessageLinked(LINK_THIS, SLAVE_RESET, &amp;quot;&amp;quot; , null_key);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
    state_entry() { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        init();&lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) {&lt;br /&gt;
        if(id == null_key)&lt;br /&gt;
            id=&amp;quot;0&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        if (channel == DISPLAY_STRING) { &lt;br /&gt;
            PassToRender(1,data, (integer)((string)id)); &lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == DISPLAY_EXTENDED) { &lt;br /&gt;
             PassToRender(2,data, (integer)((string)id)); &lt;br /&gt;
            return; &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == REMAP_INDICES) {&lt;br /&gt;
            // Parse the message, splitting it up into index values.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            integer i;&lt;br /&gt;
            // Go through the list and swap each pair of indices.&lt;br /&gt;
            for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) {&lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );&lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );&lt;br /&gt;
&lt;br /&gt;
                // Swap these index values.&lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) {&lt;br /&gt;
            // Restore the character index back to default settings.&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            return;&lt;br /&gt;
        }        &lt;br /&gt;
        else if (channel == RESCAN_LINKSET)&lt;br /&gt;
        {&lt;br /&gt;
            init();&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_COLOR) {&lt;br /&gt;
            change_color((vector)data); &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_LINE_COLOR) {&lt;br /&gt;
            change_line_color((integer)((string)id), (vector)data); &lt;br /&gt;
        }     &lt;br /&gt;
        else if (channel == REGISTER_SLAVE)&lt;br /&gt;
        {&lt;br /&gt;
            if(!~llListFindList(gSlaveNames, (list)data))&lt;br /&gt;
            {//isn&#039;t registered yet&lt;br /&gt;
                gSlaveNames += data;&lt;br /&gt;
                gSlaveRegistered=TRUE;&lt;br /&gt;
                //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave(s) Recognized: &amp;quot; + data);&lt;br /&gt;
            }&lt;br /&gt;
//            else&lt;br /&gt;
//            {//it already exists&lt;br /&gt;
//                llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave, Existing Slave Recognized: &amp;quot; + data);&lt;br /&gt;
//            }&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , null_key);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if(change&amp;amp;CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            if(gSlaveRegistered)        &lt;br /&gt;
            {&lt;br /&gt;
                //by using negative indexes they don&#039;t need to be adjusted when an entry is deleted.&lt;br /&gt;
                integer x = ~llGetListLength(gSlaveNames);&lt;br /&gt;
                while(++x)&lt;br /&gt;
                {&lt;br /&gt;
                    if (!~llGetInventoryType(llList2String(gSlaveNames, x)))&lt;br /&gt;
                    {&lt;br /&gt;
                        //llOwnerSay(&amp;quot;Slave Removed: &amp;quot; + llList2String(gSlaveNames, x));&lt;br /&gt;
                        gSlaveNames = llDeleteSubList(gSlaveNames, x, x);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                gSlaveRegistered = !(gSlaveNames == []);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Slave Script ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText v2.1(10-Char) by Thraxis Epsilon&lt;br /&gt;
// XyText v2.0 SLAVE Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
// Enabled 10-char per prim&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence.&lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character.&lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1;&lt;br /&gt;
&lt;br /&gt;
// This is a list of textures for all 2-character combinations. &lt;br /&gt;
list    CHARACTER_GRID  = [ &lt;br /&gt;
        &amp;quot;00e9f9f7-0669-181c-c192-7f8e67678c8d&amp;quot;, &lt;br /&gt;
        &amp;quot;347a5cb6-0031-7ec0-2fcf-f298eebf3c0e&amp;quot;, &lt;br /&gt;
        &amp;quot;4e7e689e-37f1-9eca-8596-a958bbd23963&amp;quot;, &lt;br /&gt;
        &amp;quot;19ea9c21-67ba-8f6f-99db-573b1b877eb1&amp;quot;, &lt;br /&gt;
        &amp;quot;dde7b412-cda1-652f-6fc2-73f4641f96e1&amp;quot;, &lt;br /&gt;
        &amp;quot;af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da&amp;quot;, &lt;br /&gt;
        &amp;quot;a201d3a2-364b-43b6-8686-5881c0f82a94&amp;quot;, &lt;br /&gt;
        &amp;quot;b674dec8-fead-99e5-c28d-2db8e4c51540&amp;quot;, &lt;br /&gt;
        &amp;quot;366e05f3-be6b-e5cf-c33b-731dff649caa&amp;quot;, &lt;br /&gt;
        &amp;quot;75c4925c-0427-dc0c-c71c-e28674ff4d27&amp;quot;, &lt;br /&gt;
        &amp;quot;dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6&amp;quot;, &lt;br /&gt;
        &amp;quot;0dca2feb-fc66-a762-db85-89026a4ecd68&amp;quot;, &lt;br /&gt;
        &amp;quot;a0fca76f-503a-946b-9336-0a918e886f7a&amp;quot;, &lt;br /&gt;
        &amp;quot;67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4&amp;quot;, &lt;br /&gt;
        &amp;quot;300470b2-da34-5470-074c-1b8464ca050c&amp;quot;, &lt;br /&gt;
        &amp;quot;d1f8e91c-ce2b-d85e-2120-930d3b630946&amp;quot;, &lt;br /&gt;
        &amp;quot;2a190e44-7b29-dadb-0bff-c31adaf5a170&amp;quot;, &lt;br /&gt;
        &amp;quot;75d55e71-f6f8-9835-e746-a45f189f30a1&amp;quot;, &lt;br /&gt;
        &amp;quot;300fac33-2b30-3da3-26bc-e2d70428ec19&amp;quot;, &lt;br /&gt;
        &amp;quot;0747c776-011a-53ce-13ee-8b5bb9e87c1e&amp;quot;, &lt;br /&gt;
        &amp;quot;85a855c3-a94f-01ca-33e0-7dde92e727e2&amp;quot;, &lt;br /&gt;
        &amp;quot;cbc1dab2-2d61-2986-1949-7a5235c954e1&amp;quot;, &lt;br /&gt;
        &amp;quot;f7aef047-f266-9596-16df-641010edd8e1&amp;quot;, &lt;br /&gt;
        &amp;quot;4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a69e98c-26a5-ad05-e92e-b5b906ad9ef9&amp;quot;, &lt;br /&gt;
        &amp;quot;462a9226-2a97-91ac-2d89-57ab33334b78&amp;quot;, &lt;br /&gt;
        &amp;quot;20b24b3a-8c57-82ee-c6ed-555003f5dbcd&amp;quot;, &lt;br /&gt;
        &amp;quot;9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217&amp;quot;, &lt;br /&gt;
        &amp;quot;c231dbdc-c842-15b0-7aa6-6da14745cfdc&amp;quot;, &lt;br /&gt;
        &amp;quot;c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf&amp;quot;, &lt;br /&gt;
        &amp;quot;f1e7d030-ff80-a242-cb69-f6951d4eae3b&amp;quot;, &lt;br /&gt;
        &amp;quot;ed32d6c4-d733-c0f1-f242-6df1d222220d&amp;quot;, &lt;br /&gt;
        &amp;quot;88f96a30-dccf-9b20-31ef-da0dfeb23c72&amp;quot;, &lt;br /&gt;
        &amp;quot;252f2595-58b8-4bcc-6515-fa274d0cfb65&amp;quot;, &lt;br /&gt;
        &amp;quot;f2838c4f-de80-cced-dff8-195dfdf36b2c&amp;quot;, &lt;br /&gt;
        &amp;quot;cc2594fe-add2-a3df-cdb3-a61711badf53&amp;quot;, &lt;br /&gt;
        &amp;quot;e0ce2972-da00-955c-129e-3289b3676776&amp;quot;, &lt;br /&gt;
        &amp;quot;3e0d336d-321f-ddfa-5c1b-e26131766f6a&amp;quot;, &lt;br /&gt;
        &amp;quot;d43b1dc4-6b51-76a7-8b90-38865b82bf06&amp;quot;, &lt;br /&gt;
        &amp;quot;06d16cbb-1868-fd1d-5c93-eae42164a37d&amp;quot;, &lt;br /&gt;
        &amp;quot;dd5d98cf-273e-3fd0-f030-48be58ee3a0b&amp;quot;, &lt;br /&gt;
        &amp;quot;0e47c89e-de4a-6233-a2da-cb852aad1b00&amp;quot;, &lt;br /&gt;
        &amp;quot;fb9c4a55-0e13-495b-25c4-f0b459dc06de&amp;quot;, &lt;br /&gt;
        &amp;quot;e3ce8def-312c-735b-0e48-018b6799c883&amp;quot;, &lt;br /&gt;
        &amp;quot;2f713216-4e71-d123-03ed-9c8554710c6b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a417d8a-1f4f-404b-9783-6672f8527911&amp;quot;, &lt;br /&gt;
        &amp;quot;ca5e21ec-5b20-5909-4c31-3f90d7316b33&amp;quot;, &lt;br /&gt;
        &amp;quot;06a4fcc3-e1c4-296d-8817-01f88fbd7367&amp;quot;, &lt;br /&gt;
        &amp;quot;130ac084-6f3c-95de-b5b6-d25c80703474&amp;quot;, &lt;br /&gt;
        &amp;quot;59d540a0-ae9d-3606-5ae0-4f2842b64cfa&amp;quot;, &lt;br /&gt;
        &amp;quot;8612ae9a-f53c-5bf4-2899-8174d7abc4fd&amp;quot;, &lt;br /&gt;
        &amp;quot;12467401-e979-2c49-34e0-6ac761542797&amp;quot;, &lt;br /&gt;
        &amp;quot;d53c3eaa-0404-3860-0675-3e375596c3e3&amp;quot;, &lt;br /&gt;
        &amp;quot;9f5b26bd-81d3-b25e-62fe-5b671d1e3e79&amp;quot;, &lt;br /&gt;
        &amp;quot;f57f0b64-a050-d617-ee00-c8e9e3adc9cb&amp;quot;, &lt;br /&gt;
        &amp;quot;beff166a-f5f3-f05e-e020-98f2b00e27ed&amp;quot;, &lt;br /&gt;
        &amp;quot;02278a65-94ba-6d5e-0d2b-93f2e4f4bf70&amp;quot;, &lt;br /&gt;
        &amp;quot;a707197d-449e-5b58-846c-0c850c61f9d6&amp;quot;, &lt;br /&gt;
        &amp;quot;021d4b1a-9503-a44f-ee2b-976eb5d80e68&amp;quot;, &lt;br /&gt;
        &amp;quot;0ae2ffae-7265-524d-cb76-c2b691992706&amp;quot;, &lt;br /&gt;
        &amp;quot;f6e41cf2-1104-bd0b-0190-dffad1bac813&amp;quot;, &lt;br /&gt;
        &amp;quot;2b4bb15e-956d-56ae-69f5-d26a20de0ce7&amp;quot;, &lt;br /&gt;
        &amp;quot;f816da2c-51f1-612a-2029-a542db7db882&amp;quot;, &lt;br /&gt;
        &amp;quot;345fea05-c7be-465c-409f-9dcb3bd2aa07&amp;quot;];&lt;br /&gt;
list    CHARACTER_GRID2  = [         &lt;br /&gt;
        &amp;quot;b3017e02-c063-5185-acd5-1ef5f9d79b89&amp;quot;, &lt;br /&gt;
        &amp;quot;4dcff365-1971-3c2b-d73c-77e1dc54242a&amp;quot; &lt;br /&gt;
          ]; &lt;br /&gt;
&lt;br /&gt;
///////////// END CONSTANTS ////////////////&lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
integer gActive; //if we are recognized, this is true&lt;br /&gt;
/////////// END GLOBAL VARIABLES ////////////&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug. &lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
    gCharIndex += &amp;quot;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridPos(integer index1, integer index2) { &lt;br /&gt;
    // There are two ways to use the lookup table... &lt;br /&gt;
    integer Col; &lt;br /&gt;
    integer Row; &lt;br /&gt;
    if (index1 &amp;gt;= index2) { &lt;br /&gt;
        // In this case, the row is the index of the first character: &lt;br /&gt;
        Row = index1; &lt;br /&gt;
        // And the col is the index of the second character (x2) &lt;br /&gt;
        Col = index2 * 2; &lt;br /&gt;
    } &lt;br /&gt;
    else { // Index1 &amp;lt; Index2 &lt;br /&gt;
        // In this case, the row is the index of the second character: &lt;br /&gt;
        Row = index2; &lt;br /&gt;
        // And the col is the index of the first character, x2, offset by 1. &lt;br /&gt;
        Col = index1 * 2 + 1; &lt;br /&gt;
    } &lt;br /&gt;
    return &amp;lt;Col, Row, 0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
string GetGridTexture(vector grid_pos) { &lt;br /&gt;
    // Calculate the texture in the grid to use. &lt;br /&gt;
    integer GridCol = llRound(grid_pos.x) / 20; &lt;br /&gt;
    integer GridRow = llRound(grid_pos.y) / 10; &lt;br /&gt;
&lt;br /&gt;
    // Lookup the texture. &lt;br /&gt;
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol); &lt;br /&gt;
    return Texture; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(vector grid_pos) { &lt;br /&gt;
    // Zoom in on the texture showing our character pair. &lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 20; &lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 10; &lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture. &lt;br /&gt;
    return &amp;lt;-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
     &lt;br /&gt;
               &lt;br /&gt;
   llSetLinkPrimitiveParams( link , [ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters. &lt;br /&gt;
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   &lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderExtended(integer link, string str) {&lt;br /&gt;
    // Look for escape sequences.&lt;br /&gt;
    list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);&lt;br /&gt;
    integer ParsedLen = llGetListLength(Parsed);&lt;br /&gt;
&lt;br /&gt;
    // Create a list of index values to work with.&lt;br /&gt;
    list Indices;&lt;br /&gt;
    // We start with room for 6 indices.&lt;br /&gt;
    integer IndicesLeft = 10;&lt;br /&gt;
&lt;br /&gt;
    string Token;&lt;br /&gt;
    integer Clipped;&lt;br /&gt;
    integer LastWasEscapeSequence = FALSE;&lt;br /&gt;
    // Work from left to right.&lt;br /&gt;
    integer i=0;&lt;br /&gt;
    for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) {&lt;br /&gt;
        Token = llList2String(Parsed, i);&lt;br /&gt;
&lt;br /&gt;
        // If this is an escape sequence, just set the flag and move on.&lt;br /&gt;
        if (Token == ESCAPE_SEQUENCE) {&lt;br /&gt;
            LastWasEscapeSequence = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else { // Token != ESCAPE_SEQUENCE&lt;br /&gt;
            // Otherwise this is a normal token.  Check its length.&lt;br /&gt;
            Clipped = FALSE;&lt;br /&gt;
            integer TokenLength = llStringLength(Token);&lt;br /&gt;
            // Clip if necessary.&lt;br /&gt;
            if (TokenLength &amp;gt; IndicesLeft) {&lt;br /&gt;
                TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));&lt;br /&gt;
                IndicesLeft = 0;&lt;br /&gt;
                Clipped = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                IndicesLeft -= TokenLength;&lt;br /&gt;
&lt;br /&gt;
            // Was the previous token an escape sequence?&lt;br /&gt;
            if (LastWasEscapeSequence) {&lt;br /&gt;
                // Yes, the first character is an escape character, the rest are normal.&lt;br /&gt;
                // This is the extended character.&lt;br /&gt;
                Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];&lt;br /&gt;
                &lt;br /&gt;
                // These are the normal characters.&lt;br /&gt;
                integer j=1;&lt;br /&gt;
                for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                {&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else { // Normal string.&lt;br /&gt;
                // Just add the characters normally.&lt;br /&gt;
                integer j=0;&lt;br /&gt;
                for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                {&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Unset this flag, since this was not an escape sequence.&lt;br /&gt;
            LastWasEscapeSequence = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Use the indices to create grid positions.&lt;br /&gt;
    vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );&lt;br /&gt;
    &lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) {&lt;br /&gt;
    // This converts from an ASCII based index to our indexing scheme.&lt;br /&gt;
    if (index &amp;gt;= 32) // &#039; &#039; or higher&lt;br /&gt;
        index -= 32;&lt;br /&gt;
    else { // index &amp;lt; 32&lt;br /&gt;
        // Quick bounds check.&lt;br /&gt;
        if (index &amp;gt; 15)&lt;br /&gt;
            index = 15;&lt;br /&gt;
&lt;br /&gt;
        index += 94; // extended characters&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return index;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);  &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) { &lt;br /&gt;
        if (channel == SLAVE_RECOGNIZED)&lt;br /&gt;
        {&lt;br /&gt;
            if (data == llGetScriptName())&lt;br /&gt;
            {&lt;br /&gt;
                gActive=TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        else if (channel == SLAVE_DISPLAY) &lt;br /&gt;
        { &lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            RenderString(llList2Integer(params, 0),data);&lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
    &lt;br /&gt;
       else if (channel == SLAVE_DISPLAY_EXTENDED) &lt;br /&gt;
       {&lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            RenderExtended(llList2Integer(params, 0),data);&lt;br /&gt;
    }&lt;br /&gt;
        else if (channel == REMAP_INDICES) {&lt;br /&gt;
            // Parse the message, splitting it up into index values.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            integer i;&lt;br /&gt;
            // Go through the list and swap each pair of indices.&lt;br /&gt;
            for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) {&lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );&lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );&lt;br /&gt;
&lt;br /&gt;
                // Swap these index values.&lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) {&lt;br /&gt;
            // Restore the character index back to default settings.&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            return;&lt;br /&gt;
        }                 &lt;br /&gt;
       else if (channel == SLAVE_RESET)&lt;br /&gt;
        {&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            gActive=FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10-Char Prim Setup ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText Prim Setup Script (5 Face)&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon&lt;br /&gt;
//&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        llSetPrimitiveParams([&lt;br /&gt;
                    PRIM_TYPE, PRIM_TYPE_PRISM, 32, &amp;lt;0.199, 0.8, 0.0&amp;gt;, 0.30, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;,&lt;br /&gt;
                    PRIM_SIZE, &amp;lt;0.03, 2.89, 0.5&amp;gt;, &lt;br /&gt;
                    PRIM_TEXTURE, 1, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;2.48, 1.0, 0.0&amp;gt;, &amp;lt;-0.74, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 6, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 4, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;14.75, 1.0, 0.0&amp;gt;, &amp;lt;0.27, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 7, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 3, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;2.48, 1.0, 0.0&amp;gt;, &amp;lt;-0.25, 0.0, 0.0&amp;gt;, 0.0]);&lt;br /&gt;
                    &lt;br /&gt;
        llRemoveInventory(llGetScriptName());&lt;br /&gt;
    } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
{{LSLC|Library}}&lt;br /&gt;
&lt;br /&gt;
{{#vardefine:sort|XyzzyText 2.1}}&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=164573</id>
		<title>XyzzyText</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=XyzzyText&amp;diff=164573"/>
		<updated>2008-12-04T20:56:19Z</updated>

		<summary type="html">&lt;p&gt;Andrew Hellershanks: Updated for use with GIMP 2.4 and later - . Corrected errors in let* block, and updated for use with GIMP 2.4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
{{RightToc}}&lt;br /&gt;
XyzzyText is a new version of Xytext with some advanced features:&lt;br /&gt;
&lt;br /&gt;
* Efficiency!  You can now control an entire linkset with just one script.&lt;br /&gt;
* Flexible Speed vs Lag.  Just drop in plug-and-play slave scripts to increase rendering speed.  (More than 4-5 slaves not recommended, there is diminishing returns)&lt;br /&gt;
* Ease of use.  There is no need to know link numbers.  Simply name the child prims xyzzytext-banknumber-cellnumber.&lt;br /&gt;
* To use, pass the bank number to use in the &amp;quot;key&amp;quot; field of the link message of DISPLAY_STRING/EXTENDED.&lt;br /&gt;
&lt;br /&gt;
=Copyright &amp;amp; Licensing=&lt;br /&gt;
&amp;lt;font size=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
* Gigs Taggart hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Thraxis Epsilon hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Strife Onizuka hereby releases his contributions to this under the MIT license.&lt;br /&gt;
* Huney Jewell hereby releases her contributions to this under the MIT license.&lt;br /&gt;
* Salahzar Stenvaag hereby releases his contributions to this under the MIT license. (photoshop/GIMP vbs script for alternative fonts plus ZZText)&lt;br /&gt;
* Ruud Lathrop hereby releases her contributions to this under the MIT license.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=XyzzyText - 5 Character=&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Display Prims named: &lt;br /&gt;
xyzzytext-0-0 xyzzytext-0-1&lt;br /&gt;
xyzzytext-1-0 xyzzytext-1-1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quickstart:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* Store all scripts in your inventory&lt;br /&gt;
* Rez a box&lt;br /&gt;
* Drop the prim setup script in it (You now have one unit, name it xyzzytext-0-0)&lt;br /&gt;
* Make a row of four of these prims (xyzzytext-0-0 xyzzytext-0-1,xyzzytext-0-2,xyzzytext-0-3)&lt;br /&gt;
* Move a copy of this row a little down, and rename the new row(xyzzytext-1-0 xyzzytext-1-1,xyzzytext-1-2,xyzzytext-1-3)&lt;br /&gt;
* Do this for every row you make&lt;br /&gt;
* Create a big box that serves as the board-background(mainprim)&lt;br /&gt;
* Link all prims with the mainprim(selected last), so the mainprim keeps yellow after linking(root-prim)&lt;br /&gt;
* Copy the main script and usage script into the root prim&lt;br /&gt;
* Type something, and check if it all works&lt;br /&gt;
* Flatten the prims, so the text looks straight&lt;br /&gt;
* Consider adding slave scripts to the root prim if you have a lot of rows&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer gToggle;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0,&amp;quot;&amp;quot;,NULL_KEY,&amp;quot;&amp;quot;);&lt;br /&gt;
       &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel,string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        if (gToggle)&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;0&amp;quot;);&lt;br /&gt;
        else&lt;br /&gt;
            llMessageLinked(LINK_THIS,DISPLAY_STRING,name + &amp;quot;:&amp;quot;+ message,&amp;quot;1&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        gToggle=!gToggle;&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Main Script==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyzzyText v2.1 Script (Set Line Color) by Huney Jewell&lt;br /&gt;
// XyzzyText v2.0 Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Core XyText Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS /////////////////// &lt;br /&gt;
// XyText Message Map. &lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out. &lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;;&lt;br /&gt;
key     null_key        = NULL_KEY;&lt;br /&gt;
///////////// END CONSTANTS //////////////// &lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
// This is whether or not to use the fade in/out special effect. &lt;br /&gt;
integer gCellUseFading      = FALSE; &lt;br /&gt;
// This is how long to display the text before fading out (if using &lt;br /&gt;
// fading special effect). &lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out. &lt;br /&gt;
float   gCellHoldDelay      = 1.0; &lt;br /&gt;
&lt;br /&gt;
integer gSlaveRegistered;&lt;br /&gt;
list gSlaveNames;&lt;br /&gt;
&lt;br /&gt;
integer BANK_STRIDE=3; //offset, length, highest_dirty&lt;br /&gt;
list gBankingData;&lt;br /&gt;
&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderWithEffects(integer link, string str) { &lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // First set the alpha to the lowest possible. &lt;br /&gt;
   llSetLinkAlpha(link,0.05, ALL_SIDES); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);          // Now turn up the alpha until it is at full strength. &lt;br /&gt;
    float Alpha = 0.10; &lt;br /&gt;
    for (; Alpha &amp;lt;= 1.0; Alpha += 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // See if we want to fade out as well. &lt;br /&gt;
   if (gCellHoldDelay &amp;lt; 0.0) &lt;br /&gt;
       // No, bail out. (Just keep showing the string at full strength). &lt;br /&gt;
       return; &lt;br /&gt;
          // Hold the text for a while. &lt;br /&gt;
   llSleep(gCellHoldDelay); &lt;br /&gt;
      // Now fade out. &lt;br /&gt;
   for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05) &lt;br /&gt;
       llSetLinkAlpha(link,Alpha, ALL_SIDES); &lt;br /&gt;
          // Make the text transparent to fully hide it. &lt;br /&gt;
   llSetLinkTexture(link,TRANSPARENT, ALL_SIDES); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer RenderExtended(integer link, string str, integer render) {&lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   integer length = 0;&lt;br /&gt;
   list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   integer i = 0;&lt;br /&gt;
   for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1)); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
               length += 2 + TokenLength;&lt;br /&gt;
               if(render)&lt;br /&gt;
               {&lt;br /&gt;
                    // This is the extended character. &lt;br /&gt;
                    Indices += (llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95);&lt;br /&gt;
                    &lt;br /&gt;
                    // These are the normal characters.&lt;br /&gt;
                    integer j = 1; &lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                    {&lt;br /&gt;
                       Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               length += TokenLength;&lt;br /&gt;
               if(render)&lt;br /&gt;
               {               &lt;br /&gt;
                   integer j = 0; &lt;br /&gt;
                   for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   {                  &lt;br /&gt;
                       Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j));&lt;br /&gt;
                   }&lt;br /&gt;
                }&lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions.&lt;br /&gt;
  if(render)&lt;br /&gt;
  {   &lt;br /&gt;
       vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
       vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
       vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
       vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
       vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
    &lt;br /&gt;
       // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
       ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);&lt;br /&gt;
   }&lt;br /&gt;
   return length;&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PassToRender(integer render,string message, integer bank)&lt;br /&gt;
{&lt;br /&gt;
//    float time;&lt;br /&gt;
    integer extendedlen = 0;&lt;br /&gt;
    integer link;&lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer msgLen = llStringLength(message);&lt;br /&gt;
    string TextToRender;&lt;br /&gt;
    integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
    string slave_name; //avoids unnecessary casts, keeping it as a string&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
    integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
    &lt;br /&gt;
    integer x = 0;&lt;br /&gt;
    for (;x &amp;lt; msgLen;x = x + 5)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;gt;= bank_length)  //we don&#039;t want to run off the end of the bank&lt;br /&gt;
        {&lt;br /&gt;
            //set the dirty to max, and bail out, we&#039;re done&lt;br /&gt;
            gBankingData=llListReplaceList(gBankingData, (list)bank_length, (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        TextToRender = llGetSubString(message, x, x + 15);&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves + 1)))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                //time = llGetAndResetTime();&lt;br /&gt;
                if(llSubStringIndex(TextToRender,&amp;quot;\e&amp;quot;) &amp;gt; x)&lt;br /&gt;
                    extendedlen = 5;&lt;br /&gt;
                else&lt;br /&gt;
                    extendedlen = RenderExtended(link,TextToRender,0);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
               llMessageLinked(LINK_THIS, SLAVE_DISPLAY_EXTENDED, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
              // llOwnerSay((string)llGetAndResetTime());&lt;br /&gt;
            }&lt;br /&gt;
               //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                RenderString(link,TextToRender);&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                extendedlen = RenderExtended(link,TextToRender,1);&lt;br /&gt;
                if (extendedlen &amp;gt; 5)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen - 5;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
            }&lt;br /&gt;
            if (render == 3)&lt;br /&gt;
                RenderWithEffects(link,TextToRender);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;            &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (bank_highest_dirty==0)&lt;br /&gt;
        bank_highest_dirty=bank_length;&lt;br /&gt;
    &lt;br /&gt;
    integer current_highest_dirty=i;&lt;br /&gt;
    while (i &amp;lt; bank_highest_dirty)&lt;br /&gt;
    {&lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves+1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_DISPLAY, &amp;quot;     &amp;quot;, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));       &lt;br /&gt;
            //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            RenderString(link,&amp;quot;     &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;        &lt;br /&gt;
    }&lt;br /&gt;
    gBankingData=llListReplaceList(gBankingData, (list)current_highest_dirty, (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka&lt;br /&gt;
list gXyTextPrims;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer get_number_of_prims()&lt;br /&gt;
{//ignores avatars.&lt;br /&gt;
    integer a = llGetNumberOfPrims();&lt;br /&gt;
    //Mono tweak&lt;br /&gt;
    vector size = llGetAgentSize(llGetLinkKey(a));&lt;br /&gt;
    while(size.z &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
        --a;&lt;br /&gt;
        size = llGetAgentSize(llGetLinkKey(a));&lt;br /&gt;
    }&lt;br /&gt;
    return a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//functions to pack 8-bit shorts into ints&lt;br /&gt;
list pack_and_insert(list in_list, integer pos, integer value)&lt;br /&gt;
{&lt;br /&gt;
//    //figure out the bitpack position&lt;br /&gt;
//    integer pack = pos &amp;amp; 3; //4 bytes per int&lt;br /&gt;
//    pos=pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
//    integer shifted = value &amp;lt;&amp;lt; (pack &amp;lt;&amp;lt; 3);&lt;br /&gt;
//    integer old_value = llList2Integer(in_list, pos);&lt;br /&gt;
//    shifted = old_value | shifted;&lt;br /&gt;
//    in_list = llListReplaceList(in_list, (list)shifted, pos, pos);&lt;br /&gt;
//    return in_list;&lt;br /&gt;
    //Safe optimized version&lt;br /&gt;
    integer index = pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
    return llListReplaceList(in_list, (list)(llList2Integer(in_list, index) | (value &amp;lt;&amp;lt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3))), index, index);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer unpack(list in_list, integer pos)&lt;br /&gt;
{&lt;br /&gt;
    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;gt;&amp;gt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;amp; 0x000000FF;//unsigned&lt;br /&gt;
//    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;lt;&amp;lt; (((~pos) &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;gt;&amp;gt; 24;//signed&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_color(vector color)&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=llGetListLength(gXyTextPrims) &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    &lt;br /&gt;
    for (; i&amp;lt;=num_prims; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_line_color(integer bank, vector color)&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
&lt;br /&gt;
    for (; i &amp;lt; bank_end; ++i)&lt;br /&gt;
    {     &lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
init()&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=get_number_of_prims();&lt;br /&gt;
    string link_name;&lt;br /&gt;
    integer bank=0;&lt;br /&gt;
    integer prims_pointer=0; //&amp;quot;pointer&amp;quot; to the next entry to be used in the gXyTextPrims list.&lt;br /&gt;
    &lt;br /&gt;
    list temp_bank = [];&lt;br /&gt;
    integer temp_bank_stride=2;&lt;br /&gt;
    &lt;br /&gt;
    //FIXME: font texture might should be per-bank&lt;br /&gt;
    llMessageLinked(LINK_THIS, SET_FONT_TEXTURE, &amp;quot;&amp;quot;, gFontTexture);&lt;br /&gt;
    &lt;br /&gt;
    gXyTextPrims=[];&lt;br /&gt;
    integer x=0;&lt;br /&gt;
    for (;x&amp;lt;64;++x)&lt;br /&gt;
    {&lt;br /&gt;
        gXyTextPrims = (gXyTextPrims = []) + gXyTextPrims + 0;  //we need to pad out the list to make it easier to add things in any order later&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @loop;&lt;br /&gt;
    {&lt;br /&gt;
        //loop over all prims, looking for ones in the current bank&lt;br /&gt;
        for(x=0;x&amp;lt;=num_prims;++x)&lt;br /&gt;
        {&lt;br /&gt;
            link_name=llGetLinkName(x);&lt;br /&gt;
            list tmp = llParseString2List(link_name, (list)&amp;quot;-&amp;quot;, []);&lt;br /&gt;
            if(llList2String(tmp,0) == &amp;quot;xyzzytext&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                if (llList2Integer(tmp,1) == bank)&lt;br /&gt;
                {&lt;br /&gt;
                    temp_bank += llList2Integer(tmp,2) + (list)x;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (temp_bank != [])&lt;br /&gt;
        {&lt;br /&gt;
            //sort the current bank&lt;br /&gt;
            temp_bank = llListSort(temp_bank, temp_bank_stride, TRUE);&lt;br /&gt;
            &lt;br /&gt;
            integer temp_len = llGetListLength(temp_bank);&lt;br /&gt;
            &lt;br /&gt;
            //store metadata&lt;br /&gt;
            gBankingData += [prims_pointer, temp_len/temp_bank_stride, 0];&lt;br /&gt;
            &lt;br /&gt;
            //repack the bank into the prim list&lt;br /&gt;
            for (x = 0; x &amp;lt; temp_len; x += temp_bank_stride)&lt;br /&gt;
            {&lt;br /&gt;
                gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, x + 1));&lt;br /&gt;
                ++prims_pointer;&lt;br /&gt;
            }&lt;br /&gt;
            ++bank;&lt;br /&gt;
            temp_bank=[];&lt;br /&gt;
            jump loop;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llMessageLinked(LINK_THIS, SLAVE_RESET, &amp;quot;&amp;quot; , null_key);&lt;br /&gt;
    //llOwnerSay((string)llGetFreeMemory());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
   state_entry() { &lt;br /&gt;
       // Initialize the character index. &lt;br /&gt;
       ResetCharIndex();&lt;br /&gt;
       init();&lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   link_message(integer sender, integer channel, string data, key id) { &lt;br /&gt;
        if (id==null_key)&lt;br /&gt;
            id=&amp;quot;0&amp;quot;;&lt;br /&gt;
            &lt;br /&gt;
        if (channel == DISPLAY_STRING) { &lt;br /&gt;
            PassToRender(1,data, (integer)((string)id)); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == DISPLAY_EXTENDED) { &lt;br /&gt;
            PassToRender(2,data, (integer)((string)id)); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == REMAP_INDICES) { &lt;br /&gt;
            // Parse the message, splitting it up into index values. &lt;br /&gt;
            list Parsed = llCSV2List(data); &lt;br /&gt;
            integer i = 0; &lt;br /&gt;
            // Go through the list and swap each pair of indices. &lt;br /&gt;
            for (; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
                // Swap these index values. &lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
        &lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            } &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == RESCAN_LINKSET)&lt;br /&gt;
        {&lt;br /&gt;
            init();&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) { &lt;br /&gt;
            // Restore the character index back to default settings. &lt;br /&gt;
            ResetCharIndex(); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_FADE_OPTIONS) { &lt;br /&gt;
            // Change the channel we listen to for cell commands, the &lt;br /&gt;
            // starting character position to extract from, and &lt;br /&gt;
            // special effect attributes. &lt;br /&gt;
            list Parsed = llCSV2List(data); &lt;br /&gt;
            gCellUseFading      = (integer) llList2String(Parsed, 0); &lt;br /&gt;
            gCellHoldDelay      = (float)   llList2String(Parsed, 1);&lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_FONT_TEXTURE) { &lt;br /&gt;
            // Use the new texture instead of the current one. &lt;br /&gt;
            gFontTexture = id; &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == SET_COLOR) {&lt;br /&gt;
            change_color((vector)data); &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_LINE_COLOR) {&lt;br /&gt;
            change_line_color((integer)((string)id), (vector)data); &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == REGISTER_SLAVE)&lt;br /&gt;
        {&lt;br /&gt;
            if(!~llListFindList(gSlaveNames, (list)data))&lt;br /&gt;
            {//isn&#039;t registered yet&lt;br /&gt;
                gSlaveNames += data;&lt;br /&gt;
                gSlaveRegistered=TRUE;&lt;br /&gt;
                //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave(s) Recognized: &amp;quot; + data);&lt;br /&gt;
            }&lt;br /&gt;
//            else&lt;br /&gt;
//            {//it already exists&lt;br /&gt;
//                llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave, Existing Slave Recognized: &amp;quot; + data);&lt;br /&gt;
//            }&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , null_key);&lt;br /&gt;
        }&lt;br /&gt;
    } &lt;br /&gt;
   &lt;br /&gt;
   &lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if(change&amp;amp;CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            if(gSlaveRegistered)        &lt;br /&gt;
            {&lt;br /&gt;
                //by using negative indexes they don&#039;t need to be adjusted when an entry is deleted.&lt;br /&gt;
                integer x = ~llGetListLength(gSlaveNames);&lt;br /&gt;
                while(++x)&lt;br /&gt;
                {&lt;br /&gt;
                    if (!~llGetInventoryType(llList2String(gSlaveNames, x)))&lt;br /&gt;
                    {&lt;br /&gt;
                        //llOwnerSay(&amp;quot;Slave Removed: &amp;quot; + llList2String(gSlaveNames, x));&lt;br /&gt;
                        gSlaveNames = llDeleteSubList(gSlaveNames, x, x);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                gSlaveRegistered = !(gSlaveNames == []);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Slave Script==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyText v2.0 SLAVE Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon and Gigs Taggart 5/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence. &lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character. &lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;12345&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// This is the key of the font we are displaying. &lt;br /&gt;
key     gFontTexture        = &amp;quot;b2e7394f-5e54-aa12-6e1c-ef327b6bed9e&amp;quot;; &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
integer gActive; //if we are recognized, this is true&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
   gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
   gCharIndex += &amp;quot;\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(integer index) { &lt;br /&gt;
   // Calculate the offset needed to display this character. &lt;br /&gt;
   integer Row = index / 10; &lt;br /&gt;
   integer Col = index % 10; &lt;br /&gt;
&lt;br /&gt;
   // Return the offset in the texture. &lt;br /&gt;
   return &amp;lt;-0.45 + 0.1 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_offset1, vector grid_offset2, vector grid_offset3, vector grid_offset4, vector grid_offset5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
    &lt;br /&gt;
   // &amp;lt;-0.256, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0.130, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;0, 0, 0&amp;gt; &lt;br /&gt;
   // &amp;lt;-0.74, 0, 0&amp;gt; &lt;br /&gt;
    &lt;br /&gt;
   llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset1 + &amp;lt;0.037, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset2, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, (string)gFontTexture, &amp;lt;-0.74, 0.1, 0&amp;gt;, grid_offset3 - &amp;lt;0.244, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, (string)gFontTexture, &amp;lt;0.05, 0.1, 0&amp;gt;, grid_offset4, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, (string)gFontTexture, &amp;lt;0.126, 0.1, 0&amp;gt;, grid_offset5 - &amp;lt;0.037, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
   // Get the grid positions for each pair of characters. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
RenderExtended(integer link, string str) { &lt;br /&gt;
   // Look for escape sequences. &lt;br /&gt;
   list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]); &lt;br /&gt;
   integer ParsedLen = llGetListLength(Parsed); &lt;br /&gt;
&lt;br /&gt;
   // Create a list of index values to work with. &lt;br /&gt;
   list Indices; &lt;br /&gt;
   // We start with room for 5 indices. &lt;br /&gt;
   integer IndicesLeft = 5; &lt;br /&gt;
&lt;br /&gt;
   integer i = 0; &lt;br /&gt;
   string Token; &lt;br /&gt;
   integer Clipped; &lt;br /&gt;
   integer LastWasEscapeSequence = FALSE; &lt;br /&gt;
   // Work from left to right. &lt;br /&gt;
   for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) { &lt;br /&gt;
       Token = llList2String(Parsed, i); &lt;br /&gt;
&lt;br /&gt;
       // If this is an escape sequence, just set the flag and move on. &lt;br /&gt;
       if (Token == ESCAPE_SEQUENCE) { &lt;br /&gt;
           LastWasEscapeSequence = TRUE; &lt;br /&gt;
       } &lt;br /&gt;
       else { // Token != ESCAPE_SEQUENCE &lt;br /&gt;
           // Otherwise this is a normal token.  Check its length. &lt;br /&gt;
           Clipped = FALSE; &lt;br /&gt;
           integer TokenLength = llStringLength(Token); &lt;br /&gt;
           // Clip if necessary. &lt;br /&gt;
           if (TokenLength &amp;gt; IndicesLeft) { &lt;br /&gt;
               Token = llGetSubString(Token, 0, IndicesLeft - 1); &lt;br /&gt;
               TokenLength = llStringLength(Token); &lt;br /&gt;
               IndicesLeft = 0; &lt;br /&gt;
               Clipped = TRUE; &lt;br /&gt;
           } &lt;br /&gt;
           else &lt;br /&gt;
               IndicesLeft -= TokenLength; &lt;br /&gt;
&lt;br /&gt;
           // Was the previous token an escape sequence? &lt;br /&gt;
           if (LastWasEscapeSequence) { &lt;br /&gt;
               // Yes, the first character is an escape character, the rest are normal. &lt;br /&gt;
&lt;br /&gt;
               // This is the extended character. &lt;br /&gt;
               Indices += (llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95); &lt;br /&gt;
&lt;br /&gt;
               // These are the normal characters. &lt;br /&gt;
               integer j = 1; &lt;br /&gt;
               for (; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
           } &lt;br /&gt;
           else { // Normal string. &lt;br /&gt;
               // Just add the characters normally. &lt;br /&gt;
               integer j; &lt;br /&gt;
               for (j = 0; j &amp;lt; TokenLength; ++j) &lt;br /&gt;
                   Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j)); &lt;br /&gt;
           } &lt;br /&gt;
&lt;br /&gt;
           // Unset this flag, since this was not an escape sequence. &lt;br /&gt;
           LastWasEscapeSequence = FALSE; &lt;br /&gt;
       } &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   // Use the indices to create grid positions. &lt;br /&gt;
   vector GridOffset1 = GetGridOffset( llList2Integer(Indices, 0) ); &lt;br /&gt;
   vector GridOffset2 = GetGridOffset( llList2Integer(Indices, 1) ); &lt;br /&gt;
   vector GridOffset3 = GetGridOffset( llList2Integer(Indices, 2) ); &lt;br /&gt;
   vector GridOffset4 = GetGridOffset( llList2Integer(Indices, 3) ); &lt;br /&gt;
   vector GridOffset5 = GetGridOffset( llList2Integer(Indices, 4) ); &lt;br /&gt;
&lt;br /&gt;
   // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
   ShowChars(link,GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5); &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) { &lt;br /&gt;
   // This converts from an ASCII based index to our indexing scheme. &lt;br /&gt;
   if (index &amp;gt;= 32) // &#039; &#039; or higher &lt;br /&gt;
       index -= 32; &lt;br /&gt;
   else { // index &amp;lt; 32 &lt;br /&gt;
       // Quick bounds check. &lt;br /&gt;
       if (index &amp;gt; 15) &lt;br /&gt;
           index = 15; &lt;br /&gt;
&lt;br /&gt;
       index += 94; // extended characters &lt;br /&gt;
   } &lt;br /&gt;
&lt;br /&gt;
   return index; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default &lt;br /&gt;
{ &lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);  &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer num)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();       &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) &lt;br /&gt;
    { &lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_RECOGNIZED)&lt;br /&gt;
        {&lt;br /&gt;
            if (data == llGetScriptName())&lt;br /&gt;
            {&lt;br /&gt;
                gActive=TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        if (channel == SLAVE_DISPLAY) &lt;br /&gt;
        { &lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            RenderString(llList2Integer(params, 0),data);&lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
       if (channel == SLAVE_DISPLAY_EXTENDED) &lt;br /&gt;
       {&lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            RenderExtended(llList2Integer(params, 0),data);&lt;br /&gt;
       } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == SET_FONT_TEXTURE) &lt;br /&gt;
        { &lt;br /&gt;
           gFontTexture = id; &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
       &lt;br /&gt;
        if (channel == REMAP_INDICES) { &lt;br /&gt;
           // Parse the message, splitting it up into index values. &lt;br /&gt;
           list Parsed = llCSV2List(data); &lt;br /&gt;
           integer i; &lt;br /&gt;
           // Go through the list and swap each pair of indices. &lt;br /&gt;
           for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) { &lt;br /&gt;
               integer Index1 = ConvertIndex( llList2Integer(Parsed, i) ); &lt;br /&gt;
               integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) ); &lt;br /&gt;
        &lt;br /&gt;
               // Swap these index values. &lt;br /&gt;
               string Value1 = llGetSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               string Value2 = llGetSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index1, Value2); &lt;br /&gt;
        &lt;br /&gt;
               gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2); &lt;br /&gt;
               gCharIndex = llInsertString(gCharIndex, Index2, Value1); &lt;br /&gt;
           } &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
        if (channel == RESET_INDICES) { &lt;br /&gt;
           // Restore the character index back to default settings. &lt;br /&gt;
           ResetCharIndex(); &lt;br /&gt;
           return; &lt;br /&gt;
        } &lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        if (channel == SLAVE_RESET)&lt;br /&gt;
        {&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            gActive=FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
    } &lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Prim Setup==&lt;br /&gt;
&#039;&#039;&#039;(Caution!  Not compatible with 5 face double texture Xytext)&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText Prim Setup Script (5 Face)&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon&lt;br /&gt;
//&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        llSetPrimitiveParams([&lt;br /&gt;
                    PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_DEFAULT, &amp;lt;0.199, 0.8, 0.0&amp;gt;, 0.68, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &lt;br /&gt;
                    PRIM_SIZE, &amp;lt;0.03, 2.89, 0.5&amp;gt;, &lt;br /&gt;
                    PRIM_TEXTURE, 1, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.740013, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 6, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 4, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;-0.740, 0.10, 0.00&amp;gt;, &amp;lt;0.130009, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 7, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.050, 0.100, 0.00&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 3, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;0.126, 0.10, 0.0&amp;gt;, &amp;lt;-0.255989, 0.0, 0.0&amp;gt;, 0.0]);&lt;br /&gt;
                    &lt;br /&gt;
        llRemoveInventory(llGetScriptName());&lt;br /&gt;
    } &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= How to produce textures with alternative fonts for 5 character version (Photoshop VBscript version) =&lt;br /&gt;
&lt;br /&gt;
Note: If you need to use XyzzyText for European or UTF-8 other languages, please see the following link: [[XyzzyText-UTF8]]&lt;br /&gt;
Use the following section for GIMP script-fu if you prefer opensource alternative. Use the following link: [[ZZText]] for an alternative international solution (still based on xytext and xyzzytext) using even fewer textures and lag than the xytext solution.&lt;br /&gt;
&lt;br /&gt;
If you need to display with another font, italics or other characters, you can do the following :)&lt;br /&gt;
&lt;br /&gt;
Using Photoshop VB Scripting on windows, just open up Photoshop CS3, and create with notepad the following MakeFonts.vbs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Dim appRef&lt;br /&gt;
Set appRef = CreateObject( &amp;quot;Photoshop.Application&amp;quot; )&lt;br /&gt;
&#039; Remember current unit settings and then set units to&lt;br /&gt;
&#039; the value expected by this script&lt;br /&gt;
Dim originalRulerUnits&lt;br /&gt;
originalRulerUnits = appRef.Preferences.RulerUnits&lt;br /&gt;
appRef.Preferences.RulerUnits = 1 &#039; psPixels&lt;br /&gt;
&#039; Create a new 512*512 pixel document and assign it to a variable.&lt;br /&gt;
Dim docRef&lt;br /&gt;
Dim artLayerRef&lt;br /&gt;
Dim textItemRef&lt;br /&gt;
dim rows(10)&lt;br /&gt;
rows(1)=&amp;quot; !&amp;quot;&amp;quot;#$%&amp;amp;&#039;()&amp;quot;&lt;br /&gt;
rows(2)=&amp;quot;*+,-./0123&amp;quot;&lt;br /&gt;
rows(3)=&amp;quot;456789:;&amp;lt;=&amp;quot;&lt;br /&gt;
rows(4)=&amp;quot;&amp;gt;?@ABCDEFG&amp;quot;&lt;br /&gt;
rows(5)=&amp;quot;HIJKLMNOPQ&amp;quot;&lt;br /&gt;
rows(6)=&amp;quot;RSTUVWXYZ[&amp;quot;&lt;br /&gt;
rows(7)=&amp;quot;\]^_`abcde&amp;quot;&lt;br /&gt;
rows(8)=&amp;quot;fghijklmno&amp;quot;&lt;br /&gt;
rows(9)=&amp;quot;pqrstuvwxy&amp;quot;&lt;br /&gt;
rows(10)=&amp;quot;z{|}~·ΘΩ√&amp;quot;      &lt;br /&gt;
&lt;br /&gt;
dim fontname&lt;br /&gt;
fontname=&amp;quot;Courier&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Set docRef = appRef.Documents.Add(512, 512, 72, &amp;quot;Table for font &amp;quot; &amp;amp; fontname, 2, 3, 1)&lt;br /&gt;
&#039; Create a new art layer containing text&lt;br /&gt;
Dim colorObj&lt;br /&gt;
Set colorObj=CreateObject(&amp;quot;Photoshop.SolidColor&amp;quot;)&lt;br /&gt;
colorObj.RGB.Red=255&lt;br /&gt;
colorObj.RGB.Green=255&lt;br /&gt;
colorObj.RGB.Blue=255&lt;br /&gt;
&#039; Set the contents of the text layer.&lt;br /&gt;
for i=1 to 10&lt;br /&gt;
   for j=1 to 10&lt;br /&gt;
     Set artLayerRef = docRef.ArtLayers.Add&lt;br /&gt;
     artLayerRef.Kind = 2&lt;br /&gt;
     Set textItemRef = artLayerRef.TextItem&lt;br /&gt;
     &#039; textItemRef.Font = fontname&lt;br /&gt;
     textItemRef.Color=colorObj&lt;br /&gt;
     textItemRef.Justification = 2 &lt;br /&gt;
     textItemRef.Font = &amp;quot;A Charming Font&amp;quot;&lt;br /&gt;
     textItemRef.Size = 38&lt;br /&gt;
     textItemRef.Contents = mid(rows(i),j,1)&lt;br /&gt;
     textItemRef.Position = Array((j-1)*51.2+25,i*51.2-7)&lt;br /&gt;
   next&lt;br /&gt;
next&lt;br /&gt;
&#039; Restore unit settingPhotoshop CS3&lt;br /&gt;
appRef.Preferences.RulerUnits = originalRulerUnits&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just click on the file in internet explorer and it will start working with your photoshop (I&#039;ll take a bit to display all the 100 characters, maybe around 1 sec for character).&lt;br /&gt;
&lt;br /&gt;
This will layout the 100 characters in photoshop on 100 different layers. Then do the following:&lt;br /&gt;
&lt;br /&gt;
* select all the layers with text and go to Text tool and change to whatever font (size etc) you want&lt;br /&gt;
* maybe need to add a black layer to see your fonts :) (after you have to hid or delete this)&lt;br /&gt;
* merge all the layers in just one&lt;br /&gt;
* add an alpha channel for transparency (all black)&lt;br /&gt;
* select all in the merged text layer and copy it to alpha channel&lt;br /&gt;
* enable the alpha channel and the RGB channel so that you see your font set and the transparent red&lt;br /&gt;
* save the font as TGA preserving alpha channel&lt;br /&gt;
* upload it to SecondLife 10 L$&lt;br /&gt;
* get the UUID from the inventory and specify it instead of the standard template.&lt;br /&gt;
&lt;br /&gt;
= How to produce textures with alternative fonts for 5 character version (GIMP script-fu version) =&lt;br /&gt;
&lt;br /&gt;
Use the following script for generating characters with GIMP:&lt;br /&gt;
&lt;br /&gt;
To use it you must put under the $HOME/.gimpXXX/scripts directory and name it something.scm.&lt;br /&gt;
Then you will find it under gimp &amp;lt;Toolbox&amp;gt;/Xtns/Script-Fu/Text. Clicking on it you are prompted for font to use (use monospaced fonts Andale Mono for instance). (Change only font and fontsize 50 should be ok, others are hard-coded in the script). Adapt with new unicode characters if you need them.&lt;br /&gt;
&lt;br /&gt;
Note: If you need to use XyzzyText for European or UTF-8 other languages, please see the following link: [[XyzzyText-UTF8]]&lt;br /&gt;
Use the following section for GIMP script-fu if you prefer opensource alternative. Use the following link: [[ZZText]] for an alternative international solution (still based on xytext and xyzzytext) using even fewer textures and lag than the xytext solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
= How to produce textures with alternative fonts for 5 character version (GIMP script-fu version) =&lt;br /&gt;
&lt;br /&gt;
Use the following script for generating characters with GIMP:&lt;br /&gt;
&lt;br /&gt;
To use it you must put under the $HOME/.gimpXXX/scripts directory and name it something.scm.&lt;br /&gt;
Then you will find it under gimp &amp;lt;Toolbox&amp;gt;/Xtns/Script-Fu/Text. Clicking on it you are prompted for font to use (use monospaced fonts Andale Mono for instance). (Change only font and fontsize 50 should be ok, others are hard-coded in the script). Adapt with new unicode characters if you need them.&lt;br /&gt;
&lt;br /&gt;
Note: If you need to use XyzzyText for European or UTF-8 other languages, please see the following link: [[XyzzyText-UTF8]]&lt;br /&gt;
Use the following section for GIMP script-fu if you prefer opensource alternative. Use the following link: [[ZZText]] for an alternative international solution (still based on xytext and xyzzytext) using even fewer textures and lag than the xytext solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
(define (script-fu-xytext-simple inText inFont inFontSize inTextColor)&lt;br /&gt;
   (let*&lt;br /&gt;
       (&lt;br /&gt;
       ; define our local variables&lt;br /&gt;
       ; create a new image:&lt;br /&gt;
       (theImageWidth  512)&lt;br /&gt;
       (theImageHeight 512)&lt;br /&gt;
       (theImage)&lt;br /&gt;
       (theLayer )&lt;br /&gt;
       (x 0)&lt;br /&gt;
       (y 0)&lt;br /&gt;
       (p 32)&lt;br /&gt;
       (theText)&lt;br /&gt;
       (rows #(&lt;br /&gt;
               &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()&amp;quot;&lt;br /&gt;
               &amp;quot;*+,-./0123&amp;quot;&lt;br /&gt;
               &amp;quot;456789:;&amp;lt;=&amp;quot;&lt;br /&gt;
               &amp;quot;&amp;gt;?@ABCDEFG&amp;quot;&lt;br /&gt;
               &amp;quot;HIJKLMNOPQ&amp;quot;&lt;br /&gt;
               &amp;quot;RSTUVWXYZ[&amp;quot;&lt;br /&gt;
               &amp;quot;\\]^_`abcde&amp;quot;&lt;br /&gt;
               &amp;quot;fghijklmno&amp;quot;&lt;br /&gt;
               &amp;quot;pqrstuvwxy&amp;quot;&lt;br /&gt;
&lt;br /&gt;
               ;&amp;quot;z{|}~·thetaOmegaRadix.o &amp;quot;&lt;br /&gt;
               (list #\z #\{ #\| #\} #\~ #x387 #x3F4 #x3A9r #x221A #x387 )&lt;br /&gt;
              )&lt;br /&gt;
       )&lt;br /&gt;
       (el 0)&lt;br /&gt;
       (ch 0)&lt;br /&gt;
       ) ;end of our local variables&lt;br /&gt;
&lt;br /&gt;
  ; builds image&lt;br /&gt;
  (set! theImage (car    (gimp-image-new theImageWidth theImageHeight RGB)))&lt;br /&gt;
  ; builds layer&lt;br /&gt;
  (set! theLayer (car (gimp-layer-new theImage theImageWidth theImageHeight RGB-IMAGE &amp;quot;layer 1&amp;quot; 100 NORMAL) ) )&lt;br /&gt;
  ; add layer to image&lt;br /&gt;
  (gimp-image-add-layer theImage theLayer 0)&lt;br /&gt;
&lt;br /&gt;
  ; add alpha and set foreground&lt;br /&gt;
  (gimp-layer-add-alpha theLayer)&lt;br /&gt;
  (gimp-palette-set-foreground inTextColor)&lt;br /&gt;
&lt;br /&gt;
  ; clear all the image and remove selection&lt;br /&gt;
  (gimp-selection-all theImage)&lt;br /&gt;
  (gimp-edit-clear theLayer)&lt;br /&gt;
  (gimp-selection-none theImage)&lt;br /&gt;
&lt;br /&gt;
  ; do actual plot of characters&lt;br /&gt;
  (while (&amp;lt; x 10)&lt;br /&gt;
    (while (&amp;lt; y 10)&lt;br /&gt;
      (set! el (vector-ref rows x))&lt;br /&gt;
      (set! ch (if (string? el) (substring el y (+ y 1)) (list-ref el (+ y 1))))&lt;br /&gt;
      (if (integer? ch) (set! ch (integer-&amp;gt;char ch)))&lt;br /&gt;
      (if (char? ch)(set! ch (string ch)))&lt;br /&gt;
      (set! p ch)&lt;br /&gt;
      (set! theText (car (gimp-text-fontname theImage theLayer&lt;br /&gt;
          (+ (* y 51.2) 12) (- (* x 51.2) 7)&lt;br /&gt;
          p    0    TRUE&lt;br /&gt;
          inFontSize PIXELS&lt;br /&gt;
          inFont)))&lt;br /&gt;
&lt;br /&gt;
        ; go on next char&lt;br /&gt;
        ;(set! p (+ p 1))&lt;br /&gt;
        (set! y (+ y 1))&lt;br /&gt;
      )&lt;br /&gt;
&lt;br /&gt;
    (set! y 0)&lt;br /&gt;
    (set! x (+ x 1))&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  ; apply the layers (apply transparence&lt;br /&gt;
  (gimp-image-merge-visible-layers theImage 0)&lt;br /&gt;
&lt;br /&gt;
  (gimp-display-new theImage)&lt;br /&gt;
  )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(script-fu-register&lt;br /&gt;
  &amp;quot;script-fu-xytext-simple&amp;quot;           ;func name&lt;br /&gt;
  &amp;quot;XYText-simple&amp;quot;                     ;menu label&lt;br /&gt;
  &amp;quot;Generate font for xytext-simple&amp;quot;   ;description&lt;br /&gt;
  &amp;quot;Salahzar Stenvaag&amp;quot;                 ;author&lt;br /&gt;
  &amp;quot;copyright 2008, Salahzar Stenvaag&amp;quot; ;copyright notice&lt;br /&gt;
  &amp;quot;October 27, 1997&amp;quot;                  ;date created&lt;br /&gt;
  &amp;quot;&amp;quot;                                  ;image type that the script works on&lt;br /&gt;
  SF-STRING      &amp;quot;Text:&amp;quot;         &amp;quot;Text Box&amp;quot;           ;a string variable&lt;br /&gt;
  SF-FONT        &amp;quot;Font:&amp;quot;         &amp;quot;Andale Mono&amp;quot;        ;a fixed font variable&lt;br /&gt;
  SF-ADJUSTMENT  &amp;quot;Font size&amp;quot;     &#039;(50 1 1000 1 10 0 1);a spin-button&lt;br /&gt;
  SF-COLOR       &amp;quot;Color:&amp;quot;        &#039;(255 255 255)       ;color variable&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(script-fu-menu-register &amp;quot;script-fu-xytext-simple&amp;quot; &amp;quot;&amp;lt;Toolbox&amp;gt;/Xtns/Text&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= XyzzyText - 10 Character =&lt;br /&gt;
&lt;br /&gt;
== Master Script ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
// XyzzyText v2.1(10-Char) by Thraxis Epsilon&lt;br /&gt;
// XyzzyText v2.1 Script (Set Line Color) by Huney Jewell&lt;br /&gt;
// XyzzyText v2.0 Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
// Enabled 10-char per prim&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Core XyText Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
/////////////// CONSTANTS /////////////////// &lt;br /&gt;
// XyText Message Map. &lt;br /&gt;
integer DISPLAY_STRING      = 204000; &lt;br /&gt;
integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003; &lt;br /&gt;
integer SET_FADE_OPTIONS    = 204004; &lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
integer SET_LINE_COLOR      = 204006; &lt;br /&gt;
integer SET_COLOR           = 204007; &lt;br /&gt;
integer RESCAN_LINKSET      = 204008;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET         = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence.&lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character.&lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1;&lt;br /&gt;
&lt;br /&gt;
// Used to hide the text after a fade-out. &lt;br /&gt;
key     TRANSPARENT     = &amp;quot;701917a8-d614-471f-13dd-5f4644e36e3c&amp;quot;;&lt;br /&gt;
key     null_key        = NULL_KEY;&lt;br /&gt;
&lt;br /&gt;
// This is a list of textures for all 2-character combinations. &lt;br /&gt;
list    CHARACTER_GRID  = [ &lt;br /&gt;
        &amp;quot;00e9f9f7-0669-181c-c192-7f8e67678c8d&amp;quot;, &lt;br /&gt;
        &amp;quot;347a5cb6-0031-7ec0-2fcf-f298eebf3c0e&amp;quot;, &lt;br /&gt;
        &amp;quot;4e7e689e-37f1-9eca-8596-a958bbd23963&amp;quot;, &lt;br /&gt;
        &amp;quot;19ea9c21-67ba-8f6f-99db-573b1b877eb1&amp;quot;, &lt;br /&gt;
        &amp;quot;dde7b412-cda1-652f-6fc2-73f4641f96e1&amp;quot;, &lt;br /&gt;
        &amp;quot;af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da&amp;quot;, &lt;br /&gt;
        &amp;quot;a201d3a2-364b-43b6-8686-5881c0f82a94&amp;quot;, &lt;br /&gt;
        &amp;quot;b674dec8-fead-99e5-c28d-2db8e4c51540&amp;quot;, &lt;br /&gt;
        &amp;quot;366e05f3-be6b-e5cf-c33b-731dff649caa&amp;quot;, &lt;br /&gt;
        &amp;quot;75c4925c-0427-dc0c-c71c-e28674ff4d27&amp;quot;, &lt;br /&gt;
        &amp;quot;dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6&amp;quot;, &lt;br /&gt;
        &amp;quot;0dca2feb-fc66-a762-db85-89026a4ecd68&amp;quot;, &lt;br /&gt;
        &amp;quot;a0fca76f-503a-946b-9336-0a918e886f7a&amp;quot;, &lt;br /&gt;
        &amp;quot;67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4&amp;quot;, &lt;br /&gt;
        &amp;quot;300470b2-da34-5470-074c-1b8464ca050c&amp;quot;, &lt;br /&gt;
        &amp;quot;d1f8e91c-ce2b-d85e-2120-930d3b630946&amp;quot;, &lt;br /&gt;
        &amp;quot;2a190e44-7b29-dadb-0bff-c31adaf5a170&amp;quot;, &lt;br /&gt;
        &amp;quot;75d55e71-f6f8-9835-e746-a45f189f30a1&amp;quot;, &lt;br /&gt;
        &amp;quot;300fac33-2b30-3da3-26bc-e2d70428ec19&amp;quot;, &lt;br /&gt;
        &amp;quot;0747c776-011a-53ce-13ee-8b5bb9e87c1e&amp;quot;, &lt;br /&gt;
        &amp;quot;85a855c3-a94f-01ca-33e0-7dde92e727e2&amp;quot;, &lt;br /&gt;
        &amp;quot;cbc1dab2-2d61-2986-1949-7a5235c954e1&amp;quot;, &lt;br /&gt;
        &amp;quot;f7aef047-f266-9596-16df-641010edd8e1&amp;quot;, &lt;br /&gt;
        &amp;quot;4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a69e98c-26a5-ad05-e92e-b5b906ad9ef9&amp;quot;, &lt;br /&gt;
        &amp;quot;462a9226-2a97-91ac-2d89-57ab33334b78&amp;quot;, &lt;br /&gt;
        &amp;quot;20b24b3a-8c57-82ee-c6ed-555003f5dbcd&amp;quot;, &lt;br /&gt;
        &amp;quot;9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217&amp;quot;, &lt;br /&gt;
        &amp;quot;c231dbdc-c842-15b0-7aa6-6da14745cfdc&amp;quot;, &lt;br /&gt;
        &amp;quot;c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf&amp;quot;, &lt;br /&gt;
        &amp;quot;f1e7d030-ff80-a242-cb69-f6951d4eae3b&amp;quot;, &lt;br /&gt;
        &amp;quot;ed32d6c4-d733-c0f1-f242-6df1d222220d&amp;quot;, &lt;br /&gt;
        &amp;quot;88f96a30-dccf-9b20-31ef-da0dfeb23c72&amp;quot;, &lt;br /&gt;
        &amp;quot;252f2595-58b8-4bcc-6515-fa274d0cfb65&amp;quot;, &lt;br /&gt;
        &amp;quot;f2838c4f-de80-cced-dff8-195dfdf36b2c&amp;quot;, &lt;br /&gt;
        &amp;quot;cc2594fe-add2-a3df-cdb3-a61711badf53&amp;quot;, &lt;br /&gt;
        &amp;quot;e0ce2972-da00-955c-129e-3289b3676776&amp;quot;, &lt;br /&gt;
        &amp;quot;3e0d336d-321f-ddfa-5c1b-e26131766f6a&amp;quot;, &lt;br /&gt;
        &amp;quot;d43b1dc4-6b51-76a7-8b90-38865b82bf06&amp;quot;, &lt;br /&gt;
        &amp;quot;06d16cbb-1868-fd1d-5c93-eae42164a37d&amp;quot;, &lt;br /&gt;
        &amp;quot;dd5d98cf-273e-3fd0-f030-48be58ee3a0b&amp;quot;, &lt;br /&gt;
        &amp;quot;0e47c89e-de4a-6233-a2da-cb852aad1b00&amp;quot;, &lt;br /&gt;
        &amp;quot;fb9c4a55-0e13-495b-25c4-f0b459dc06de&amp;quot;, &lt;br /&gt;
        &amp;quot;e3ce8def-312c-735b-0e48-018b6799c883&amp;quot;, &lt;br /&gt;
        &amp;quot;2f713216-4e71-d123-03ed-9c8554710c6b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a417d8a-1f4f-404b-9783-6672f8527911&amp;quot;, &lt;br /&gt;
        &amp;quot;ca5e21ec-5b20-5909-4c31-3f90d7316b33&amp;quot;, &lt;br /&gt;
        &amp;quot;06a4fcc3-e1c4-296d-8817-01f88fbd7367&amp;quot;, &lt;br /&gt;
        &amp;quot;130ac084-6f3c-95de-b5b6-d25c80703474&amp;quot;, &lt;br /&gt;
        &amp;quot;59d540a0-ae9d-3606-5ae0-4f2842b64cfa&amp;quot;, &lt;br /&gt;
        &amp;quot;8612ae9a-f53c-5bf4-2899-8174d7abc4fd&amp;quot;, &lt;br /&gt;
        &amp;quot;12467401-e979-2c49-34e0-6ac761542797&amp;quot;, &lt;br /&gt;
        &amp;quot;d53c3eaa-0404-3860-0675-3e375596c3e3&amp;quot;, &lt;br /&gt;
        &amp;quot;9f5b26bd-81d3-b25e-62fe-5b671d1e3e79&amp;quot;, &lt;br /&gt;
        &amp;quot;f57f0b64-a050-d617-ee00-c8e9e3adc9cb&amp;quot;, &lt;br /&gt;
        &amp;quot;beff166a-f5f3-f05e-e020-98f2b00e27ed&amp;quot;, &lt;br /&gt;
        &amp;quot;02278a65-94ba-6d5e-0d2b-93f2e4f4bf70&amp;quot;, &lt;br /&gt;
        &amp;quot;a707197d-449e-5b58-846c-0c850c61f9d6&amp;quot;, &lt;br /&gt;
        &amp;quot;021d4b1a-9503-a44f-ee2b-976eb5d80e68&amp;quot;, &lt;br /&gt;
        &amp;quot;0ae2ffae-7265-524d-cb76-c2b691992706&amp;quot;];&lt;br /&gt;
list    CHARACTER_GRID2  = [         &lt;br /&gt;
        &amp;quot;f6e41cf2-1104-bd0b-0190-dffad1bac813&amp;quot;, &lt;br /&gt;
        &amp;quot;2b4bb15e-956d-56ae-69f5-d26a20de0ce7&amp;quot;, &lt;br /&gt;
        &amp;quot;f816da2c-51f1-612a-2029-a542db7db882&amp;quot;, &lt;br /&gt;
        &amp;quot;345fea05-c7be-465c-409f-9dcb3bd2aa07&amp;quot;, &lt;br /&gt;
        &amp;quot;b3017e02-c063-5185-acd5-1ef5f9d79b89&amp;quot;, &lt;br /&gt;
        &amp;quot;4dcff365-1971-3c2b-d73c-77e1dc54242a&amp;quot; &lt;br /&gt;
          ]; &lt;br /&gt;
&lt;br /&gt;
///////////// END CONSTANTS ////////////////&lt;br /&gt;
&lt;br /&gt;
///////////// GLOBAL VARIABLES /////////////// &lt;br /&gt;
// All displayable characters.  Default to ASCII order. &lt;br /&gt;
string gCharIndex; &lt;br /&gt;
// This is the channel to listen on while acting &lt;br /&gt;
// as a cell in a larger display. &lt;br /&gt;
integer gCellChannel      = -1; &lt;br /&gt;
// This is the starting character position in the cell channel message &lt;br /&gt;
// to render. &lt;br /&gt;
integer gCellCharPosition = 0;&lt;br /&gt;
// This is whether or not to use the fade in/out special effect. &lt;br /&gt;
integer gCellUseFading      = FALSE; &lt;br /&gt;
// This is how long to display the text before fading out (if using &lt;br /&gt;
// fading special effect). &lt;br /&gt;
// Note: &amp;lt; 0  means don&#039;t fade out. &lt;br /&gt;
float   gCellHoldDelay      = 1.0; &lt;br /&gt;
&lt;br /&gt;
integer gSlaveRegistered;&lt;br /&gt;
list gSlaveNames;&lt;br /&gt;
&lt;br /&gt;
integer BANK_STRIDE=3; //offset, length, highest_dirty&lt;br /&gt;
list gBankingData;&lt;br /&gt;
&lt;br /&gt;
/////////// END GLOBAL VARIABLES //////////// &lt;br /&gt;
&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug. &lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
    gCharIndex += &amp;quot;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridPos(integer index1, integer index2) { &lt;br /&gt;
    // There are two ways to use the lookup table... &lt;br /&gt;
    integer Col; &lt;br /&gt;
    integer Row; &lt;br /&gt;
    if (index1 &amp;gt;= index2) { &lt;br /&gt;
        // In this case, the row is the index of the first character: &lt;br /&gt;
        Row = index1; &lt;br /&gt;
        // And the col is the index of the second character (x2) &lt;br /&gt;
        Col = index2 * 2; &lt;br /&gt;
    } &lt;br /&gt;
    else { // Index1 &amp;lt; Index2 &lt;br /&gt;
        // In this case, the row is the index of the second character: &lt;br /&gt;
        Row = index2; &lt;br /&gt;
        // And the col is the index of the first character, x2, offset by 1. &lt;br /&gt;
        Col = index1 * 2 + 1; &lt;br /&gt;
    } &lt;br /&gt;
    return &amp;lt;Col, Row, 0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
string GetGridTexture(vector grid_pos) { &lt;br /&gt;
    // Calculate the texture in the grid to use. &lt;br /&gt;
    integer GridCol = llRound(grid_pos.x) / 20; &lt;br /&gt;
    integer GridRow = llRound(grid_pos.y) / 10; &lt;br /&gt;
&lt;br /&gt;
    // Lookup the texture. &lt;br /&gt;
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol); &lt;br /&gt;
    return Texture; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(vector grid_pos) { &lt;br /&gt;
    // Zoom in on the texture showing our character pair. &lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 20; &lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 10; &lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture. &lt;br /&gt;
    return &amp;lt;-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
     &lt;br /&gt;
               &lt;br /&gt;
   llSetLinkPrimitiveParams( link , [ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters. &lt;br /&gt;
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   &lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//RenderWithEffects(integer link, string str) { &lt;br /&gt;
//    // Get the grid positions for each pair of characters. &lt;br /&gt;
//    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
//    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
//    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
//    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
//    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
//                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                          //         &lt;br /&gt;
//&lt;br /&gt;
//      // First set the alpha to the lowest possible. &lt;br /&gt;
//   llSetAlpha(0.05, ALL_SIDES); &lt;br /&gt;
//&lt;br /&gt;
//    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
//    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
//&lt;br /&gt;
//    float Alpha = 0.10; &lt;br /&gt;
//    for (; Alpha &amp;lt;= 1.0; Alpha += 0.05)  &lt;br /&gt;
//       llSetAlpha(Alpha, ALL_SIDES); &lt;br /&gt;
//          // See if we want to fade out as well. &lt;br /&gt;
//   if (gCellHoldDelay &amp;lt; 0.0) &lt;br /&gt;
//       // No, bail out. (Just keep showing the string at full strength). &lt;br /&gt;
//       return; &lt;br /&gt;
//          // Hold the text for a while. &lt;br /&gt;
//   llSleep(gCellHoldDelay); &lt;br /&gt;
//      // Now fade out. &lt;br /&gt;
//   for (Alpha = 0.95; Alpha &amp;gt;= 0.05; Alpha -= 0.05) &lt;br /&gt;
//       llSetAlpha(Alpha, ALL_SIDES); &lt;br /&gt;
//          // Make the text transparent to fully hide it. &lt;br /&gt;
//   llSetTexture(TRANSPARENT, ALL_SIDES); &lt;br /&gt;
//} &lt;br /&gt;
&lt;br /&gt;
integer RenderExtended(integer link, string str,integer render) {&lt;br /&gt;
    // Look for escape sequences.&lt;br /&gt;
    integer length = 0;&lt;br /&gt;
    list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);&lt;br /&gt;
    integer ParsedLen = llGetListLength(Parsed);&lt;br /&gt;
&lt;br /&gt;
    // Create a list of index values to work with.&lt;br /&gt;
    list Indices;&lt;br /&gt;
    // We start with room for 6 indices.&lt;br /&gt;
    integer IndicesLeft = 10;&lt;br /&gt;
&lt;br /&gt;
    string Token;&lt;br /&gt;
    integer Clipped;&lt;br /&gt;
    integer LastWasEscapeSequence = FALSE;&lt;br /&gt;
    // Work from left to right.&lt;br /&gt;
    integer i=0;&lt;br /&gt;
    for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) {&lt;br /&gt;
        Token = llList2String(Parsed, i);&lt;br /&gt;
&lt;br /&gt;
        // If this is an escape sequence, just set the flag and move on.&lt;br /&gt;
        if (Token == ESCAPE_SEQUENCE) {&lt;br /&gt;
            LastWasEscapeSequence = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else { // Token != ESCAPE_SEQUENCE&lt;br /&gt;
            // Otherwise this is a normal token.  Check its length.&lt;br /&gt;
            Clipped = FALSE;&lt;br /&gt;
            integer TokenLength = llStringLength(Token);&lt;br /&gt;
            // Clip if necessary.&lt;br /&gt;
            if (TokenLength &amp;gt; IndicesLeft) {&lt;br /&gt;
                TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));&lt;br /&gt;
                IndicesLeft = 0;&lt;br /&gt;
                Clipped = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                IndicesLeft -= TokenLength;&lt;br /&gt;
&lt;br /&gt;
            // Was the previous token an escape sequence?&lt;br /&gt;
            if (LastWasEscapeSequence) {&lt;br /&gt;
                // Yes, the first character is an escape character, the rest are normal.&lt;br /&gt;
                length += 2 + TokenLength;&lt;br /&gt;
                if (render)&lt;br /&gt;
                {&lt;br /&gt;
                    // This is the extended character.&lt;br /&gt;
                    Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];&lt;br /&gt;
                    &lt;br /&gt;
                    // These are the normal characters.&lt;br /&gt;
                    integer j=1;&lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                    {&lt;br /&gt;
                        Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else { // Normal string.&lt;br /&gt;
                // Just add the characters normally.&lt;br /&gt;
                length += TokenLength;&lt;br /&gt;
                if(render)&lt;br /&gt;
                {&lt;br /&gt;
                    integer j=0;&lt;br /&gt;
                    for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                    {&lt;br /&gt;
                        Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Unset this flag, since this was not an escape sequence.&lt;br /&gt;
            LastWasEscapeSequence = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(render)&lt;br /&gt;
    {&lt;br /&gt;
        // Use the indices to create grid positions.&lt;br /&gt;
        vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );&lt;br /&gt;
        vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );&lt;br /&gt;
        vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );&lt;br /&gt;
        vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );&lt;br /&gt;
        vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );&lt;br /&gt;
        &lt;br /&gt;
        // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
        ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
    }&lt;br /&gt;
    return length;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) {&lt;br /&gt;
    // This converts from an ASCII based index to our indexing scheme.&lt;br /&gt;
    if (index &amp;gt;= 32) // &#039; &#039; or higher&lt;br /&gt;
        index -= 32;&lt;br /&gt;
    else { // index &amp;lt; 32&lt;br /&gt;
        // Quick bounds check.&lt;br /&gt;
        if (index &amp;gt; 15)&lt;br /&gt;
            index = 15;&lt;br /&gt;
&lt;br /&gt;
        index += 94; // extended characters&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return index;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PassToRender(integer render,string message, integer bank)&lt;br /&gt;
{&lt;br /&gt;
    float time;&lt;br /&gt;
    integer extendedlen = 0;&lt;br /&gt;
    integer link;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    integer msgLen = llStringLength(message);&lt;br /&gt;
    string TextToRender;&lt;br /&gt;
    integer num_slaves=llGetListLength(gSlaveNames);&lt;br /&gt;
    string slave_name; //avoids unnecessary casts, keeping it as a string&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
    integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
&lt;br /&gt;
    integer x=0;    &lt;br /&gt;
    for (;x &amp;lt; msgLen;x = x + 10)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;gt;= bank_length)  //we don&#039;t want to run off the end of the bank&lt;br /&gt;
        {&lt;br /&gt;
            //set the dirty to max, and bail out, we&#039;re done&lt;br /&gt;
            gBankingData=llListReplaceList(gBankingData, [bank_length], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
            return;&lt;br /&gt;
        }   &lt;br /&gt;
        &lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        TextToRender = llGetSubString(message, x, x + 20);&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves +1)))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if(llSubStringIndex(TextToRender,&amp;quot;\e&amp;quot;)&amp;gt;x+10)&lt;br /&gt;
                {&lt;br /&gt;
                    extendedlen = 10;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    extendedlen = RenderExtended(link,TextToRender,0);&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if(extendedlen&amp;gt;10)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen-10;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                llMessageLinked(LINK_THIS,SLAVE_DISPLAY_EXTENDED,TextToRender,(key)((string)link+&amp;quot;,&amp;quot;+slave_name));&lt;br /&gt;
            }        &lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (render == 1)&lt;br /&gt;
                RenderString(link,TextToRender);&lt;br /&gt;
            if (render == 2)&lt;br /&gt;
            {&lt;br /&gt;
                extendedlen = RenderExtended(link,TextToRender,1);&lt;br /&gt;
                if(extendedlen&amp;gt;10)&lt;br /&gt;
                {&lt;br /&gt;
                    x += extendedlen-10;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
//            if (render == 3)&lt;br /&gt;
//                RenderWithEffects(link,TextToRender);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;            &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (bank_highest_dirty==0)&lt;br /&gt;
        bank_highest_dirty=bank_length;&lt;br /&gt;
    &lt;br /&gt;
    integer current_highest_dirty=i;&lt;br /&gt;
    while (i &amp;lt; bank_highest_dirty)&lt;br /&gt;
    {&lt;br /&gt;
        link = unpack(gXyTextPrims,(i + bank_offset));&lt;br /&gt;
        &lt;br /&gt;
        if(gSlaveRegistered &amp;amp;&amp;amp; (link % (num_slaves+1) != 0))&lt;br /&gt;
        {&lt;br /&gt;
            slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_DISPLAY, &amp;quot;     &amp;quot;, (key)((string)link + &amp;quot;,&amp;quot; + slave_name));       &lt;br /&gt;
            //sorry, no fade effect with slave&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            RenderString(link,&amp;quot;          &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        ++i;        &lt;br /&gt;
    }&lt;br /&gt;
    gBankingData=llListReplaceList(gBankingData, [current_highest_dirty], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka&lt;br /&gt;
list gXyTextPrims;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer get_number_of_prims()&lt;br /&gt;
{//ignores avatars.&lt;br /&gt;
    integer a = llGetNumberOfPrims();&lt;br /&gt;
    while(llGetAgentSize(llGetLinkKey(a)))&lt;br /&gt;
        --a;&lt;br /&gt;
    return a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//functions to pack 8-bit shorts into ints&lt;br /&gt;
list pack_and_insert(list in_list, integer pos, integer value)&lt;br /&gt;
{&lt;br /&gt;
//    //figure out the bitpack position&lt;br /&gt;
//    integer pack = pos &amp;amp; 3; //4 bytes per int&lt;br /&gt;
//    pos=pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
//    integer shifted = value &amp;lt;&amp;lt; (pack &amp;lt;&amp;lt; 3);&lt;br /&gt;
//    integer old_value = llList2Integer(in_list, pos);&lt;br /&gt;
//    shifted = old_value | shifted;&lt;br /&gt;
//    in_list = llListReplaceList(in_list, (list)shifted, pos, pos);&lt;br /&gt;
//    return in_list;&lt;br /&gt;
    //Safe optimized version&lt;br /&gt;
    integer index = pos &amp;gt;&amp;gt; 2;&lt;br /&gt;
    return llListReplaceList(in_list, (list)(llList2Integer(in_list, index) | (value &amp;lt;&amp;lt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3))), index, index);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer unpack(list in_list, integer pos)&lt;br /&gt;
{&lt;br /&gt;
    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;gt;&amp;gt; ((pos &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;amp; 0x000000FF;//unsigned&lt;br /&gt;
//    return (llList2Integer(in_list, pos &amp;gt;&amp;gt; 2) &amp;lt;&amp;lt; (((~pos) &amp;amp; 3) &amp;lt;&amp;lt; 3)) &amp;gt;&amp;gt; 24;//signed&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
change_color(vector color)&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=llGetListLength(gXyTextPrims) &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    integer i = 0;&lt;br /&gt;
    &lt;br /&gt;
    for (; i&amp;lt;=num_prims; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
change_line_color(integer bank, vector color)&lt;br /&gt;
{    &lt;br /&gt;
&lt;br /&gt;
    //get the bank offset and length&lt;br /&gt;
    integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));&lt;br /&gt;
    integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);&lt;br /&gt;
&lt;br /&gt;
    for (; i &amp;lt; bank_end; ++i)&lt;br /&gt;
    {     &lt;br /&gt;
        integer link = unpack(gXyTextPrims,i);&lt;br /&gt;
        if (!link)&lt;br /&gt;
            return;&lt;br /&gt;
        &lt;br /&gt;
        llSetLinkPrimitiveParams( link,[ &lt;br /&gt;
            PRIM_COLOR, FACE_1, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_2, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_3, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_4, color, 1.0,&lt;br /&gt;
            PRIM_COLOR, FACE_5, color, 1.0&lt;br /&gt;
        ]);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
init()&lt;br /&gt;
{&lt;br /&gt;
    integer num_prims=get_number_of_prims();&lt;br /&gt;
&lt;br /&gt;
    string link_name;&lt;br /&gt;
    integer bank=0;&lt;br /&gt;
    integer bank_empty=FALSE;&lt;br /&gt;
    integer prims_pointer=0; //&amp;quot;pointer&amp;quot; to the next entry to be used in the gXyTextPrims list.&lt;br /&gt;
    &lt;br /&gt;
    list temp_bank=[];&lt;br /&gt;
    integer temp_bank_stride=2;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
    gXyTextPrims=[];&lt;br /&gt;
    integer x=0;&lt;br /&gt;
    for (;x&amp;lt;64;++x)&lt;br /&gt;
    {&lt;br /&gt;
        gXyTextPrims= (gXyTextPrims = []) + gXyTextPrims + [0];  //we need to pad out the list to make it easier to add things in any order later&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    @loop;&lt;br /&gt;
    &lt;br /&gt;
    {&lt;br /&gt;
       &lt;br /&gt;
        //loop over all prims, looking for ones in the current bank&lt;br /&gt;
        for(x=0;x&amp;lt;=num_prims;++x)&lt;br /&gt;
        {&lt;br /&gt;
            link_name=llGetLinkName(x);&lt;br /&gt;
            list tmp = llParseString2List(link_name, [&amp;quot;-&amp;quot;], []);&lt;br /&gt;
            if(llList2String(tmp,0)== &amp;quot;xyzzytext&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                integer prims_bank=llList2Integer(tmp,1);&lt;br /&gt;
                if (llList2Integer(tmp,1)==bank)&lt;br /&gt;
                {&lt;br /&gt;
                    temp_bank+=llList2Integer(tmp,2) + (list)x;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
        if (temp_bank!=[])&lt;br /&gt;
        {&lt;br /&gt;
            //sort the current bank&lt;br /&gt;
            temp_bank=llListSort(temp_bank, temp_bank_stride, TRUE);&lt;br /&gt;
            &lt;br /&gt;
            integer temp_len=llGetListLength(temp_bank);&lt;br /&gt;
            &lt;br /&gt;
            //store metadata&lt;br /&gt;
            gBankingData+=[prims_pointer,temp_len/temp_bank_stride,0];&lt;br /&gt;
            &lt;br /&gt;
            //repack the bank into the prim list&lt;br /&gt;
            for (x=0; x &amp;lt; temp_len; x+=temp_bank_stride)&lt;br /&gt;
            {&lt;br /&gt;
                gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, x+1));&lt;br /&gt;
                ++prims_pointer;&lt;br /&gt;
            }&lt;br /&gt;
            ++bank;&lt;br /&gt;
            temp_bank=[];&lt;br /&gt;
            jump loop;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llMessageLinked(LINK_THIS, SLAVE_RESET, &amp;quot;&amp;quot; , null_key);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
    state_entry() { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        init();&lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) {&lt;br /&gt;
        if(id == null_key)&lt;br /&gt;
            id=&amp;quot;0&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        if (channel == DISPLAY_STRING) { &lt;br /&gt;
            PassToRender(1,data, (integer)((string)id)); &lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
        else if (channel == DISPLAY_EXTENDED) { &lt;br /&gt;
             PassToRender(2,data, (integer)((string)id)); &lt;br /&gt;
            return; &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == REMAP_INDICES) {&lt;br /&gt;
            // Parse the message, splitting it up into index values.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            integer i;&lt;br /&gt;
            // Go through the list and swap each pair of indices.&lt;br /&gt;
            for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) {&lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );&lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );&lt;br /&gt;
&lt;br /&gt;
                // Swap these index values.&lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) {&lt;br /&gt;
            // Restore the character index back to default settings.&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            return;&lt;br /&gt;
        }        &lt;br /&gt;
        else if (channel == RESCAN_LINKSET)&lt;br /&gt;
        {&lt;br /&gt;
            init();&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_COLOR) {&lt;br /&gt;
            change_color((vector)data); &lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == SET_LINE_COLOR) {&lt;br /&gt;
            change_line_color((integer)((string)id), (vector)data); &lt;br /&gt;
        }     &lt;br /&gt;
        else if (channel == REGISTER_SLAVE)&lt;br /&gt;
        {&lt;br /&gt;
            if(!~llListFindList(gSlaveNames, (list)data))&lt;br /&gt;
            {//isn&#039;t registered yet&lt;br /&gt;
                gSlaveNames += data;&lt;br /&gt;
                gSlaveRegistered=TRUE;&lt;br /&gt;
                //llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave(s) Recognized: &amp;quot; + data);&lt;br /&gt;
            }&lt;br /&gt;
//            else&lt;br /&gt;
//            {//it already exists&lt;br /&gt;
//                llOwnerSay((string)llGetListLength(gSlaveNames) + &amp;quot; Slave, Existing Slave Recognized: &amp;quot; + data);&lt;br /&gt;
//            }&lt;br /&gt;
            llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , null_key);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if(change&amp;amp;CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            if(gSlaveRegistered)        &lt;br /&gt;
            {&lt;br /&gt;
                //by using negative indexes they don&#039;t need to be adjusted when an entry is deleted.&lt;br /&gt;
                integer x = ~llGetListLength(gSlaveNames);&lt;br /&gt;
                while(++x)&lt;br /&gt;
                {&lt;br /&gt;
                    if (!~llGetInventoryType(llList2String(gSlaveNames, x)))&lt;br /&gt;
                    {&lt;br /&gt;
                        //llOwnerSay(&amp;quot;Slave Removed: &amp;quot; + llList2String(gSlaveNames, x));&lt;br /&gt;
                        gSlaveNames = llDeleteSubList(gSlaveNames, x, x);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                gSlaveRegistered = !(gSlaveNames == []);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Slave Script ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText v2.1(10-Char) by Thraxis Epsilon&lt;br /&gt;
// XyText v2.0 SLAVE Script (5 Face, Single Texture) &lt;br /&gt;
//&lt;br /&gt;
// Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007&lt;br /&gt;
// Rewrite to allow one-script-per-object operation w/ optional slaves&lt;br /&gt;
// Enable prim-label functionality&lt;br /&gt;
// Enabled Banking&lt;br /&gt;
// Enabled 10-char per prim&lt;br /&gt;
//&lt;br /&gt;
// Modified by Kermitt Quirk 19/01/2006 &lt;br /&gt;
// To add support for 5 face prim instead of 3 &lt;br /&gt;
// &lt;br /&gt;
// Originally Written by Xylor Baysklef &lt;br /&gt;
// &lt;br /&gt;
//&lt;br /&gt;
//////////////////////////////////////////// &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
integer REMAP_INDICES       = 204002; &lt;br /&gt;
integer RESET_INDICES       = 204003;&lt;br /&gt;
&lt;br /&gt;
//internal API&lt;br /&gt;
integer REGISTER_SLAVE      = 205000;&lt;br /&gt;
integer SLAVE_RECOGNIZED    = 205001;&lt;br /&gt;
integer SLAVE_DISPLAY       = 205003;&lt;br /&gt;
integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
&lt;br /&gt;
integer SLAVE_DISPLAY_EXTENDED = 205004;&lt;br /&gt;
integer SLAVE_RESET = 205005;&lt;br /&gt;
&lt;br /&gt;
// This is an extended character escape sequence.&lt;br /&gt;
string  ESCAPE_SEQUENCE = &amp;quot;\\e&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// This is used to get an index for the extended character.&lt;br /&gt;
string  EXTENDED_INDEX  = &amp;quot;123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Face numbers. &lt;br /&gt;
integer FACE_1          = 3; &lt;br /&gt;
integer FACE_2          = 7; &lt;br /&gt;
integer FACE_3          = 4; &lt;br /&gt;
integer FACE_4          = 6; &lt;br /&gt;
integer FACE_5          = 1;&lt;br /&gt;
&lt;br /&gt;
// This is a list of textures for all 2-character combinations. &lt;br /&gt;
list    CHARACTER_GRID  = [ &lt;br /&gt;
        &amp;quot;00e9f9f7-0669-181c-c192-7f8e67678c8d&amp;quot;, &lt;br /&gt;
        &amp;quot;347a5cb6-0031-7ec0-2fcf-f298eebf3c0e&amp;quot;, &lt;br /&gt;
        &amp;quot;4e7e689e-37f1-9eca-8596-a958bbd23963&amp;quot;, &lt;br /&gt;
        &amp;quot;19ea9c21-67ba-8f6f-99db-573b1b877eb1&amp;quot;, &lt;br /&gt;
        &amp;quot;dde7b412-cda1-652f-6fc2-73f4641f96e1&amp;quot;, &lt;br /&gt;
        &amp;quot;af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da&amp;quot;, &lt;br /&gt;
        &amp;quot;a201d3a2-364b-43b6-8686-5881c0f82a94&amp;quot;, &lt;br /&gt;
        &amp;quot;b674dec8-fead-99e5-c28d-2db8e4c51540&amp;quot;, &lt;br /&gt;
        &amp;quot;366e05f3-be6b-e5cf-c33b-731dff649caa&amp;quot;, &lt;br /&gt;
        &amp;quot;75c4925c-0427-dc0c-c71c-e28674ff4d27&amp;quot;, &lt;br /&gt;
        &amp;quot;dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6&amp;quot;, &lt;br /&gt;
        &amp;quot;0dca2feb-fc66-a762-db85-89026a4ecd68&amp;quot;, &lt;br /&gt;
        &amp;quot;a0fca76f-503a-946b-9336-0a918e886f7a&amp;quot;, &lt;br /&gt;
        &amp;quot;67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4&amp;quot;, &lt;br /&gt;
        &amp;quot;300470b2-da34-5470-074c-1b8464ca050c&amp;quot;, &lt;br /&gt;
        &amp;quot;d1f8e91c-ce2b-d85e-2120-930d3b630946&amp;quot;, &lt;br /&gt;
        &amp;quot;2a190e44-7b29-dadb-0bff-c31adaf5a170&amp;quot;, &lt;br /&gt;
        &amp;quot;75d55e71-f6f8-9835-e746-a45f189f30a1&amp;quot;, &lt;br /&gt;
        &amp;quot;300fac33-2b30-3da3-26bc-e2d70428ec19&amp;quot;, &lt;br /&gt;
        &amp;quot;0747c776-011a-53ce-13ee-8b5bb9e87c1e&amp;quot;, &lt;br /&gt;
        &amp;quot;85a855c3-a94f-01ca-33e0-7dde92e727e2&amp;quot;, &lt;br /&gt;
        &amp;quot;cbc1dab2-2d61-2986-1949-7a5235c954e1&amp;quot;, &lt;br /&gt;
        &amp;quot;f7aef047-f266-9596-16df-641010edd8e1&amp;quot;, &lt;br /&gt;
        &amp;quot;4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a69e98c-26a5-ad05-e92e-b5b906ad9ef9&amp;quot;, &lt;br /&gt;
        &amp;quot;462a9226-2a97-91ac-2d89-57ab33334b78&amp;quot;, &lt;br /&gt;
        &amp;quot;20b24b3a-8c57-82ee-c6ed-555003f5dbcd&amp;quot;, &lt;br /&gt;
        &amp;quot;9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217&amp;quot;, &lt;br /&gt;
        &amp;quot;c231dbdc-c842-15b0-7aa6-6da14745cfdc&amp;quot;, &lt;br /&gt;
        &amp;quot;c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf&amp;quot;, &lt;br /&gt;
        &amp;quot;f1e7d030-ff80-a242-cb69-f6951d4eae3b&amp;quot;, &lt;br /&gt;
        &amp;quot;ed32d6c4-d733-c0f1-f242-6df1d222220d&amp;quot;, &lt;br /&gt;
        &amp;quot;88f96a30-dccf-9b20-31ef-da0dfeb23c72&amp;quot;, &lt;br /&gt;
        &amp;quot;252f2595-58b8-4bcc-6515-fa274d0cfb65&amp;quot;, &lt;br /&gt;
        &amp;quot;f2838c4f-de80-cced-dff8-195dfdf36b2c&amp;quot;, &lt;br /&gt;
        &amp;quot;cc2594fe-add2-a3df-cdb3-a61711badf53&amp;quot;, &lt;br /&gt;
        &amp;quot;e0ce2972-da00-955c-129e-3289b3676776&amp;quot;, &lt;br /&gt;
        &amp;quot;3e0d336d-321f-ddfa-5c1b-e26131766f6a&amp;quot;, &lt;br /&gt;
        &amp;quot;d43b1dc4-6b51-76a7-8b90-38865b82bf06&amp;quot;, &lt;br /&gt;
        &amp;quot;06d16cbb-1868-fd1d-5c93-eae42164a37d&amp;quot;, &lt;br /&gt;
        &amp;quot;dd5d98cf-273e-3fd0-f030-48be58ee3a0b&amp;quot;, &lt;br /&gt;
        &amp;quot;0e47c89e-de4a-6233-a2da-cb852aad1b00&amp;quot;, &lt;br /&gt;
        &amp;quot;fb9c4a55-0e13-495b-25c4-f0b459dc06de&amp;quot;, &lt;br /&gt;
        &amp;quot;e3ce8def-312c-735b-0e48-018b6799c883&amp;quot;, &lt;br /&gt;
        &amp;quot;2f713216-4e71-d123-03ed-9c8554710c6b&amp;quot;, &lt;br /&gt;
        &amp;quot;4a417d8a-1f4f-404b-9783-6672f8527911&amp;quot;, &lt;br /&gt;
        &amp;quot;ca5e21ec-5b20-5909-4c31-3f90d7316b33&amp;quot;, &lt;br /&gt;
        &amp;quot;06a4fcc3-e1c4-296d-8817-01f88fbd7367&amp;quot;, &lt;br /&gt;
        &amp;quot;130ac084-6f3c-95de-b5b6-d25c80703474&amp;quot;, &lt;br /&gt;
        &amp;quot;59d540a0-ae9d-3606-5ae0-4f2842b64cfa&amp;quot;, &lt;br /&gt;
        &amp;quot;8612ae9a-f53c-5bf4-2899-8174d7abc4fd&amp;quot;, &lt;br /&gt;
        &amp;quot;12467401-e979-2c49-34e0-6ac761542797&amp;quot;, &lt;br /&gt;
        &amp;quot;d53c3eaa-0404-3860-0675-3e375596c3e3&amp;quot;, &lt;br /&gt;
        &amp;quot;9f5b26bd-81d3-b25e-62fe-5b671d1e3e79&amp;quot;, &lt;br /&gt;
        &amp;quot;f57f0b64-a050-d617-ee00-c8e9e3adc9cb&amp;quot;, &lt;br /&gt;
        &amp;quot;beff166a-f5f3-f05e-e020-98f2b00e27ed&amp;quot;, &lt;br /&gt;
        &amp;quot;02278a65-94ba-6d5e-0d2b-93f2e4f4bf70&amp;quot;, &lt;br /&gt;
        &amp;quot;a707197d-449e-5b58-846c-0c850c61f9d6&amp;quot;, &lt;br /&gt;
        &amp;quot;021d4b1a-9503-a44f-ee2b-976eb5d80e68&amp;quot;, &lt;br /&gt;
        &amp;quot;0ae2ffae-7265-524d-cb76-c2b691992706&amp;quot;, &lt;br /&gt;
        &amp;quot;f6e41cf2-1104-bd0b-0190-dffad1bac813&amp;quot;, &lt;br /&gt;
        &amp;quot;2b4bb15e-956d-56ae-69f5-d26a20de0ce7&amp;quot;, &lt;br /&gt;
        &amp;quot;f816da2c-51f1-612a-2029-a542db7db882&amp;quot;, &lt;br /&gt;
        &amp;quot;345fea05-c7be-465c-409f-9dcb3bd2aa07&amp;quot;];&lt;br /&gt;
list    CHARACTER_GRID2  = [         &lt;br /&gt;
        &amp;quot;b3017e02-c063-5185-acd5-1ef5f9d79b89&amp;quot;, &lt;br /&gt;
        &amp;quot;4dcff365-1971-3c2b-d73c-77e1dc54242a&amp;quot; &lt;br /&gt;
          ]; &lt;br /&gt;
&lt;br /&gt;
///////////// END CONSTANTS ////////////////&lt;br /&gt;
string gCharIndex; &lt;br /&gt;
&lt;br /&gt;
integer gActive; //if we are recognized, this is true&lt;br /&gt;
/////////// END GLOBAL VARIABLES ////////////&lt;br /&gt;
ResetCharIndex() { &lt;br /&gt;
    gCharIndex  = &amp;quot; !\&amp;quot;#$%&amp;amp;&#039;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`&amp;quot;; &lt;br /&gt;
    // \&amp;quot; &amp;lt;-- Fixes LSL syntax highlighting bug. &lt;br /&gt;
    gCharIndex += &amp;quot;abcdefghijklmnopqrstuvwxyz{|}~&amp;quot;; &lt;br /&gt;
    gCharIndex += &amp;quot;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n&amp;quot;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridPos(integer index1, integer index2) { &lt;br /&gt;
    // There are two ways to use the lookup table... &lt;br /&gt;
    integer Col; &lt;br /&gt;
    integer Row; &lt;br /&gt;
    if (index1 &amp;gt;= index2) { &lt;br /&gt;
        // In this case, the row is the index of the first character: &lt;br /&gt;
        Row = index1; &lt;br /&gt;
        // And the col is the index of the second character (x2) &lt;br /&gt;
        Col = index2 * 2; &lt;br /&gt;
    } &lt;br /&gt;
    else { // Index1 &amp;lt; Index2 &lt;br /&gt;
        // In this case, the row is the index of the second character: &lt;br /&gt;
        Row = index2; &lt;br /&gt;
        // And the col is the index of the first character, x2, offset by 1. &lt;br /&gt;
        Col = index1 * 2 + 1; &lt;br /&gt;
    } &lt;br /&gt;
    return &amp;lt;Col, Row, 0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
string GetGridTexture(vector grid_pos) { &lt;br /&gt;
    // Calculate the texture in the grid to use. &lt;br /&gt;
    integer GridCol = llRound(grid_pos.x) / 20; &lt;br /&gt;
    integer GridRow = llRound(grid_pos.y) / 10; &lt;br /&gt;
&lt;br /&gt;
    // Lookup the texture. &lt;br /&gt;
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol); &lt;br /&gt;
    return Texture; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
vector GetGridOffset(vector grid_pos) { &lt;br /&gt;
    // Zoom in on the texture showing our character pair. &lt;br /&gt;
    integer Col = llRound(grid_pos.x) % 20; &lt;br /&gt;
    integer Row = llRound(grid_pos.y) % 10; &lt;br /&gt;
&lt;br /&gt;
    // Return the offset in the texture. &lt;br /&gt;
    return &amp;lt;-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0&amp;gt;; &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
ShowChars(integer link,vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) { &lt;br /&gt;
   // Set the primitive textures directly. &lt;br /&gt;
     &lt;br /&gt;
               &lt;br /&gt;
   llSetLinkPrimitiveParams( link , [ &lt;br /&gt;
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos1) + &amp;lt;0.075, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos2), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), &amp;lt;-1.48, 0.1, 0&amp;gt;, GetGridOffset(grid_pos3)+ &amp;lt;0.37, 0, 0&amp;gt;, 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), &amp;lt;0.1, 0.1, 0&amp;gt;, GetGridOffset(grid_pos4), 0.0, &lt;br /&gt;
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), &amp;lt;0.25, 0.1, 0&amp;gt;, GetGridOffset(grid_pos5) - &amp;lt;0.075, 0, 0&amp;gt;, 0.0 &lt;br /&gt;
        ]); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderString(integer link, string str) {&lt;br /&gt;
    // Get the grid positions for each pair of characters. &lt;br /&gt;
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) ); &lt;br /&gt;
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) ); &lt;br /&gt;
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) ); &lt;br /&gt;
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) ); &lt;br /&gt;
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)), &lt;br /&gt;
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   &lt;br /&gt;
&lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets. &lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
RenderExtended(integer link, string str) {&lt;br /&gt;
    // Look for escape sequences.&lt;br /&gt;
    list Parsed       = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);&lt;br /&gt;
    integer ParsedLen = llGetListLength(Parsed);&lt;br /&gt;
&lt;br /&gt;
    // Create a list of index values to work with.&lt;br /&gt;
    list Indices;&lt;br /&gt;
    // We start with room for 6 indices.&lt;br /&gt;
    integer IndicesLeft = 10;&lt;br /&gt;
&lt;br /&gt;
    string Token;&lt;br /&gt;
    integer Clipped;&lt;br /&gt;
    integer LastWasEscapeSequence = FALSE;&lt;br /&gt;
    // Work from left to right.&lt;br /&gt;
    integer i=0;&lt;br /&gt;
    for (; i &amp;lt; ParsedLen &amp;amp;&amp;amp; IndicesLeft &amp;gt; 0; ++i) {&lt;br /&gt;
        Token = llList2String(Parsed, i);&lt;br /&gt;
&lt;br /&gt;
        // If this is an escape sequence, just set the flag and move on.&lt;br /&gt;
        if (Token == ESCAPE_SEQUENCE) {&lt;br /&gt;
            LastWasEscapeSequence = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else { // Token != ESCAPE_SEQUENCE&lt;br /&gt;
            // Otherwise this is a normal token.  Check its length.&lt;br /&gt;
            Clipped = FALSE;&lt;br /&gt;
            integer TokenLength = llStringLength(Token);&lt;br /&gt;
            // Clip if necessary.&lt;br /&gt;
            if (TokenLength &amp;gt; IndicesLeft) {&lt;br /&gt;
                TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));&lt;br /&gt;
                IndicesLeft = 0;&lt;br /&gt;
                Clipped = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
                IndicesLeft -= TokenLength;&lt;br /&gt;
&lt;br /&gt;
            // Was the previous token an escape sequence?&lt;br /&gt;
            if (LastWasEscapeSequence) {&lt;br /&gt;
                // Yes, the first character is an escape character, the rest are normal.&lt;br /&gt;
                // This is the extended character.&lt;br /&gt;
                Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];&lt;br /&gt;
                &lt;br /&gt;
                // These are the normal characters.&lt;br /&gt;
                integer j=1;&lt;br /&gt;
                for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                {&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else { // Normal string.&lt;br /&gt;
                // Just add the characters normally.&lt;br /&gt;
                integer j=0;&lt;br /&gt;
                for (; j &amp;lt; TokenLength; ++j)&lt;br /&gt;
                {&lt;br /&gt;
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Unset this flag, since this was not an escape sequence.&lt;br /&gt;
            LastWasEscapeSequence = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Use the indices to create grid positions.&lt;br /&gt;
    vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );&lt;br /&gt;
    vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );&lt;br /&gt;
    vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );&lt;br /&gt;
    vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );&lt;br /&gt;
    vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );&lt;br /&gt;
    &lt;br /&gt;
    // Use these grid positions to display the correct textures/offsets.&lt;br /&gt;
    ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer ConvertIndex(integer index) {&lt;br /&gt;
    // This converts from an ASCII based index to our indexing scheme.&lt;br /&gt;
    if (index &amp;gt;= 32) // &#039; &#039; or higher&lt;br /&gt;
        index -= 32;&lt;br /&gt;
    else { // index &amp;lt; 32&lt;br /&gt;
        // Quick bounds check.&lt;br /&gt;
        if (index &amp;gt; 15)&lt;br /&gt;
            index = 15;&lt;br /&gt;
&lt;br /&gt;
        index += 94; // extended characters&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return index;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
default { &lt;br /&gt;
    state_entry() &lt;br /&gt;
    { &lt;br /&gt;
        // Initialize the character index. &lt;br /&gt;
        ResetCharIndex();&lt;br /&gt;
        llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);  &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
   on_rez(integer num)&lt;br /&gt;
   {&lt;br /&gt;
      llResetScript();       &lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
    link_message(integer sender, integer channel, string data, key id) { &lt;br /&gt;
        if (channel == SLAVE_RECOGNIZED)&lt;br /&gt;
        {&lt;br /&gt;
            if (data == llGetScriptName())&lt;br /&gt;
            {&lt;br /&gt;
                gActive=TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    &lt;br /&gt;
        else if (channel == SLAVE_DISPLAY) &lt;br /&gt;
        { &lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
            &lt;br /&gt;
            &lt;br /&gt;
            RenderString(llList2Integer(params, 0),data);&lt;br /&gt;
            return; &lt;br /&gt;
        } &lt;br /&gt;
    &lt;br /&gt;
       else if (channel == SLAVE_DISPLAY_EXTENDED) &lt;br /&gt;
       {&lt;br /&gt;
            if (!gActive)  &lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            list params=llCSV2List((string)id);&lt;br /&gt;
            if (llList2String(params, 1) != llGetScriptName())&lt;br /&gt;
                return;&lt;br /&gt;
                &lt;br /&gt;
            RenderExtended(llList2Integer(params, 0),data);&lt;br /&gt;
    }&lt;br /&gt;
        else if (channel == REMAP_INDICES) {&lt;br /&gt;
            // Parse the message, splitting it up into index values.&lt;br /&gt;
            list Parsed = llCSV2List(data);&lt;br /&gt;
            integer i;&lt;br /&gt;
            // Go through the list and swap each pair of indices.&lt;br /&gt;
            for (i = 0; i &amp;lt; llGetListLength(Parsed); i += 2) {&lt;br /&gt;
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );&lt;br /&gt;
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );&lt;br /&gt;
&lt;br /&gt;
                // Swap these index values.&lt;br /&gt;
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);&lt;br /&gt;
&lt;br /&gt;
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);&lt;br /&gt;
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        else if (channel == RESET_INDICES) {&lt;br /&gt;
            // Restore the character index back to default settings.&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            return;&lt;br /&gt;
        }                 &lt;br /&gt;
       else if (channel == SLAVE_RESET)&lt;br /&gt;
        {&lt;br /&gt;
            ResetCharIndex();&lt;br /&gt;
            gActive=FALSE;&lt;br /&gt;
            llMessageLinked(LINK_THIS, REGISTER_SLAVE, llGetScriptName() , NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10-Char Prim Setup ==&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// XyzzyText Prim Setup Script (5 Face)&lt;br /&gt;
//&lt;br /&gt;
// Modified by Thraxis Epsilon&lt;br /&gt;
//&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
        llSetPrimitiveParams([&lt;br /&gt;
                    PRIM_TYPE, PRIM_TYPE_PRISM, 32, &amp;lt;0.199, 0.8, 0.0&amp;gt;, 0.30, &amp;lt;0.0, 0.0, 0.0&amp;gt;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;,&lt;br /&gt;
                    PRIM_SIZE, &amp;lt;0.03, 2.89, 0.5&amp;gt;, &lt;br /&gt;
                    PRIM_TEXTURE, 1, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;2.48, 1.0, 0.0&amp;gt;, &amp;lt;-0.74, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 6, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 4, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;14.75, 1.0, 0.0&amp;gt;, &amp;lt;0.27, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 7, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;1.0, 1.0, 0.0&amp;gt;, &amp;lt;0.0, 0.0, 0.0&amp;gt;, 0.0, &lt;br /&gt;
                    PRIM_TEXTURE, 3, &amp;quot;09b04244-9569-d21f-6de0-4bbcf5552222&amp;quot;, &amp;lt;2.48, 1.0, 0.0&amp;gt;, &amp;lt;-0.25, 0.0, 0.0&amp;gt;, 0.0]);&lt;br /&gt;
                    &lt;br /&gt;
        llRemoveInventory(llGetScriptName());&lt;br /&gt;
    } &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
{{LSLC|Library}}&lt;br /&gt;
&lt;br /&gt;
{{#vardefine:sort|XyzzyText 2.1}}&lt;/div&gt;</summary>
		<author><name>Andrew Hellershanks</name></author>
	</entry>
</feed>