Skip to content

Automatically exported from code.google.com/p/owllang

License

Unknown, Apache-2.0 licenses found

Licenses found

Unknown
license.txt
Apache-2.0
Apache-license.txt
Notifications You must be signed in to change notification settings

thisvieira/owllang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
    <title>Getting Started With Program D</title>
    <style type="text/css"
    >
*
{
font-family: sans-serif;
font-size: 10pt;
color: black;
background-color: transparent;
}
p
{
margin-left: 6pt;
margin-right: 10pt;
}
h1
{
font-size: 18pt;
font-weight: bold;
margin-left: 0pt;
}
h2, h2 *
{
background-color: #cccccc;
font-size: 16pt;
font-weight: bold;
margin-top: 12pt;
margin-bottom: 3pt;
margin-left: 0pt;
}
h3, h3 *
{
font-size: 14pt;
font-weight: bold;
margin-bottom: 0pt;
margin-left: 1pt;
}
h4, h4 *
{
font-size: 12pt;
font-weight: bold;
margin-top: 8pt;
margin-bottom: 0pt;
margin-left: 2pt;
}
p
{
margin-top: 0pt;
margin-bottom: 8pt;
}
p.docinfo
{
font-style: italic;
margin-top: 0pt;
}
em
{
color: #dd4444;
font-weight: bold;
font-style: italic;
}
span.literal
{
font-family: monospace;
font-weight: bold;
font-style: normal;
font-size: 9pt;
color: #000055;
}
span.user-value
{
font-family: monospace;
font-weight: bold;
font-style: italic;
font-size: 9pt;
color: #005500;
}
.example
{
font-family: monospace;
font-style: normal;
font-size: 9pt;
color: #000055;
margin-left: 20px;
margin-right: 20px;
}
p.example-head
{
font-family: monospace;
font-weight: bold;
font-style: normal;
color: #000055;
margin-left: 20px;
margin-right: 100pt;
margin-top: 16pt;
margin-bottom: 4pt;
border: solid windowtext 0.5pt;
padding: 1.0pt 4.0pt 1.0pt 4.0pt;
}
p.blockquote
{
font-style: italic;
margin-left: 14pt;
margin-right: 14pt;
margin-bottom: 8pt;
}
p.faq, p.faq *
{
font-weight: bold;
margin-bottom: 0pt;
}
a:link
{
color: #114466;
background-color: transparent;
}
a:visited
{
color: #441166;
background-color: transparent;
}
a:hover
{
color: #664411;
background-color: #ffbb44;
}
a.nohover:hover
{
color: #664411;
background-color: transparent;
}
a:active
{
color: #664411;
background-color: transparent;
}
div.box
{
border: solid windowtext 1.0pt;
padding: 1.0pt 4.0pt 1.0pt 4.0pt;
margin-left: 10pt;
margin-right: 100pt;
margin-top: 10pt;
margin-bottom: 10pt;
}
</style>
  </head>
  <body>
    <h1>Getting Started With Program D</h1>
    <p class="docinfo"> author: <a href="mailto:noel@aitools.org">Noel Bush</a>
      <br/> revised from a document by Kim Sullivan, with contributions from Zayn Blore and Dennis
      Daniels.<br/> Last updated: 23 April 2005</p>
    <p class="docinfo"> Please check <a href="http://aitools.org">http://aitools.org</a> for more
      documentation, including updates to this document.</p>
    <ul>
      <li>
        <a href="#preparation">0. Preparation</a>
      </li>
      <li>
        <a href="#installation">1. Installation</a>
      </li>
      <li>
        <a href="#configuration">2. Configuration</a>
      </li>
      <li>
        <a href="#startup">3. First Startup</a>
      </li>
    </ul>
    <h2>
      <a id="preparation">0. Preparation</a>
    </h2>
    <h3>0.0. Download Program D</h3>
    <p>Go to <a href="http://aitools.org/downloads">http://aitools.org/downloads</a> and get the
      latest Program D distribution.</p>
    <p>You don't necessarily need the distribution that includes source code--you can get a
      pre-compiled version that will work on any platform for which there's a compatible Java 2
      (version 1.5 or later) JRE or SDK. So unless you want to modify and rebuild the project, we
      suggest downloading <span class="literal">d-bin-current.tar.gz</span> or <span class="literal"
      >d-bin-current.zip</span>.</p>
    <h3>0.1. Get the Java Runtime (or SDK)</h3>
    <p>You need to download and install a Java 2 version 1.5 compatible JVM. Examples are the Sun
      JRE (Java Runtime Edition) or SDK (Software Development Kit). The JRE is much smaller than the
      SDK (~16MB as compared with ~44!!!). You only need the SDK if you want to rebuild the program,
      or want to develop Java programs of your own. You can download the necessary software and find
      installation instructions at <a href="http://java.sun.com/j2se/1.5.0/download.jsp"
        target="_blank">http://java.sun.com/j2se/1.5.0/download.jsp</a>.</p>
    <h3>0.2. Get Some AIML</h3>
    <p>Also at <a href="http://aitools.org/aiml-sets">http://aitools.org/aiml-sets</a>, you'll find
      several choices of freely-available AIML. Pick one and download it.</p>
    <h2>
      <a id="installation">1. Installation</a>
    </h2>
    <h3>1.0. Java</h3>
    <p>We won't cover installation instructions for the JRE/Java SDK here. We'll just assume that
      you've followed the instructions. In the following, we'll refer to the directory where you
      installed Java as <span class="user-value">JAVA_HOME</span>. (If you use Windows, this might
      be something like <span class="literal">C:\jdk1.5.0_02</span>. If you're using Linux, this
      might be <span class="literal">/usr/java/jdk1.5.0_02</span>.)</p>
    <p>You should at least be able to type &quot;<span class="literal"
      >java
      -version</span>&quot; at a command line (syntax may vary) and get a response
      something like:</p>
    <pre class="example">java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode)</pre>
    <p>If you get some kind of error like &quot;command not found&quot;, check that your
      system path settings are correct. Or, just try &quot;<span class="user-value">JAVA_HOME</span>
      <span class="literal">/java -version</span>&quot; (Linux) or &quot;<span
        class="user-value">JAVA_HOME</span>
      <span class="literal">\java.exe -version</span>&quot; (Windows), substituting your actual
        <span class="user-value">JAVA_HOME</span> path.</p>
    <h3>1.1. Program D</h3>
    <p>If you're upgrading from a previous version, please check the <a href="release-notes.html"
        >release notes</a>, since some configuration files may have changed.</p>
    <p>Unzip/untar the Program D download in a convenient location. On Linux, we suggest <span
        class="literal">/usr/local/ProgramD</span>; on Windows, the root directory (<span
        class="literal">C:\</span>, perhaps) is as good as anything. The unzipping/untarring process
      will create a directory called <span class="literal">ProgramD</span> that will contain all the
      program files.</p>
    <p>Linux users may type:</p>
    <p class="example"> tar xvjf programd-4.5rc1-bin.tar.bz2</p>
    <p>Windows 95-2000 users could try a free unzip utility such as <a href="http://www.7-zip.org"
      >7-Zip</a>.  Windows XP users will find that XP is able to open the zip file and guide you
      through extracting it using a &quot;wizard&quot;.</p>
    <p>We'll refer to the root directory created by the unzip/untar (such as <span class="literal"
      >/usr/alice/ProgramD</span>) as <span class="user-value">PROGRAMD</span>.</p>
    <h4>1.1.1 Compile (source downloads only)</h4>
    <p>If you downloaded the binary version of Program D (<span class="literal">programd-4.5rc1-bin.tar.bz2</span>
    or <span class="literal">programd-4.5rc1-bin.zip</span>), you can skip this step.</p>
    <p>If you downloaded the source version of Program D (<span class="literal">programd-4.5rc1-src.tar.bz2</span>
    or <span class="literal">programd-4.5rc1-src.zip</span>), you will need to compile the code
    before you can run it.  This is very easily done by running the <span class="literal">build</span>
    shell script (Linux) or <span class="literal">build.bat</span> batch file (Windows).  Here's what
    will happen:</p>
    <pre class="example">
[noel@emery ProgramD]$ chmod +x bin/build
[noel@emery ProgramD]$ bin/build

JAVA_HOME is not set in your environment.
I have set JAVA_HOME to "/usr/java/jdk1.5.0_02".
Please consider setting your JAVA_HOME environment variable.

Buildfile: /home/noel/d-test/ProgramD/conf/build.xml

init:
     [echo] Building Program D 4.5rc1....

prepare:
    [mkdir] Created dir: /home/noel/d-test/ProgramD/build.tmp

prepare-src:

compile:
    [javac] Compiling 186 source files to /home/noel/d-test/ProgramD/build.tmp
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

package:
      [jar] Building jar: /home/noel/d-test/ProgramD/lib/programd-main.jar
      [jar] Building jar: /home/noel/d-test/ProgramD/lib/programd-jetty.jar
      [jar] Building jar: /home/noel/d-test/ProgramD/lib/programd-rhino.jar

BUILD SUCCESSFUL
Total time: 4 seconds</pre>
    <h4>1.1.2 Verify Installation</h4>
    <p>The Program D distribution includes the set of test cases used to check AIML interpreter
        functionality, and as shipped, it is configured to load this small AIML set.  Therefore, you
        can verify the installation &quot;out of the box&quot; if you wish, by running the simple
        console immediately.  See <a href="#startup">First Startup</a> for tips on running the simple
        console.  If all is well, you should see something like this:</p>
    <pre class="example">
[21:54:58] Starting Program D version 4.5rc1.
[21:54:58] Using Java VM 1.5.0_02-b09 from Sun Microsystems Inc.
[21:54:58] On Linux version 2.6.11-1.14_FC3smp (i386)
[21:54:58] Predicates with no values defined will return: "undefined".
[21:54:58] Initializing FlatFileMultiplexor.
[21:54:58] Starting up the Graphmaster.
[21:54:58] Configuring bot "yourbot".
[21:54:59] Loaded 287 input substitutions.
[21:54:59] Loaded 19 gender substitutions.
[21:54:59] Loaded 9 person substitutions.
[21:54:59] Loaded 60 person2 substitutions.
[21:54:59] 91 categories loaded in 0.602 seconds.
[21:54:59] The AIML Watcher is not active.
[21:54:59] JavaScript interpreter not started.
[21:54:59] emery&gt; CONNECT : * : * : yourbot
[21:54:59] Match: CONNECT : * : * : yourbot
[21:54:59] Filename: "../resources/testing/testcases.aiml"
[21:54:59] Response 1 in 9 ms. (Average: 9.0 ms.)
[21:54:59] Interactive shell: type "/exit" to shut down; "/help" for help.</pre>
    <p>The fourth line from the bottom ("") indicates that a category from the testcases.aiml
        set has been matched.  Now that you know you have a working installation, please
        skim through the rest of these notes and decide what else you want to configure.</p>
    <h3>1.2. AIML</h3>
    <p>We suggest creating a subdirectory called &quot;<span class="literal"
      >aiml</span>&quot; in your <span class="user-value">PROGRAMD</span> directory, and then
      arranging your AIML files there in a way that makes sense to you. You'll need to unzip/untar
      as above.</p>
    <p>Note that, starting with version 4.5 of Program D, your AIML <i>must</i> declare the AIML
      namespace URI. The AIML set you download may not yet have been properly formatted in this way;
      if this is so, you should make the changes yourself. The namespace declaration is made on the
      opening tag of the root element of the document (the <span class="literal"
      >&lt;aiml&gt;</span> tag). At minimum, you should add this declaration:</p>
    <p class="example">xmlns="http://alicebot.org/2001/AIML-1.0.1"</p>
    <p>Also, if your AIML contains HTML markup (which is common in many AIML sets), you will need to
      do two things:</p>
    <ol>
      <li>
        <p>Declare the HTML or XHTML namespace and assign it to a prefix. This should also be done
          on the root element. This may look like:</p>
        <p class="example">xmlns:html="http://www.w3.org/1999/xhtml"</p>
      </li>
      <li>
        <p>Add the prefix you associated with the HTML/XHTML namespace to all HTML/XHTML elements in
          the document. This is less onerous than it might sound if you use a shell script or batch
          file. An example script that processes the "AAA" AIML set is included with this release in
          the <span class="literal">resources/scripts</span> subdirectory.</p>
        <p>For instance, every instance of</p>
        <p class="example">&lt;br /&gt;</p>
        <p>should become</p>
        <p class="example">&lt;html:br/&gt;</p>
      </li>
    </ol>
    <p>Additionally, please note that your HTML/XHTML markup (all of the markup, in fact) must be
      valid XML&mdash;in other words, an opening tag must have a corresponding closing tag
        (<span class="literal">&lt;some-element&gt;&lt;/some-element&gt;</span>) ,
      and an empty element ("atomic tag") must be properly notated (<span class="literal"
      >&lt;some-element/&gt;</span>). (This will all be obvious to you if you are using
      contemporary standards and standards-based tools, but several years ago the notion of
      well-formed XML was not something universally familiar, and so some AIML sets still include
      orphaned tags and other detritus that needs to be cleaned up.)</p>
    <p>So, starting from a root element that looks simply like:</p>
    <p class="example">&lt;aiml&gt;</p>
    <p>you will wind up with something like:</p>
    <pre class="example">&lt;aiml version="1.0.1" xmlns="http://alicebot.org/2001/AIML-1.0.1"
      xmlns:html="http://www.w3.org/1999/xhtml"&gt;</pre>
    <hr/>
    <h4>optional step</h4>
    <p>For purposes of editing AIML locally, you would be well advised to include an <span
        class="literal">xsi:schemaLocation</span> notation pointing to a local copy of the AIML
      schema. If you do not, then your XML editing application will attempt to connect to the
      aitools.org server to grab the schema whenever it needs to validate AIML, which is probably
      undesirable (for you and for us). (Note that Program D will <i>not</i> connect to the
      aitools.org server&mdash;it knows to look at the local copy of the schema.) Just as you
      would keep a copy of the XHTML schema locally for validating XHTML, you want to keep and point
      to a copy of the AIML schema. A copy of the AIML schema is included in the Program D
      distribution. There are two ways of pointing to it. The most direct approach is to add the
      following, again to the root element:</p>
    <p class="example">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br/>
      xsi:schemaLocation="http://alicebot.org/2001/AIML-1.0.1 resources/schema/AIML.xsd"</p>
    <p>However, this has the disadvantage that it hard-codes a local file path in your AIML file.
      (It is also technically incorrect, since the second part of the <span class="literal"
      >schemaLocation</span> is supposed to be a "canonical" URI.) So, if you are using an XML
      system that supports the use of XML Catalogs, you can enter the following:</p>
    <p class="example">xsi:schemaLocation="http://alicebot.org/2001/AIML-1.0.1
      http://aitools.org/aiml/schema/AIML.xsd"</p>
    <p>and then, in your catalog file, include an entry like this:</p>
    <p class="example">&lt;system systemId="http://aitools.org/aiml/schema/AIML.xsd"
      uri="./schema/AIML.xsd"/&gt;</p>
    <p>Again, an example catalog file is included in the Program D distribution.</p>
    <hr/>
    <h2>
      <a id="configuration">2. Configuration</a>
    </h2>
    <p>There's a lot to configure with Program D. What's needed for you really depends on how you
      want to use the program. If you don't care about running a web server, you don't need to
      bother with the &quot;<a href="#config-http-server">HTTP Server</a>&quot; section. If
      you don't care about using Program D with chat interfaces like AOL Instant Messenger or IRC,
      you won't be interested in the information about &quot;<a href="#config-listeners">Chat
        Listeners</a>&quot;. If you don't care about high-volume applications, or don't really
      want to do database-based log analysis, you can skip the &quot;<a href="#config-database"
        >Database</a>&quot; section.</p>
    <h3>
      <a id="config-bots">2.0. Bots</a>
    </h3>
    <p>Program D lets you configure an unlimited number of bots that can run at the same time. The
      bots are configured in the <span class="user-value">PROGRAMD</span>/<span class="literal"
      >conf/bots.xml</span> file. (In previous releases, this file was called <span class="literal"
      >startup.xml</span>.)</p>
    <p>Open the <span class="literal">bots.xml</span> file. Notice that the root element is called
        <span class="literal">&lt;bots&gt;</span>. Inside <span class="literal"
      >&lt;bots&gt;</span>, we place one or more <span class="literal"
      >&lt;bot&gt;</span> elements. These <span class="literal">&lt;bot&gt;</span>
      elements are not the same as the AIML tag of the same name.</p>
    <p>Each <span class="literal">&lt;bot&gt;</span> element has two important attributes:
        <span class="literal">id</span> and <span class="literal">enabled</span>. The first one
      assigns an identifier, which should be unique, for the bot. The identifier will be used
      internally by the engine and will be written to some log resources. The <span class="literal"
      >enabled</span> attribute should have either of the values &quot;<span class="literal"
      >true</span>&quot; or &quot;<span class="literal">false</span>&quot;. If the value
      is &quot;<span class="literal">true</span>&quot;, then Program D will try to load that
      bot when the server starts up. Switching <span class="literal">enabled</span> to
        &quot;<span class="literal">false</span>&quot; is an easy way to quickly turn off a
      bot configuration that you don't want to use (although a restart is required).</p>
    <p>Within the <span class="literal">&lt;bot&gt;</span> element we define <b>bot
        properties</b>, <b>listeners</b>, <b>default predicates</b>, <b>substitutions</b>,
        <b>sentence-splitters</b> and <b>learn directives</b>.</p>
    <h4>
      <a id="config-bot-properties">2.0.0. Bot Properties</a>
    </h4>
    <p>
      <b>Bot properties</b> are predicates that cannot be changed during the runtime life of the
      bot, but which <i>can</i> be included in AIML patterns for matching. A common property to
      define for a bot is &quot;<span class="literal">name</span>&quot;. Bot properties are
      defined in individual <span class="literal">&lt;property&gt;</span> elements inside a
      bot's <span class="literal">&lt;properties&gt;</span> element, as in the example:</p>
    <p class="example"> &lt;property name=&quot;master&quot; value=&quot;Joe
      Schmoe&quot;/&gt;</p>
    <p>This associates the bot property name &quot;<span class="literal">master</span>&quot;
      with the value &quot;<span class="literal">Joe
      Schmoe</span>&quot;.</p>
    <p>(You can also define bot properties in a separate file, and point to that file using an
        &quot;<span class="literal">href</span>&quot; attribute on the <span class="literal"
      >&lt;properties&gt;</span> element. See other elements inside <span class="literal"
      >&lt;bot&gt;</span> in the example <span class="literal">startup.xml</span> to
      understand how this is done.)</p>
    <p>Properties don't mean anything unless your AIML uses them. You can display the value of a bot
      property inside an AIML template by using the form <span class="literal"
      >&lt;bot
        name=&quot;<span class="user-value">property-name</span>&quot;/&gt;</span>.</p>
    <h4>(2.0.1. Listeners)</h4>
    <p>Listeners are discussed in more detail <a href="#config-listeners">below</a>.</p>
    <h4>
      <a id="config-predicates">2.0.2. Default Predicates</a>
    </h4>
    <p>
      <b>Default predicates</b> can be thought of as your bot's &quot;assumptions&quot;
      about new users. While AIML allows you to use <span class="literal">&lt;set
        name=&quot;<span class="user-value">predicate-name</span>&quot;&gt;</span>
      <span class="user-value">...something...</span>
      <span class="literal">&lt;/set&gt;</span> and <span class="literal"
      >&lt;get
        name=&quot;<span class="user-value">predicate-name</span>&quot;/&gt;</span>
      forms without any sort of &quot;declaration&quot;, Program D does allow you to set
      default values to associate with any predicate names you wish, so that you have more control
      over what is returned by <span class="literal"
      >&lt;get name=&quot;<span class="user-value">predicate-name</span>&quot;/&gt;</span>
      if a corresponding <span class="literal">&lt;set&gt;</span> has not yet happened for a
      given user.</p>
    <p>The <span class="literal">&lt;predicates&gt;</span> section, if it exists, may
      directly include one or more <span class="literal">&lt;predicate&gt;</span> children,
      or it may use an &quot;<span class="literal">href</span>&quot; attribute, as in the
      example, that points to another file where the predicates are defined.</p>
    <p>You can also use <span class="literal">&lt;predicate&gt;</span> elements to mark a
      predicate as <a href="http://aitools.org/aiml/spec#section-aiml-predicate-behaviors"
        target="_blank">return-name-when-set</a>. For instance, this predicate definition is
      included in a sample file:</p>
    <p class="example"> &lt;predicate name=&quot;he&quot;
      default=&quot;somebody&quot; set-return=&quot;name&quot;/&gt;</p>
    <p>This means that when <span class="literal">&lt;set name=&quot;he&quot;&gt;</span>
      <span class="user-value">...</span>
      <span class="literal">&lt;/set&gt;</span> is included in a template, the name of the
      predicate, &quot;<span class="literal">he</span>&quot;, will be displayed, rather than
      whatever value is associated with the name by the <span class="literal"
      >&lt;set&gt;</span>.</p>
    <h4>
      <a id="config-substitutions">2.0.3. Substitutions</a>
    </h4>
    <p>
      <b>Substitutions</b> have several different purposes, depending on their type. <b>Input</b>
      substitutions contribute to the process of <a
        href="http://aitools.org/aiml/spec#section-input-normalization" target="_blank">input
        normalization</a>. <span class="literal">person</span> substitutions provide macros for
      transformations by the <a href="http://aitools.org/aiml/spec#section-person" target="_blank"
        >&lt;person&gt;</a> tag; likewise <span class="literal">person2</span> and <span
        class="literal">gender</span> apply to the <a
        href="http://aitools.org/aiml/spec#section-person2" target="_blank"
      >&lt;person2&gt;</a> and <a href="http://aitools.org/aiml/spec#section-gender"
        target="_blank">&lt;gender&gt;</a> tags, respectively.</p>
    <p>Starting in version 4.5, the <span class="literal">find</span> attributes of substitutions
      are parsed as regular expressions. This lends a great deal more power and precision to the
      input normalization step, and to the <span class="literal">gender</span>, <span
        class="literal">person</span> and <span class="literal">person2</span> processors. For a
      guide to the regular expression syntax that is available, see the <a
        href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html#sum">JDK
        documentation</a>.</p>
    <p>Each individual substitution specification, regardless of whether it is inside an <span
        class="literal">&lt;input&gt;</span>, <span class="literal"
      >&lt;gender&gt;</span>, <span class="literal">&lt;person&gt;</span> or <span
        class="literal">&lt;person2&gt;</span>, takes the same form as this example from
        <span class="literal">conf/substitutions.xml</span>:</p>
    <p class="example"> &lt;substitute find=&quot;\bbecasue\b&quot;
      replace=&quot;because&quot;/&gt;</p>
    <p>This means that, when this substitution is applied, each instance of the separate word
      &quot;becasue&quot; will be replaced with &quot;because&quot;. (This is an
      example of typo correction in Program D.)</p>
    <p>Note the use of the <span class="literal">\b</span> marker, which is regular expression
      notation for &quot;word boundary&quot;. In previous versions of Program D, you were
      advised to pad find and replace strings with spaces, as a way of approximating word boundary
      matching. This is no longer advised, and in fact will not work properly now that regular
      expression support is included.</p>
    <h4>
      <a id="config-sentence-splitters">2.0.4. Sentence-Splitters</a>
    </h4>
    <p>
      <b>Sentence-splitters</b>, as described in the <a
        href="http://aitools.org/aiml/spec#section-sentence-splitting-normalizations"
        target="_blank">AIML spec</a>, are:</p>
    <p class="blockquote"> ...heuristics applied to an input that attempt to break it into
      "sentences". The notion of "sentence", however, is ill-defined for many languages, so the
      heuristics for division into sentences are left up to the developer.</p>
    <p>Since sentence-splitters are applied to the input <i>after</i> substitution normalizations,
      they can be more general rules. The entire collection of example sentence-splitters shipped
      with Program D is:</p>
    <p class="example"> &lt;sentence-splitters&gt;<br/>
      &nbsp;&nbsp;&nbsp;&nbsp;&lt;splitter
      value=&quot;.&quot;/&gt;<br/>
      &nbsp;&nbsp;&nbsp;&nbsp;&lt;splitter
      value=&quot;!&quot;/&gt;<br/>
      &nbsp;&nbsp;&nbsp;&nbsp;&lt;splitter
      value=&quot;?&quot;/&gt;<br/>
      &nbsp;&nbsp;&nbsp;&nbsp;&lt;splitter
      value=&quot;;&quot;/&gt;<br/> &lt;/sentence-splitters&gt;</p>
    <p>As with some other examples, these are defined in a separate file that is pointed to by the
        &quot;<span class="literal">href</span>&quot; attribute on the <span class="literal"
      >&lt;sentence-splitters&gt;</span> element.</p>
    <h4>
      <a id="config-learn-directives">2.0.5. Learn Directives</a>
    </h4>
    <p>
      <b>Learn directives</b> function identically to the <a
        href="http://aitools.org/aiml/spec#section-learn" target="_blank">&lt;learn&gt;</a>
      element in AIML.</p>
    <p>You can use simple &quot;glob&quot;-like wildcard patterns for specifying files to
      load. For example, the shipped <span class="literal">startup.xml</span> file has this single
      learn directive:</p>
    <p class="example"> &lt;learn&gt;../aiml/standard/*.aiml&lt;/learn&gt;</p>
    <p>The path specification is relative to the current file, so this indicates that within a
      directory reached by going one level up (to the main <span class="user-value">PROGRAMD</span>
      directory), and then into a directory called &quot;<span class="literal"
      >aiml</span>&quot;, and from there into a subdirectory called &quot;<span
        class="literal">standard</span>&quot;, the program should load all files that end in
        &quot;<span class="literal">.aiml</span>&quot;. Note that files containing AIML are
        <i>not</i> required to have this or any particular suffix; also, if you direct the program
      to learn files that do not contain any AIML, you will receive a warning but nothing will be
      loaded from that file.</p>
    <h3>
      <a id="config-http-server">2.1. HTTP Server</a>
    </h3>
    <p>If you want to be able to talk to your bot through a web interface, you'll be interested to
      know that Program D ships with a fully optional &quot;servlet&quot; implementation. A
      servlet is an application that runs on a server and interacts with users via the web. As an
      example we use Program D with <a href="http://jetty.mortbay.org" target="_blank">Jetty</a>, an
      open source HTTP server and servlet container. It is possible to integrate Program D with
      other servlet containers, or other application frameworks entirely. Here, purely for example
      purposes, we describe using the Jetty interface.</p>
    <p>The main file you'll be interested in is <span class="user-value">PROGRAMD</span>
      <span class="literal">/conf/jetty.xml</span>. This is the file that is read by the Jetty
      server when it is invoked by Program D.</p>
    <p>The parameter that will probably be of most interest here is the port number. This is
      specified in the place that looks like:</p>
    <p class="example"> &lt;Set name=&quot;Port&quot;&gt;2001&lt;/Set&gt;</p>
    <p>Most web sites use the port numbered <span class="literal">80</span>, which is the port
      assumed by a web browser when you type a URL without a port specification, so you might never
      have even known that there was such a thing as a port in a URL! Having different ports allows
      different server programs running on the same machine to answer requests without bothering
      each other.</p>
    <p>For testing purposes, it is probably fine to use the default value of <span class="literal"
      >2001</span>, or whatever you prefer (although on some operating systems you can't use a
      number lower than <span class="literal">1024</span> without special privileges). But for
      serious applications you'll want to deal with this differently, since many firewalls don't
      allow people to access arbitrary ports. The easiest solution to the port problem is to use a
      proxy server (or the proxy feature of a good web server like <a href="http://httpd.apache.org"
        target="_blank">Apache</a>) to allow external users to access your bot using a regular web
      address that doesn't specify a port (i.e., through port <span class="literal">80</span>).</p>
    <p>You probably won't care to change the rest of the Jetty configuration file, unless you intend
      to use Jetty to serve content or run other applications besides Program D.</p>
    <h3>
      <a id="config-listeners">2.2. Chat Listeners</a>
    </h3>
    <p>In current Program D nomenclature, a &quot;listener&quot; is a program that knows how
      to speak a particular protocol and interpret messages for the bot. For instance, the <span
        class="literal">IRCListener</span> understands the popular IRC protocol and allows you to
      connect your bot to any IRC server.</p>
    <p>You can enable one or more listeners for each bot. Each listener has its own unique
      configuration parameters, which are specific to the requirements of the protocol for which
      it's designed. You'll find examples of each currently-available listener in the <span
        class="user-value">PROGRAMD</span>/<span class="literal">conf/bots.xml</span> file.</p>
    <p>Listeners for a given bot are specified within the <span class="literal"
      >&lt;listeners&gt;</span> element, in individual <span class="literal"
      >&lt;listener&gt;</span> elements. Each <span class="literal"
      >&lt;listener&gt;</span> element must have two attributes: &quot;<span
        class="literal">type</span>&quot;, and &quot;<span class="literal"
      >enabled</span>&quot;. The value for &quot;<span class="literal">type</span>&quot;
      must correspond with a value assigned by the developer to a listener that is somewhere in the
      Java classpath for Program D. The example <span class="literal">bots.xml</span> includes an
      example of each type currently known. The value of &quot;<span class="literal"
      >enabled</span>&quot; must be &quot;<span class="literal">true</span>&quot; or
        &quot;<span class="literal">false</span>&quot;, allowing the listener to be switched
      on or off with ease.</p>
    <p>The parameters for a listener are specifed in individual <span class="literal"
      >&lt;parameter&gt;</span> elements within the <span class="literal"
      >&lt;listener&gt;</span>. For example:</p>
    <p class="example"> &lt;parameter name=&quot;host&quot;
      value=&quot;ar.chatjunkies.org&quot;/&gt;<br/> &lt;parameter
      name=&quot;port&quot; value=&quot;6667&quot;/&gt;<br/> &lt;parameter
      name=&quot;nick&quot; value=&quot;programd&quot;/&gt;<br/>
      &lt;parameter name=&quot;channel&quot; value=&quot;#bots&quot;/&gt;</p>
    <p>These are the parameters set for the example use of the <span class="literal"
      >IRCListener</span>, whose type string is &quot;<span class="literal"
      >ProgramD-IRC</span>&quot;.</p>
    <p>When you enable a chat listener, you will see its output mixed in with the console output.
      You can also interact with some listeners if they implement the
      &quot;commandable&quot; interface (see <a href="#commandables">below</a>).</p>
    <h3>
      <a id="config-database">2.3. Database</a>
    </h3>
    <p>You are not required to install, configure or use a database in order to use Program D. The
      default configuration is entirely based on text files in order to make setup quick, painless,
      and no more resource-intensive than necessary.</p>
    <p>However, for heavy-volume situations, and/or for cases where you want to collect dialogue in
      a form that can perhaps be more easily mined, you may wish to use a database.</p>
    <p>We have done the most extensive testing with <a href="http://www.mysql.com" target="_blank"
        >MySQL</a>; however, other users have connected Program D with various other DBMSes. The
      major point is that you must have a JDBC driver for the database you wish to use. We include
      the MySQL JDBC driver with the Program D distribution for convenience.</p>
    <p>If you do want to use a database, you need to configure it properly in the <span
        class="user-value">PROGRAMD</span>/<span class="literal">core.xml</span> file. The relevant
      part of the file is this:</p>
    <pre class="example">
    &lt;!--
    DATABASE CONFIGURATION
         * This is only meaningful if you are using a database-enabled Multiplexor
         * and/or the database-based chat logging.
    --&gt;
    
    &lt;!--Typical mySQL configuration--&gt;
    
    &lt;!--The URL of the database to use. [String: jdbc:mysql:///programdbot]--&gt;
    &lt;entry key="programd.database.url"&gt;jdbc:mysql:///programdbot&lt;/entry&gt;
    
    &lt;!--The database driver to use. [String: org.gjt.mm.mysql.Driver]--&gt;
    &lt;entry key="programd.database.driver"&gt;org.gjt.mm.mysql.Driver&lt;/entry&gt;
    
    
    &lt;!--The maximum number of simultaneous connections to the database. [int: 25]--&gt;
    &lt;entry key="programd.database.connections"&gt;25&lt;/entry&gt;
    
    &lt;!--The username which with to access the database. [String: programd]--&gt;
    &lt;entry key="programd.database.user"&gt;programd&lt;/entry&gt;
    
    &lt;!--The password for the database. [String: yourpassword]--&gt;
    &lt;entry key="programd.database.password"&gt;yourpassword&lt;/entry&gt;</pre>
    <p>You should set these values to match your database installation. Remember that the driver
      class must be available from the Java classpath.</p>
    <h4>2.3.0. DBMultiplexor</h4>
    <p>If you want to store predicates in the database, you must enable the <span class="literal"
      >DBMultiplexor</span>. This can be done by switching the comment marks in <span
        class="user-value">PROGRAMD</span>/<span class="literal">core.xml</span> so that this:</p>
    <pre class="example">
    &lt;!--The Multiplexor to use. [String: org.aitools.programd.multiplexor.FlatFileMultiplexor]--&gt;
    &lt;entry key="programd.multiplexor-classname"&gt;org.aitools.programd.multiplexor.FlatFileMultiplexor&lt;/entry&gt;
    &lt;!--&lt;entry key="programd.multiplexor"&gt;org.aitools.programd.multiplexor.DBMultiplexor&lt;/entry&gt;--&gt;</pre>
    <p>becomes this:</p>
    <pre class="example">
    &lt;!--The Multiplexor to use. [String: org.aitools.programd.multiplexor.FlatFileMultiplexor]--&gt;
    &lt;!--&lt;entry key="programd.multiplexor-classname"&gt;org.aitools.programd.multiplexor.FlatFileMultiplexor&lt;/entry&gt;--&gt;
    &lt;entry key="programd.multiplexor"&gt;org.aitools.programd.multiplexor.DBMultiplexor&lt;/entry&gt;</pre>
    <p>If <span class="literal">DBMultiplexor</span> is enabled, Program D will expect to find two
      tables called <span class="literal">users</span> and <span class="literal">predicates</span>
      in the configured database. The SQL commands for creating these tables are in <span
        class="user-value">PROGRAMD</span>/<span class="literal"
      >database/db-multiplexor.script</span>.</p>
    <h4>2.3.1. Database-based Chat Logging</h4>
    <p>Database-based chat logging stores each exchange with the bot in a database. This is useful
      for monitoring conversations, data mining, etc. To enable this feature, you must set:</p>
    <pre class="example">
    &lt;!--Enable chat logging to the database? [boolean: false]
        * Be sure that the database configuration (later in this file) is valid.--&gt;
    &lt;entry key="programd.logging.to-database.chat"&gt;<span class="user-value">true</span>&lt;/entry&gt;</pre>
    <p>(in <span class="user-value">PROGRAMD</span>
      <span class="literal">/core.xml</span>). If this is enabled, Program D will expect to find a
      table called <span class="literal">chatlog</span> in the database. The command for creating
      this table is in <span class="user-value">PROGRAMD</span>/<span class="literal"
      >database/db-chatlog.script</span>. Note that if you are logging chats to a database, you
      might want to disable the redundant logging to XML files. You can do this by setting:</p>
    <p class="example"> programd.logging.to-xml.chat=false</p>
    <h3>2.4. Shell and Console</h3>
    <p>In its usual configuration, Program D displays information about what it is doing while it
      starts, runs, and shuts down. We call this the &quot;console&quot;. Also, you can
      interact with Program D via a simple shell, if desired. Sometimes it is simpler to use this
      shell than to open a web browser or IM program. Both the console and shell can be configured
      to suit your needs. Configuration for both is done in the <span class="user-value"
        >PROGRAMD</span>/<span class="literal">console.xml</span> file.</p>
    <h3>
      <a id="aiml-watcher">2.5. AIMLWatcher</a>
    </h3>
    <p>The AIML Watcher is a nifty feature that watches to see if you change your AIML files. This
      allows you to update AIML without restarting the bot.</p>
    <p>As a security feature, the AIML Watcher only watches files that were loaded by a <b>learn</b>
      directive. If you put a new file into a directory with other AIML files, that file will
      <i>not</i> be automatically loaded (but you can load it with the <span class="literal"
      >/load</span> shell command if you have access to the console and have not disabled the
      shell).</p>
    <p>You can enable the AIML Watcher by setting:</p>
    <pre class="example">
    &lt;!--Enable the AIML Watcher? [boolean: false]
        * This will automatically load your AIML files if they are changed.--&gt;
    &lt;entry key="programd.use-watcher"&gt;false&lt;/entry&gt;</pre>
    <p>(in <span class="user-value">PROGRAMD</span>
      <span class="literal">/core.xml</span>). And you can set the frequency with which the AIML
      Watcher checks your files for modification by changing:</p>
    <pre class="example">
    &lt;!--The delay period when checking changed AIML (milliseconds). [int: 2000]
        * Only applicable if the AIML Watcher is enabled.--&gt;
    &lt;entry key="programd.watcher.timer"&gt;2000&lt;/entry&gt;</pre>
    <p>(The units are milliseconds. Don't be unreasonable in setting this too low.)</p>
    <h4>2.6. Other server.properties Configuration Items</h4>
    <p>The <span class="user-value">PROGRAMD</span>
      <span class="literal">/core.xml</span> file is documented inline.</p>
    <h2>
      <a id="startup">3. First Startup</a>
    </h2>
    <h3>3.0. Starting Program D</h3>
    <p>Starting with version 4.5, Program D has a much clearer idea of "configurations". You will
      find three different configurations available for your use. Additional configurations can
      easily be created, to customize the environment in which you run Program D.</p>
    <p>To start Program D in the simplest way, run <span class="user-value">PROGRAMD</span>
      <span class="literal">/bin/simple-console</span> (*nix) or <span class="user-value">PROGRAMD</span><span class="literal"
      >/bin/simple-console.bat</span> (Windows).</p>
    <p>If you're using Windows and you launch the batch file by double-clicking it, but there are
      some configuration problems, the console window might disappear before you have time to read
      the messages. You are advised in this case to open a command prompt and run the batch file
      from there (cd to the right directory, type &quot;<span class="literal"
      >run</span>&quot;).</p>
    <p>If you're using Linux, you may need to make the <span class="user-value">PROGRAMD</span>
      <span class="literal">/bin/simple-console</span> file
      executable by issuing the command:</p>
    <p class="example"> chmod +x simple-console</p>
    <p>Starting the server script should look something like this:</p>
<pre class="example">
[17:06:40] Starting Program D version 4.5rc1.
[17:06:40] Using Java VM 1.5.0_02-b09 from Sun Microsystems Inc.
[17:06:40] On Linux version 2.6.11-1.14_FC3smp (i386)
[17:06:40] Predicates with no values defined will return: "undefined".
[17:06:40] Initializing FlatFileMultiplexor.
[17:06:40] Starting up the Graphmaster.
[17:06:40] Configuring bot "yourbot".
[17:06:40] Loaded 287 input substitutions.
[17:06:40] Loaded 19 gender substitutions.
[17:06:40] Loaded 9 person substitutions.
[17:06:40] Loaded 60 person2 substitutions.
[17:06:40] 92 categories loaded in 0.564 seconds.
[17:06:40] The AIML Watcher is not active.
[17:06:40] Initializing org.aitools.programd.interpreter.RhinoInterpreter.
[17:06:40] emery&gt; CONNECT : * : * : yourbot
[17:06:40] Match: CONNECT : * : * : yourbot
[17:06:40] Filename: "../resources/testing/testcases.aiml"
[17:06:40] Response 1 in 8 ms. (Average: 8.0 ms.)
[17:06:40] Interactive shell: type "/exit" to shut down; "/help" for help.
[17:06:40] [YourBot] JUDGE&gt; </pre>
    <p>If there are any errors while starting up, an explanation will be printed and the server will
      shut down. If you encounter a confusing error message, please <a
        href="http://bugs.aitools.org" target="_blank">file a bug report</a>!!!</p>
    <h3>3.1. Understanding the Console</h3>
    <p>While the bot is running, information will be printed to the console to tell you what's going
      on.</p>
    <h4>
      <a id="shutdown-info">3.1.1. Shutdown Messages</a>
    </h4>
    <p>Before the bot server can shut down, it must stop the http server and must save any
      predicates left in the cache. It also must stop all listeners. There are several different <a
        href="#shutting-down">ways to shut down</a>, but all of them should cause Program D to print
      information that looks like this:</p>
      <pre class="example">
[17:07:38] Program D is shutting down.
[17:07:38] Shutting down all ManagedProcesses.
[17:07:38] Finished shutting down ManagedProcesses.
[17:07:38] PredicateMaster saving all cached predicates (2)
[17:07:38] Shutdown complete.</pre>
    <p>&quot;ManagedProcesses&quot; are such things as the http server and listeners. Sometimes
      one or more of these may take a long time to shut down. Unless you are in a great hurry, you
      should allow this process to complete properly. The saving of cached predicates should be very
      fast.</p>
    <h3>
      <a id="using-shell">3.2. Using the Shell</a>
    </h3>
    <p>The simplest use of the shell is to talk to your bot(s). However, there are some
      other capabilities available to you. All shell commands in Program D are preceded by a <span
        class="literal">/</span> (slash) character. If you type &quot;<span class="literal"
      >/help</span>&quot; at a shell prompt, you can see the list of available commands:</p>
<pre class="example">
[17:10:55] All shell commands are preceded by a forward slash (/).
[17:10:55] The commands available are:
[17:10:55] /help             - prints this help
[17:10:55] /exit             - shuts down the bot server
[17:10:55] /load filename    - loads/reloads given filename for active bot
[17:10:55] /unload filename  - unloads given filename for active bot
[17:10:55] /bots             - lists loaded bots
[17:10:55] /talkto botid     - switches conversation to given bot
[17:10:55] /who              - prints the id of the current bot
[17:10:55] /files            - lists the files loaded by the current bot
[17:10:55] /roll chatlog     - rolls over chat log
[17:10:55] /roll targets     - rolls over saved targeting data
[17:10:55] /commandables     - lists available "shell commandables" (such as listeners)</pre>
    <h4>3.2.0. Loading AIML</h4>
    <p>The <span class="literal">/load</span> command lets you load new AIML files, or reload files
      (useful if you have disabled the <a href="#aiml-watcher">AIML Watcher</a>.)</p>
    <h4>3.2.1. Unloading AIML</h4>
    <p>The <span class="literal">/unload</span> command lets you unload an AIML file that is
      currently in memory. You must unload using the pathname that was originally used to load it,
      which can be a little tricky to get right.</p>
    <h4>3.2.2. Listing Loaded Bots</h4>
    <p>You can see which bots are currently loaded with the <span class="literal">/bots</span>
      command.</p>
    <h4>3.2.3. Talking to a Different Bot</h4>
    <p>You can switch the bot with whom you are conversing by using the <span class="literal"
      >/talkto</span> command. You must use a valid bot id as the argument. (The bot id is not
      necessarily the same as the value associated with its &quot;name&quot; property. To
      see bot ids, look at your <span class="literal">startup.xml</span> file or use the <span
        class="literal">/bots</span> command.</p>
    <p>Each time you switch bots, the connect string will be sent to the bot.</p>
    <p>Trying to talk to a botid that doesn't exist will result in an error message.</p>
    <h3>3.3. Connecting via the Web Interface</h3>
    <p>If you want to talk to your bot through a web server, use the example <span class="user-value">PROGRAMD</span><span class="literal">/web-server</span> configuration.
    Once your bot is started, you can interact with it through a web browser. If you have not
      changed the port number (see <a href="#config-http-server">HTTP Server</a> above, then you
      should get a response when you go to this address:</p>
    <p class="example"> http://localhost:2001</p>
    <p>Note that &quot;localhost&quot; is the name by which your computer knows itself&mdash;not
      only in Program D, but in any program that uses TCP/IP (the set of protocols that makes the
      Internet work). You cannot go to another computer and connect to yours using the name
        &quot;<span class="literal">localhost</span>&quot;. You will need to know the IP
      address or name of the computer where the bot is running, in order to connect from another
      machine. On Windows 95 and 98, you can find this out by running the command:</p>
    <p class="example"> winipcfg</p>
    <p>On Windows NT, 2000 and XP, use:</p>
    <p class="example"> ipconfig</p>
    <p>On *nix, use:</p>
    <p class="example"> host</p>
    <p>Try using the hostname first (it's usually easier to remember); if that causes problems, use
      the IP address. Also note that if you are behind a firewall, or otherwise part of a network
      over which you do not have complete control, your bot may be inaccessible to users from other
      machines even if they know your IP address or hostname. In such cases, contact your system
      administrator or Internet service provider.</p>
    <p>Once you do succeed to connect with the bot, you should see something like this:</p>
    <div class="box">
        <table border="0" cellpadding="0" cellspacing="5" width="500">

            <tr xmlns="http://www.w3.org/1999/xhtml">
                <td valign="top" width="30%">
                    <p class="fieldlabel">
                        You said:
                    </p>
                </td>
                <td valign="top" width="70%">
                    <p id="userinput">
                        CONNECT
                    </p>

                </td>
            </tr>
            <tr xmlns="http://www.w3.org/1999/xhtml">
                <td valign="top" width="30%">
                    <p class="fieldlabel">
                        
                        YourBot said:
                    </p>
                </td>
                <td valign="top" width="70%">

                    <p class="botresponse">
                        
                        Connected to test case AIML set.
                    </p>
                </td>
            </tr>
            <tr xmlns="http://www.w3.org/1999/xhtml">
                <td colspan="2" valign="top" width="100%">
                    <form method="post">
                        <input name="text" size="50" type="text"/>

                        <input type="submit" value="Say"/>
                    </form>
                </td>
            </tr>
            <tr xmlns="http://www.w3.org/1999/xhtml">
                <td colspan="2" valign="top" width="100%">
                    <p class="bottomtext">
                        
                        You are speaking with YourBot from emery.
                    </p>

                    <p class="bottomtext">
                        
                        YourBot's botmaster is unknown.
                    </p>
                    <p xmlns="http://www.w3.org/1999/xhtml">
                        You are  logged in.
                    </p>
                    <p xmlns="http://www.w3.org/1999/xhtml">
                        You can:
                    </p>
                    <ul xmlns="http://www.w3.org/1999/xhtml">

                            <li xmlns="http://www.w3.org/1999/xhtml">
                                <p xmlns="http://www.w3.org/1999/xhtml">
                                    
                                    <a href="?request=logout">log out</a>.
                                </p>
                            </li>
                        </ul>
                    
                </td>
            </tr>
        </table>
    </div>
    <p>If you have configured more than one bot, you can request the one you want by appending a
        <span class="literal">botid</span> parameter to your request. For example:</p>
    <p class="example"> http://vasya:2001?botid=TestBot-2</p>
    <p>would request the bot with id (not necessarily name!) <span class="literal">TestBot-2</span>
      from the machine <span class="literal">vasya</span>.</p>
    <p>You can also create different HTML templates for chat with your bot, by following the example
      provided in <span class="user-value">PROGRAMD</span>
      <span class="literal">/templates/html/chat.html</span>. If you then want to request one of
      these alternate templates you can add a <span class="literal">template</span> parameter to the
      URL request. The value of this parameter should be the name of the file, minus whatever
      extension. So if you create a template file named <span class="literal">fancy.html</span> and
      store it in the <span class="literal">templates/html</span> directory, then you can use a
      request like this:</p>
    <p class="example"> http://localhost:2001?botid=TestBot-1&amp;template=fancy</p>
    <h3>3.4. Connecting via a Chat Interface</h3>
    <p>If you have correctly configured one or more listeners (see <a href="#config-listeners"
        >Configuring Listeners</a> above, then you should be able to start the appropriate chat
      client and communicate with your bot.</p>
    <h3>3.5. Shutting Down</h3>
    <p>If you start Program D with the shell enabled, you can shut down the bot from the console by
      typing <span class="literal">/exit</span> command.</p>
    <p>If the shell is disabled, you can shut down the bot by pressing the interrupt key sequence
      for your operating system; this is often <span class="literal">Ctrl-C</span>. Or, on *nix
      systems, you can send the main JVM process a <span class="literal">SIGINT</span> signal with
      the <span class="literal">kill</span> command.</p>
    <p>
      <a href="http://validator.w3.org/check/referer" class="nohover">
        <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31"
          width="88" border="0"/>
      </a>
    </p>
  </body>
</html>

About

Automatically exported from code.google.com/p/owllang

Resources

License

Unknown, Apache-2.0 licenses found

Licenses found

Unknown
license.txt
Apache-2.0
Apache-license.txt

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published